From 0d8071ff77dc75e2fec28c3989f47ed382697905 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 21 Jul 2023 01:27:19 +0600 Subject: [PATCH 001/690] C&T 69000 (broken) --- src/include/86box/video.h | 3 + src/machine/m_at_socket370.c | 4 + src/machine/machine_table.c | 2 +- src/video/CMakeLists.txt | 3 +- src/video/vid_c&t_69000.c | 1353 ++++++++++++++++++++++++++++++++++ src/video/vid_table.c | 1 + 6 files changed, 1364 insertions(+), 2 deletions(-) create mode 100644 src/video/vid_c&t_69000.c diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 418423ea9..4c94fabfd 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -537,6 +537,9 @@ extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; +/* Chips & Technologies */ +extern const device_t chips_69000_device; + #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index b8cc437a1..5e60885f3 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -312,6 +312,10 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); + if (gfxcard[0] == VID_INTERNAL) { + extern const device_t chips_69000_onboard_device; + device_add(&chips_69000_onboard_device); + } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e73b74736..ea5d06a70 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12478,7 +12478,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO, .ram = { .min = 8192, .max = 524288, diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index b37e81134..70ef72b7a 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -25,7 +25,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c + vid_c&t_69000.c) if(MGA) target_compile_definitions(vid PRIVATE USE_MGA) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c new file mode 100644 index 000000000..fe22985e0 --- /dev/null +++ b/src/video/vid_c&t_69000.c @@ -0,0 +1,1353 @@ +/* + * 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. + * + * C&T 69000 emulation. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/pci.h> +#include <86box/thread.h> +#include + +typedef struct chips_69000_t { + svga_t svga; + uint8_t pci_conf_status; + uint8_t pci_line_interrupt; + uint8_t pci_rom_enable; + uint8_t read_write_bank; + atomic_bool engine_active; + atomic_bool quit; + thread_t *accel_thread; + event_t *fifo_event, *fifo_data_event; + pc_timer_t decrement_timer; + uint16_t rom_addr; + mem_mapping_t linear_mapping; + uint8_t on_board; + + rgb_t cursor_palette[8]; + uint32_t cursor_pallook[8]; + + uint8_t mm_regs[256], mm_index; + uint8_t flat_panel_regs[256], flat_panel_index; + uint8_t ext_regs[256], ext_index; + + union { + uint32_t mem_regs[4]; + uint16_t mem_regs_w[4 * 2]; + uint8_t mem_regs_b[4 * 4]; + }; + union { + uint32_t bitblt_regs[16]; + uint16_t bitblt_regs_w[16 * 2]; + uint8_t bitblt_regs_b[16 * 4]; + }; + + union { + uint16_t subsys_vid; + uint8_t subsys_vid_b[2]; + }; + + union { + uint16_t subsys_pid; + uint8_t subsys_pid_b[2]; + }; + + rom_t bios_rom; +} chips_69000_t; + +static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; + +void +chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_15bpp(uint16_t *dst, uint16_t src, uint8_t rop) +{ + uint16_t orig_dst = *dst & 0x8000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = ~0; + break; + } + *dst &= 0x7FFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) +{ + uint32_t orig_dst = *dst & 0xFF000000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0xFFFFFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_15bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +{ + uint16_t orig_dst = *dst & 0x8000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0x7FFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) +{ + uint32_t orig_dst = *dst & 0xFF000000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0xFFFFFF; + *dst |= orig_dst; +} + +void +chips_69000_recalctimings(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (chips->ext_regs[0x81] & 0x10) { + svga->htotal -= 5; + } + + if (chips->ext_regs[0x09] & 0x1) { + svga->vtotal -= 2; + svga->vtotal &= 0xFF; + svga->vtotal |= (svga->crtc[0x30] & 0xF) << 8; + svga->vtotal += 2; + + svga->dispend--; + svga->dispend &= 0xFF; + svga->dispend |= (svga->crtc[0x31] & 0xF) << 8; + svga->dispend++; + + svga->vsyncstart--; + svga->vsyncstart &= 0xFF; + svga->vsyncstart |= (svga->crtc[0x32] & 0xF) << 8; + svga->vsyncstart++; + + svga->vblankstart--; + svga->vblankstart &= 0xFF; + svga->vblankstart |= (svga->crtc[0x33] & 0xF) << 8; + svga->vblankstart++; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal -= 5; + + svga->htotal |= (svga->crtc[0x38] & 0x1) << 8; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal += 5; + + /* Let's care about horizontal blanking end later when it matters. */ + + svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; + svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 16; + } + + svga->interlace = !!(svga->crtc[0x70] & 0x80); + + switch (chips->ext_regs[0x81] & 0xF) { + case 0b0010: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 2; + break; + + case 0b0100: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0101: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0110: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0111: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 2; + break; + } +} + +void +chips_69000_decrement_timer(void* p) +{ + chips_69000_t *chips = (chips_69000_t*)p; + + chips->ext_regs[0xD2]--; + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); +} + +void +chips_69000_recalc_banking(chips_69000_t *chips) +{ + svga_t* svga = &chips->svga; + chips->svga.read_bank = chips->svga.write_bank = 0; + + svga->chain2_write = !(svga->seqregs[0x4] & 4); + svga->chain4 = (svga->seqregs[0x4] & 8) || (chips->ext_regs[0xA] & 0x4); + svga->packed_chain4 = !!(chips->ext_regs[0xA] & 0x4); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + + if (chips->ext_regs[0xA] & 1) { + chips->svga.read_bank = chips->svga.write_bank = 0x10000 * (chips->ext_regs[0xE] & 0x7f); + } + + /*if (chips->ext_regs[0x40] & 2) { + svga->decode_mask = (1 << 18) - 1; + } else { + svga->decode_mask = (1 << 21) - 1; + }*/ +} + +uint8_t +chips_69000_read_ext_reg(chips_69000_t* chips) +{ + uint8_t index = chips->ext_index; + switch (index) { + case 0x00: + return 0x2C; + case 0x01: + return 0x10; + case 0x02: + return 0xC0; + case 0x03: + return 0x00; + case 0x04: + return 0x62; + case 0x05: + case 0x06: + return 0x00; + case 0x08: + return 0x02; + case 0x0A: + return chips->ext_regs[index] & 0x37; + case 0x63: + return 0xFF; + case 0x70: + return 0x3; + case 0x71: + return 0x0; + } + return chips->ext_regs[index]; +} + +void +chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) +{ + switch (chips->ext_index) { + case 0xA: + chips->ext_regs[chips->ext_index] = val & 0x37; + chips_69000_recalc_banking(chips); + break; + case 0xB: + chips->ext_regs[chips->ext_index] = val & 0xD; + break; + case 0xE: + chips->ext_regs[chips->ext_index] = val & 0x7f; + chips_69000_recalc_banking(chips); + break; + case 0x9: + chips->ext_regs[chips->ext_index] = val & 0x3; + svga_recalctimings(&chips->svga); + break; + case 0x40: + chips->ext_regs[chips->ext_index] = val & 0x3; + chips_69000_recalc_banking(chips); + break; + case 0x60: + chips->ext_regs[chips->ext_index] = val & 0x43; + break; + case 0x20: + chips->ext_regs[chips->ext_index] = val & 0x3f; + break; + case 0x61: + chips->ext_regs[chips->ext_index] = val & 0x7f; + break; + case 0x62: + chips->ext_regs[chips->ext_index] = val & 0x9C; + break; + case 0x67: + chips->ext_regs[chips->ext_index] = val & 0x2; + break; + case 0x80: + chips->ext_regs[chips->ext_index] = val & 0xBF; + chips->svga.ramdac_type = (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x81: + chips->ext_regs[chips->ext_index] = val & 0x1f; + svga_recalctimings(&chips->svga); + break; + default: + chips->ext_regs[chips->ext_index] = val; + break; + } +} + +void +chips_69000_out(uint16_t addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t old, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA out: 0x%X, 0x%X\n", addr, val); + switch (addr) { + case 0x3c0: + if (!(chips->ext_regs[0x09] & 0x02)) + break; + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + return; + case 0x3c1: + if ((chips->ext_regs[0x09] & 0x02)) + { + svga->attrff = 1; + svga_out(addr, val, svga); + svga->attrff = 0; + return; + } + break; + case 0x3c9: + if (!(chips->ext_regs[0x09] & 0x01)) + break; + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = svga->monitor->mon_changeframecount; + switch (svga->dac_pos) { + case 2: + index = svga->dac_addr & 7; + chips->cursor_palette[index].r = svga->dac_r; + chips->cursor_palette[index].g = svga->dac_g; + chips->cursor_palette[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + chips->cursor_pallook[index] = makecol32(chips->cursor_palette[index].r, chips->cursor_palette[index].g, chips->cursor_palette[index].b); + else + chips->cursor_pallook[index] = makecol32(video_6to8[chips->cursor_palette[index].r & 0x3f], video_6to8[chips->cursor_palette[index].g & 0x3f], video_6to8[chips->cursor_palette[index].b & 0x3f]); + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + } + return; + case 0x3c5: + svga_out(addr, val, svga); + chips_69000_recalc_banking(chips); + return; + case 0x3D4: + svga->crtcreg = val & 0xff; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + case 0x3D6: + chips->ext_index = val; + return; + case 0x3D7: + return chips_69000_write_ext_reg(chips, val); + + } + svga_out(addr, val, svga); +} + +uint8_t +chips_69000_in(uint16_t addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t temp, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA in: 0x%X\n", addr); + switch (addr) { + case 0x3C5: + return svga->seqregs[svga->seqaddr]; + case 0x3c9: + if (!(chips->ext_regs[0x09] & 0x01)) { + temp = svga_in(addr, svga); + break; + } + index = (svga->dac_addr - 1) & 7; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].r; + else + temp = chips->cursor_palette[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].g; + else + temp = chips->cursor_palette[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].b; + else + temp = chips->cursor_palette[index].b & 0x3f; + break; + } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + temp >>= 2; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + case 0x3D6: + temp = chips->ext_index; + break; + case 0x3D7: + temp = chips_69000_read_ext_reg(chips); + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + +static uint8_t +chips_69000_pci_read(int func, int addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x00: + case 0x01: + return (0x102C >> ((addr & 1) * 8)) & 0xFF; + case 0x02: + case 0x03: + return (0x00C0 >> ((addr & 1) * 8)) & 0xFF; + case 0x04: + return chips->pci_conf_status; + case 0x07: + return 0x02; + case 0x08: + case 0x09: + case 0x0a: + return 0x00; + case 0x0b: + return 0x03; + case 0x13: + return chips->linear_mapping.base >> 24; + case 0x30: + return chips->pci_rom_enable & 0x1; + case 0x31: + return 0x0; + case 0x32: + return chips->rom_addr & 0xFF; + case 0x33: + return (chips->rom_addr & 0xFF00) >> 8; + case 0x3c: + return chips->pci_line_interrupt; + case 0x3d: + return 0x01; + case 0x2C: + case 0x2D: + case 0x6C: + case 0x6D: + return (chips->subsys_vid >> ((addr & 1) * 8)) & 0xFF; + case 0x2E: + case 0x2F: + case 0x6E: + case 0x6F: + return (chips->subsys_pid >> ((addr & 1) * 8)) & 0xFF; + default: + return 0x00; + } + } +} + +static void +chips_69000_pci_write(int func, int addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x04: + { + chips->pci_conf_status = val; + io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + mem_mapping_disable(&chips->bios_rom.mapping); + mem_mapping_disable(&chips->linear_mapping); + mem_mapping_disable(&chips->svga.mapping); + if (chips->pci_conf_status & PCI_COMMAND_IO) { + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + } + if (chips->pci_conf_status & PCI_COMMAND_MEM) { + if (!chips->on_board) mem_mapping_enable(&chips->bios_rom.mapping); + mem_mapping_enable(&chips->svga.mapping); + if (chips->linear_mapping.base) + mem_mapping_enable(&chips->linear_mapping); + } + break; + } + case 0x13: + { + mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24) - 1); + break; + } + case 0x3c: + chips->pci_line_interrupt = val; + break; + case 0x30: + if (chips->on_board) break; + chips->pci_rom_enable = val & 0x1; + mem_mapping_disable(&chips->bios_rom.mapping); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x32: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF; + chips->rom_addr |= val & 0xFC; + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x33: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF00; + chips->rom_addr |= (val << 8); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x6C: + case 0x6D: + chips->subsys_vid_b[addr & 1] = val; + break; + case 0x6E: + case 0x6F: + chips->subsys_pid_b[addr & 1] = val; + break; + } + } +} + +uint8_t +chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + case 0x00 ... 0x28: + return chips->bitblt_regs_b[addr & 0xFF]; + case 0x600 ... 0x60F: + return chips->mem_regs_b[addr & 0xF]; + case 0x768: + return chips_69000_in(0x3b4, chips); + case 0x769: + return chips_69000_in(0x3b5, chips); + case 0x774: + return chips_69000_in(0x3ba, chips); + case 0x780: + return chips_69000_in(0x3c0, chips); + case 0x781: + return chips_69000_in(0x3c1, chips); + case 0x784: + return chips_69000_in(0x3c2, chips); + case 0x788: + return chips_69000_in(0x3c4, chips); + case 0x789: + return chips_69000_in(0x3c5, chips); + case 0x78C: + return chips_69000_in(0x3c6, chips); + case 0x78D: + return chips_69000_in(0x3c7, chips); + case 0x790: + return chips_69000_in(0x3c8, chips); + case 0x791: + return chips_69000_in(0x3c9, chips); + case 0x794: + return chips_69000_in(0x3ca, chips); + case 0x798: + return chips_69000_in(0x3cc, chips); + case 0x79C: + return chips_69000_in(0x3ce, chips); + case 0x79D: + return chips_69000_in(0x3cf, chips); + case 0x7A0: + return chips_69000_in(0x3d0, chips); + case 0x7A1: + return chips_69000_in(0x3d1, chips); + case 0x7A4: + return chips_69000_in(0x3d2, chips); + case 0x7A5: + return chips_69000_in(0x3d3, chips); + case 0x7A8: + return chips_69000_in(0x3d4, chips); + case 0x7A9: + return chips_69000_in(0x3d5, chips); + case 0x7AC: + return chips_69000_in(0x3d6, chips); + case 0x7AD: + return chips_69000_in(0x3d7, chips); + case 0x7B4: + return chips_69000_in(0x3da, chips); + } + return 0xFF; +} + +uint16_t +chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); + } + return 0xFFFF; +} + +uint32_t +chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); + } + return 0xFFFFFFFF; +} + +void +chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + case 0x00 ... 0x28: + chips->bitblt_regs_b[addr & 0xFF] = val; + break; + case 0x600 ... 0x60F: + chips->mem_regs_b[addr & 0xF] = val; + break; + case 0x768: + chips_69000_out(0x3b4, val, chips); break; + case 0x769: + chips_69000_out(0x3b5, val, chips); break; + case 0x774: + chips_69000_out(0x3ba, val, chips); break; + case 0x780: + chips_69000_out(0x3c0, val, chips); break; + case 0x781: + chips_69000_out(0x3c1, val, chips); break; + case 0x784: + chips_69000_out(0x3c2, val, chips); break; + case 0x788: + chips_69000_out(0x3c4, val, chips); break; + case 0x789: + chips_69000_out(0x3c5, val, chips); break; + case 0x78C: + chips_69000_out(0x3c6, val, chips); break; + case 0x78D: + chips_69000_out(0x3c7, val, chips); break; + case 0x790: + chips_69000_out(0x3c8, val, chips); break; + case 0x791: + chips_69000_out(0x3c9, val, chips); break; + case 0x794: + chips_69000_out(0x3ca, val, chips); break; + case 0x798: + chips_69000_out(0x3cc, val, chips); break; + case 0x79C: + chips_69000_out(0x3ce, val, chips); break; + case 0x79D: + chips_69000_out(0x3cf, val, chips); break; + case 0x7A0: + chips_69000_out(0x3d0, val, chips); break; + case 0x7A1: + chips_69000_out(0x3d1, val, chips); break; + case 0x7A4: + chips_69000_out(0x3d2, val, chips); break; + case 0x7A5: + chips_69000_out(0x3d3, val, chips); break; + case 0x7A8: + chips_69000_out(0x3d4, val, chips); break; + case 0x7A9: + chips_69000_out(0x3d5, val, chips); break; + case 0x7AC: + chips_69000_out(0x3d6, val, chips); break; + case 0x7AD: + chips_69000_out(0x3d7, val, chips); break; + case 0x7B4: + chips_69000_out(0x3da, val, chips); break; + } +} + +void +chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + chips_69000_writeb_mmio(addr, val, chips); + chips_69000_writeb_mmio(addr + 1, val >> 8, chips); + break; + } +} + +void +chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + chips_69000_writew_mmio(addr, val, chips); + chips_69000_writew_mmio(addr + 2, val >> 16, chips); + break; + } +} + +uint8_t +chips_69000_readb_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readb_mmio(addr, chips); + + return svga_readb_linear(addr & 0x1FFFFF, p); +} + +uint16_t +chips_69000_readw_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readw_mmio(addr, chips); + + return svga_readw_linear(addr & 0x1FFFFF, p); +} + +uint32_t +chips_69000_readl_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readl_mmio(addr, chips); + + return svga_readl_linear(addr & 0x1FFFFF, p); +} + +void +chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writeb_mmio(addr, val, chips); + + svga_writeb_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writew_mmio(addr, val, chips); + + svga_writew_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writel_mmio(addr, val, chips); + + svga_writel_linear(addr & 0x1FFFFF, val, p); +} + +static void * +chips_69000_init(const device_t *info) +{ + chips_69000_t *chips = malloc(sizeof(chips_69000_t)); + memset(chips, 0, sizeof(chips_69000_t)); + + /* Appears to have an odd VBIOS size. */ + if (!info->local) { + rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x40000, 0x3ffff, 0x0000, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&chips->bios_rom.mapping); + } + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); + + svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ + NULL, + chips_69000_in, chips_69000_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + + chips->svga.bpp = 8; + chips->svga.miscout = 1; + chips->svga.recalctimings_ex = chips_69000_recalctimings; + + mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); + + chips->quit = 0; + chips->engine_active = 0; + chips->on_board = !!(info->local); + + timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); + + return chips; +} + +static int +chips_69000_available(void) +{ + return rom_present("roms/video/chips/69000.ROM"); +} + +void +chips_69000_close(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->quit = 1; +// thread_set_event(chips->fifo_event); + // thread_wait(chips->accel_thread); + svga_close(&chips->svga); + + free(chips); +} + +void +chips_69000_speed_changed(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + svga_recalctimings(&chips->svga); +} + +void +chips_69000_force_redraw(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->svga.fullchange = changeframecount; +} + +const device_t chips_69000_device = { + .name = "Chips & Technologies 69000", + .internal_name = "c&t_69000", + .flags = DEVICE_PCI, + .local = 0, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; + +const device_t chips_69000_onboard_device = { + .name = "Chips & Technologies 69000 (onboard)", + .internal_name = "c&t_69000_onboard", + .flags = DEVICE_PCI, + .local = 1, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a2cead1ec..d4915a056 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -198,6 +198,7 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, + { &chips_69000_device }, #if defined(DEV_BRANCH) && defined(USE_MGA) { &millennium_device, VIDEO_FLAG_TYPE_SPECIAL }, { &mystique_device }, From a947e49f5ef036c7303bc6208742d66d9f270727 Mon Sep 17 00:00:00 2001 From: redoste Date: Tue, 5 Sep 2023 19:01:33 +0200 Subject: [PATCH 002/690] Allow connection to a VDE switch run by the same user `libvdeplug` will only change the mode if the switch is run by another user that isn't root. If the switch is run by the same user as 86Box the socket will be chmoded to 000 and the switch, unable to connect back, will drop the connection. https://github.com/rd235/vdeplug4/blob/187256c528137036cc4e3228728b3f70a3342fa5/libvdeplug4/libvdeplug_vde.c#L261-L275 --- src/network/net_vde.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_vde.c b/src/network/net_vde.c index afeeaac9c..d783c9c9d 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -274,7 +274,7 @@ void *net_vde_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, c vde_args.group = 0; vde_args.port = 0; - vde_args.mode = 0; + vde_args.mode = 0700; // Allow the switch to connect back to our socket if it is run by the same user // We are calling vde_open_real(), not the vde_open() macro... if ((vde->vdeconn = f_vde_open(socket_name, VDE_DESCRIPTION, From 7cf1ffeb68a55ad271cd6208c1386a10583df3b0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 7 Dec 2023 20:30:48 +0100 Subject: [PATCH 003/690] Initial stub for CD-ROM passthrough (currently Windows only). --- src/cdrom/cdrom_ioctl.c | 221 ++++++++++++++++++++++++++++++ src/win/win_cdrom_ioctl.c | 275 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 496 insertions(+) create mode 100644 src/cdrom/cdrom_ioctl.c create mode 100644 src/win/win_cdrom_ioctl.c diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c new file mode 100644 index 000000000..382465637 --- /dev/null +++ b/src/cdrom/cdrom_ioctl.c @@ -0,0 +1,221 @@ +/* + * 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. + * + * CD-ROM passthrough support. + * + * + * + * Authors: TheCollector1995, , + * Miran Grca, + * + * Copyright 2023 TheCollector1995. + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/path.h> +#include <86box/plat.h> +#include <86box/plat_cdrom.h> +#include <86box/scsi_device.h> +#include <86box/cdrom.h> + +#ifdef ENABLE_CDROM_IOCTL_LOG +int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG; + +void +cdrom_ioctl_log(const char *fmt, ...) +{ + va_list ap; + + if (cdrom_ioctl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define cdrom_ioctl_log(fmt, ...) +#endif + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) + +static void +cdrom_ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) +{ + TMSF tmsf; + + plat_cdrom_get_audio_tracks(first, last, &tmsf); +} + +static void +cdrom_ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti) +{ + TMSF tmsf; + + plat_cdrom_get_audio_track_info(end, track, &ti->number, &tmsf, &ti->attr); + + ti->m = tmsf.min; + ti->s = tmsf.sec; + ti->f = tmsf.fr; +} + +static void +cdrom_ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) +{ + TMSF rel_pos; + TMSF abs_pos; + + plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index, + &rel_pos, &abs_pos); + + subc->abs_m = abs_pos.min; + subc->abs_s = abs_pos.sec; + subc->abs_f = abs_pos.fr; + + subc->rel_m = rel_pos.min; + subc->rel_s = rel_pos.sec; + subc->rel_f = rel_pos.fr; +} + +static int +cdrom_ioctl_is_track_audio(uint32_t pos, int ismsf) +{ + uint8_t attr; + int m; + int s; + int f; + int track; + + if (ismsf) { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f) - 150; + } + + /* GetTrack requires LBA. */ + return plat_cdrom_get_audio_track(pos); +} + +static int +cdrom_ioctl_sector_size(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) +{ + return plat_get_sector_size(); +} + +static int +cdrom_ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba) +{ + switch (type) { + case CD_READ_DATA: + return plat_cdrom_read_sector(b, 0, lba); + case CD_READ_AUDIO: + return plat_cdrom_read_sector(b, 1, lba); + case CD_READ_RAW: + if (plat_get_sector_size() == 2352) + return plat_cdrom_read_sector(b, 1, lba); + else + return plat_cdrom_read_sector(b, 0, lba); + break; + default: + cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); + return 0; + } +} + +static int +cdrom_ioctl_track_type(UNUSED(cdrom_t *dev), uint32_t lba) +{ + if (cdrom_ioctl_is_track_audio(lba, 0)) + return CD_TRACK_AUDIO; + + return 0; +} + +static void +cdrom_ioctl_exit(cdrom_t *dev) +{ + dev->cd_status = CD_STATUS_EMPTY; + + plat_cdrom_exit(); + + dev->ops = NULL; +} + +static const cdrom_ops_t cdrom_ioctl_ops = { + cdrom_ioctl_get_tracks, + cdrom_ioctl_get_track_info, + cdrom_ioctl_get_subchannel, + NULL, + cdrom_ioctl_sector_size, + cdrom_ioctl_read_sector, + cdrom_ioctl_track_type, + cdrom_ioctl_exit +}; + +void +cdrom_ioctl_eject(void) +{ + plat_cdrom_eject(); +} + +void +cdrom_ioctl_load(void) +{ + plat_cdrom_load(); +} + +static int +cdrom_ioctl_open_abort(cdrom_t *dev) +{ + if (dev && dev->ops && dev->ops->exit) + dev->ops->exit(dev); + + dev->ops = NULL; + dev->host_drive = 0; + dev->ioctl_path[0] = 0; + return 1; +} + +int +cdrom_ioctl_open(cdrom_t *dev, const char *path) +{ + /* Open the drive. */ + if (plat_cdrom_open()) + return cdrom_ioctl_open_abort(dev); + + /* Make sure to not STRCPY if the two are pointing + at the same place. */ + if (path != dev->ioctl_path) + strcpy(dev->ioctl_path, path); + + /* All good, reset state. */ + dev->cd_status = CD_STATUS_STOPPED; + dev->is_dir = 0; + dev->seek_pos = 0; + dev->cd_buflen = 0; + plat_cdrom_reset(); + dev->cdrom_capacity = plat_cdrom_get_capacity(); + pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); + + /* Attach this handler to the drive. */ + dev->ops = &cdrom_ioctl_ops; + + return 0; +} diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c new file mode 100644 index 000000000..9eee9c789 --- /dev/null +++ b/src/win/win_cdrom_ioctl.c @@ -0,0 +1,275 @@ +/* + * 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. + * + * Win32 CD-ROM support via IOCTL. + * + * + * + * Authors: TheCollector1995, , + * Miran Grca, + * + * Copyright 2023 TheCollector1995. + * Copyright 2023 Miran Grca. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include "ntddcdrm.h" +#include "ntddscsi.h" +#include +#include +#include <86box/86box.h> +#include <86box/scsi_device.h> +#include <86box/cdrom.h> +#include <86box/plat_unused.h> +#include <86box/plat_cdrom.h> + +static const char ioctl_path[8]; +static HANDLE hIOCTL; +static CDROM_TOC toc; + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) + +static int +plat_cdrom_get_track(uint32_t sector) +{ + int track = 0; + uint32_t track_addr; + + for (int i = toc.FirstTrack; i < toc.LastTrack; i++) { + /* There must be at least two tracks - data and lead out. */ + track_addr = MSFtoLBA(toc.TrackData[i].Address[1], toc.TrackData[i].Address[2], toc.TrackData[i].Address[3]); + if (track_addr <= sector) { + track = i; + } + } + + pclog("GetTrack = %d.\n", track); + return track; +} + +int +plat_cdrom_get_audio_track(uint32_t sector) +{ + int control = 0; + uint32_t track_addr; + + for (int i = 0; toc.TrackData[i].TrackNumber != 0xaa; i++) { + /* There must be at least two tracks - data and lead out. */ + track_addr = MSFtoLBA(toc.TrackData[i].Address[1], toc.TrackData[i].Address[2], toc.TrackData[i].Address[3]); + if ((toc.TrackData[i].TrackNumber >= toc.FirstTrack) && (toc.TrackData[i].TrackNumber <= toc.LastTrack) && + (track_addr >= sector)) { + control = toc.TrackData[i].Control; + break; + } + } + + return (control & 4) ? DATA_TRACK : AUDIO_TRACK; +} + +int +plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +{ + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + DWORD size; + int pos = 0; + int cur_track = plat_cdrom_get_track(sector); + + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + if (plat_cdrom_open()) + return 0; + DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &size, NULL); + plat_cdrom_exit(); + + *attr = sub.CurrentPosition.Control; + *track = (uint8_t)(cur_track + 1); + *index = sub.CurrentPosition.IndexNumber; + + FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); + + /* Absolute position should be adjusted by 150, not the relative ones. */ + FRAMES_TO_MSF(sector - toc.FirstTrack, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); + + return 1; +} + +int +plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +{ + CDROM_TOC toc; + DWORD byteCount; + + *st_track = toc.FirstTrack; + *end = toc.LastTrack; + FRAMES_TO_MSF(toc.TrackData[*end].TrackNumber + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); + + return 1; +} + +/* This replaces both Info and EndInfo, they are specified by a variable. */ +int +plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr) +{ + int pos; + DWORD byteCount; + + pclog("plat_cdrom_get_audio_track_info(): start track = %d, last track = %d.\n", track, end); + + if ((track < 1) || (track > end)) + return 0; + + pos = toc.FirstTrack + 150; + + FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); + + *track_num = toc.TrackData[track - 1].TrackNumber; + *attr = toc.TrackData[track - 1].Control; + + return 1; +} + +uint32_t +plat_get_sector_size(void) +{ + DISK_GEOMETRY dgCDROM; + DWORD size; + + if (plat_cdrom_open()) + return 0; + DeviceIoControl(hIOCTL, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(DISK_GEOMETRY), &size, NULL); + plat_cdrom_exit(); + + if (dgCDROM.MediaType != 11) // Removable Media Check + return 0; + + return dgCDROM.BytesPerSector; +} + +int +plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +{ + int ret; + LARGE_INTEGER pos; + RAW_READ_INFO in; + DWORD byteCount; + pclog("plat_cdrom_read_sector(): raw? = %d, sector = %02x.\n", raw, sector); + + if (raw) { + in.TrackMode = CDDA; + in.SectorCount = 1; + in.DiskOffset.QuadPart = sector * RAW_SECTOR_SIZE; + if (plat_cdrom_open()) + return 0; + ret = DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(RAW_READ_INFO), buffer, RAW_SECTOR_SIZE, &byteCount, NULL); + plat_cdrom_exit(); + return ret; + } else { + pos.QuadPart = sector * COOKED_SECTOR_SIZE; + if (plat_cdrom_open()) + return 0; + SetFilePointer(hIOCTL, pos.LowPart, &pos.HighPart, FILE_BEGIN); + ret = ReadFile(hIOCTL, buffer, COOKED_SECTOR_SIZE, &byteCount, NULL); + plat_cdrom_exit(); + pclog("plat_cdrom_read_sector(): ret = %x.\n", !ret); + return !ret; + } + return 0; +} + +uint32_t +plat_cdrom_get_capacity(void) +{ + DWORD size; + int c; + DISK_GEOMETRY dgCDROM; + uint32_t totals; + + if (plat_cdrom_open()) + return 0; + DeviceIoControl(hIOCTL, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(DISK_GEOMETRY), &size, NULL); + plat_cdrom_exit(); + + totals = dgCDROM.SectorsPerTrack * dgCDROM.TracksPerCylinder * dgCDROM.Cylinders.QuadPart; + + pclog("Total = %08x.\n", totals); + return totals; +} + +int +plat_cdrom_load(void) +{ + int ret; + DWORD size; + + if (plat_cdrom_open()) + return 0; + DeviceIoControl(hIOCTL, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &size, NULL); + plat_cdrom_exit(); + return 1; +} + +int +plat_cdrom_eject(void) +{ + int ret; + DWORD size; + + if (plat_cdrom_open()) + return 0; + ret = DeviceIoControl(hIOCTL, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &size, NULL); + plat_cdrom_exit(); + return ret; +} + +void +plat_cdrom_exit(void) +{ + if (hIOCTL) { + CloseHandle(hIOCTL); + hIOCTL = NULL; + } +} + +void +plat_cdrom_close(void) +{ + plat_cdrom_exit(); +} + +int +plat_cdrom_reset(void) +{ + CDROM_TOC ltoc; + DWORD size; + + if (plat_cdrom_open()) + return 0; + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + plat_cdrom_exit(); + + toc = ltoc; + return 1; +} + +int +plat_cdrom_open(void) +{ + plat_cdrom_exit(); + hIOCTL = CreateFile((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hIOCTL == NULL) + return 1; + + return 0; +} From 91da7aab511f4187650b6f24d64456488647a1ca Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 15:53:26 +0600 Subject: [PATCH 004/690] Merge prep --- src/machine/m_at_socket370.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 5e60885f3..b8cc437a1 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -312,10 +312,6 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); - if (gfxcard[0] == VID_INTERNAL) { - extern const device_t chips_69000_onboard_device; - device_add(&chips_69000_onboard_device); - } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; From 00a5017f5549284529fa8055058dc628e4b962bd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 15:57:09 +0600 Subject: [PATCH 005/690] Re-add it again --- src/machine/m_at_socket370.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 2b2615422..4920f3d27 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -351,6 +351,10 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); + if (gfxcard[0] == VID_INTERNAL) { + extern const device_t chips_69000_onboard_device; + device_add(&chips_69000_onboard_device); + } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; From c95a0ac599524f756eeaa95e62e82eb0db082084 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:23:23 +0600 Subject: [PATCH 006/690] Update vid_c&t_69000.c --- src/video/vid_c&t_69000.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fe22985e0..4856aff33 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -42,6 +42,7 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; + uint8_t slot; atomic_bool engine_active; atomic_bool quit; thread_t *accel_thread; @@ -1193,7 +1194,7 @@ uint16_t chips_69000_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -1205,7 +1206,7 @@ uint32_t chips_69000_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -1217,7 +1218,7 @@ void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writeb_mmio(addr, val, chips); @@ -1229,7 +1230,7 @@ void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -1241,7 +1242,7 @@ void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); @@ -1271,7 +1272,7 @@ chips_69000_init(const device_t *info) io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips, &chips->slot); chips->svga.bpp = 8; chips->svga.miscout = 1; From 8724f30320b1b09e32a3ab317126e0cf0ad73e9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:31:35 +0600 Subject: [PATCH 007/690] Update vid_c&t_69000.c --- src/video/vid_c&t_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 4856aff33..c994e8e54 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1182,7 +1182,7 @@ uint8_t chips_69000_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readb_mmio(addr, chips); @@ -1268,7 +1268,7 @@ chips_69000_init(const device_t *info) NULL, chips_69000_in, chips_69000_out, NULL, - NULL); + chips_69000_recalctimings); io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); From f313e420d3887db891009cd3121668fd996d30b7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:35:10 +0600 Subject: [PATCH 008/690] Ok fixed for real --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index c994e8e54..a06246538 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -544,7 +544,7 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpatte void chips_69000_recalctimings(svga_t *svga) { - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; @@ -1265,10 +1265,10 @@ chips_69000_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ - NULL, + chips_69000_recalctimings, chips_69000_in, chips_69000_out, NULL, - chips_69000_recalctimings); + NULL); io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); From 0d427c813838db3a3e1d35aae420d30dd24a1356 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 13:41:35 +0600 Subject: [PATCH 009/690] Fix video modes for real --- src/video/vid_c&t_69000.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fe22985e0..6c9abd742 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -39,6 +39,7 @@ typedef struct chips_69000_t { svga_t svga; uint8_t pci_conf_status; + uint8_t slot; uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; @@ -543,7 +544,7 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpatte void chips_69000_recalctimings(svga_t *svga) { - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; @@ -581,7 +582,7 @@ chips_69000_recalctimings(svga_t *svga) /* Let's care about horizontal blanking end later when it matters. */ svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; - svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 16; + svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; } svga->interlace = !!(svga->crtc[0x70] & 0x80); @@ -614,6 +615,11 @@ chips_69000_recalctimings(svga_t *svga) svga->rowoffset <<= 2; break; } + + if (chips->ext_regs[0x40] & 1) { + svga->force_dword_mode = chips->ext_regs[0x40] & 1; + svga->rowoffset >>= 2; + } } void @@ -701,6 +707,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0x40: chips->ext_regs[chips->ext_index] = val & 0x3; chips_69000_recalc_banking(chips); + svga_recalctimings(&chips->svga); break; case 0x60: chips->ext_regs[chips->ext_index] = val & 0x43; @@ -1181,7 +1188,7 @@ uint8_t chips_69000_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readb_mmio(addr, chips); @@ -1193,7 +1200,7 @@ uint16_t chips_69000_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -1205,7 +1212,7 @@ uint32_t chips_69000_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -1217,7 +1224,7 @@ void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writeb_mmio(addr, val, chips); @@ -1229,7 +1236,7 @@ void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -1241,7 +1248,7 @@ void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); @@ -1271,7 +1278,7 @@ chips_69000_init(const device_t *info) io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips, &chips->slot); chips->svga.bpp = 8; chips->svga.miscout = 1; From 82e95cf59cb43465d278d9aee5a72f0b4c11686f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 16:56:08 +0600 Subject: [PATCH 010/690] More C&T 69000 fixes --- src/video/vid_c&t_69000.c | 70 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 92de759f9..5b1384b17 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -43,7 +43,6 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; - uint8_t slot; atomic_bool engine_active; atomic_bool quit; thread_t *accel_thread; @@ -580,46 +579,45 @@ chips_69000_recalctimings(svga_t *svga) if (!(chips->ext_regs[0x81] & 0x10)) svga->htotal += 5; - /* Let's care about horizontal blanking end later when it matters. */ + svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); + svga->hblank_end_len = 0x100; svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; - } - - svga->interlace = !!(svga->crtc[0x70] & 0x80); - switch (chips->ext_regs[0x81] & 0xF) { - case 0b0010: - svga->bpp = 8; - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 2; - break; + svga->interlace = !!(svga->crtc[0x70] & 0x80); - case 0b0100: - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0101: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0110: - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0111: - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 2; - break; - } + switch (chips->ext_regs[0x81] & 0xF) { + case 0b0010: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; - if (chips->ext_regs[0x40] & 1) { - svga->force_dword_mode = chips->ext_regs[0x40] & 1; - svga->rowoffset >>= 2; + case 0b0100: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + break; + case 0b0101: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + case 0b0110: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + case 0b0111: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + break; + } + + if (chips->ext_regs[0x40] & 1) { + svga->force_dword_mode = chips->ext_regs[0x40] & 1; + } else { + svga->force_dword_mode = 0; + } + } else { + svga->force_dword_mode = 0; } } @@ -976,7 +974,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24) - 1); + mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } case 0x3c: From 844e6e8579d8a213ccc71dfcf7fb6de566c87af7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 21:18:55 +0600 Subject: [PATCH 011/690] Fix 8bpp modes --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5b1384b17..aa42b61d6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -725,7 +725,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) break; case 0x80: chips->ext_regs[chips->ext_index] = val & 0xBF; - chips->svga.ramdac_type = (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT; + svga_set_ramdac_type(&chips->svga, (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT); break; case 0x81: chips->ext_regs[chips->ext_index] = val & 0x1f; @@ -769,7 +769,7 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) } break; case 0x3c9: - if (!(chips->ext_regs[0x09] & 0x01)) + if (!(chips->ext_regs[0x80] & 0x01)) break; if (svga->adv_flags & FLAG_RAMDAC_SHIFT) val <<= 2; @@ -840,7 +840,7 @@ chips_69000_in(uint16_t addr, void *p) case 0x3C5: return svga->seqregs[svga->seqaddr]; case 0x3c9: - if (!(chips->ext_regs[0x09] & 0x01)) { + if (!(chips->ext_regs[0x80] & 0x01)) { temp = svga_in(addr, svga); break; } From 439c1152fb4d2fe0a2d4c487a2667d683c286096 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 22:00:12 +0600 Subject: [PATCH 012/690] C&T_69000: All modes are working --- src/video/vid_c&t_69000.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index aa42b61d6..e351f51af 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -610,14 +610,6 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - - if (chips->ext_regs[0x40] & 1) { - svga->force_dword_mode = chips->ext_regs[0x40] & 1; - } else { - svga->force_dword_mode = 0; - } - } else { - svga->force_dword_mode = 0; } } @@ -638,7 +630,6 @@ chips_69000_recalc_banking(chips_69000_t *chips) svga->chain2_write = !(svga->seqregs[0x4] & 4); svga->chain4 = (svga->seqregs[0x4] & 8) || (chips->ext_regs[0xA] & 0x4); - svga->packed_chain4 = !!(chips->ext_regs[0xA] & 0x4); svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); if (chips->ext_regs[0xA] & 1) { @@ -1288,6 +1279,8 @@ chips_69000_init(const device_t *info) chips->quit = 0; chips->engine_active = 0; chips->on_board = !!(info->local); + + chips->svga.packed_chain4 = 1; timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); From 2ee97bf1e190d8a00bbacf9ae3e0969a249560cd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 23:33:55 +0600 Subject: [PATCH 013/690] DDC work --- src/video/vid_c&t_69000.c | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index e351f51af..5037cb1c2 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -10,11 +10,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Cacodemon345 * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2023-2024 Cacodemon345 */ #include #include @@ -34,6 +32,8 @@ #include <86box/vid_svga_render.h> #include <86box/pci.h> #include <86box/thread.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> #include typedef struct chips_69000_t { @@ -81,6 +81,8 @@ typedef struct chips_69000_t { }; rom_t bios_rom; + + void* i2c_ddc, *ddc; } chips_69000_t; static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; @@ -666,7 +668,16 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x0A: return chips->ext_regs[index] & 0x37; case 0x63: - return 0xFF; + { + uint8_t val = chips->ext_regs[index]; + if (!(chips->ext_regs[0x62] & 0x8)) + val = (val & ~8) | (i2c_gpio_get_scl(chips->i2c_ddc) << 3); + + if (!(chips->ext_regs[0x62] & 0x4)) + val = (val & ~4) | (i2c_gpio_get_sda(chips->i2c_ddc) << 2); + + return val; + } case 0x70: return 0x3; case 0x71: @@ -711,6 +722,24 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0x62: chips->ext_regs[chips->ext_index] = val & 0x9C; break; + case 0x63: + { + uint8_t scl = 0, sda = 0; + if (chips->ext_regs[0x62] & 0x8) + scl = !!(val & 8); + else + scl = i2c_gpio_get_scl(chips->i2c_ddc); + + if (chips->ext_regs[0x62] & 0x4) + sda = !!(val & 4); + else + scl = i2c_gpio_get_sda(chips->i2c_ddc); + + i2c_gpio_set(chips->i2c_ddc, scl, sda); + + chips->ext_regs[chips->ext_index] = val & 0x9F; + break; + } case 0x67: chips->ext_regs[chips->ext_index] = val & 0x2; break; @@ -1285,6 +1314,9 @@ chips_69000_init(const device_t *info) timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); + chips->i2c_ddc = i2c_gpio_init("c&t_69000_mga"); + chips->ddc = ddc_init(i2c_gpio_get_bus(chips->i2c_ddc)); + return chips; } @@ -1302,6 +1334,8 @@ chips_69000_close(void *p) chips->quit = 1; // thread_set_event(chips->fifo_event); // thread_wait(chips->accel_thread); + ddc_close(chips->ddc); + i2c_gpio_close(chips->i2c_ddc); svga_close(&chips->svga); free(chips); From f018ef27889c40e54153d9d8933dc5245acdf3d5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 00:59:37 +0600 Subject: [PATCH 014/690] More changes --- src/video/vid_c&t_69000.c | 108 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5037cb1c2..5e23c0710 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -83,10 +83,68 @@ typedef struct chips_69000_t { rom_t bios_rom; void* i2c_ddc, *ddc; + + uint8_t st01; } chips_69000_t; static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +/* Multimedia handling. */ +uint8_t +chips_69000_read_multimedia(chips_69000_t* chips) +{ + switch (chips->mm_index) { + case 0: + /* Report no playback/capture capability. */ + return 0; + default: + return chips->mm_regs[chips->mm_index]; + } + return chips->mm_regs[chips->mm_index]; +} + +/* Multimedia (write) handling. */ +void +chips_69000_write_multimedia(chips_69000_t* chips, uint8_t val) +{ + switch (chips->mm_index) { + case 0: + return; + default: + chips->mm_regs[chips->mm_index] = val; + break; + } + chips->mm_regs[chips->mm_index] = val; +} + +/* Flat panel handling. */ +uint8_t +chips_69000_read_flat_panel(chips_69000_t* chips) +{ + switch (chips->flat_panel_index) { + case 0: + /* Report no presence of flat panel module. */ + return 0; + default: + return chips->flat_panel_regs[chips->flat_panel_index]; + } + return chips->flat_panel_regs[chips->flat_panel_index]; +} + +/* Flat panel (write) handling. */ +void +chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) +{ + switch (chips->flat_panel_index) { + case 0: + return; + default: + chips->flat_panel_regs[chips->flat_panel_index] = val; + break; + } + chips->flat_panel_regs[chips->flat_panel_index] = val; +} + void chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) { @@ -813,6 +871,18 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); chips_69000_recalc_banking(chips); return; +#if 1 + case 0x3D0: + chips->flat_panel_index = val; + return; + case 0x3D1: + return chips_69000_write_flat_panel(chips, val); + case 0x3D2: + chips->mm_index = val; + return; + case 0x3D3: + return chips_69000_write_multimedia(chips, val); +#endif case 0x3D4: svga->crtcreg = val & 0xff; return; @@ -850,7 +920,7 @@ chips_69000_in(uint16_t addr, void *p) { chips_69000_t *chips = (chips_69000_t *) p; svga_t *svga = &chips->svga; - uint8_t temp, index; + uint8_t temp = 0, index; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -892,6 +962,16 @@ chips_69000_in(uint16_t addr, void *p) if (svga->adv_flags & FLAG_RAMDAC_SHIFT) temp >>= 2; break; +#if 1 + case 0x3D0: + return chips->flat_panel_index; + case 0x3D1: + return chips_69000_read_flat_panel(chips); + case 0x3D2: + return chips->mm_index; + case 0x3D3: + return chips_69000_read_multimedia(chips); +#endif case 0x3D4: temp = svga->crtcreg; break; @@ -1124,6 +1204,8 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; + if ((addr & 0xFFF) == 0x023) + pclog("BitBLT/Draw operation\n"); break; case 0x600 ... 0x60F: chips->mem_regs_b[addr & 0xF] = val; @@ -1275,11 +1357,25 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_writel_linear(addr & 0x1FFFFF, val, p); } +void +chips_69000_vsync_start(svga_t *svga) +{ + /* TODO: PCI interrupts for this. */ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + +} + +void +chips_69000_vblank_start(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + /* Needed? */ +} + static void * chips_69000_init(const device_t *info) { - chips_69000_t *chips = malloc(sizeof(chips_69000_t)); - memset(chips, 0, sizeof(chips_69000_t)); + chips_69000_t *chips = calloc(1, sizeof(chips_69000_t)); /* Appears to have an odd VBIOS size. */ if (!info->local) { @@ -1302,6 +1398,8 @@ chips_69000_init(const device_t *info) chips->svga.bpp = 8; chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; + chips->svga.vsync_callback = chips_69000_vsync_start; + chips->svga.vblank_start = chips_69000_vblank_start; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); @@ -1316,6 +1414,10 @@ chips_69000_init(const device_t *info) chips->i2c_ddc = i2c_gpio_init("c&t_69000_mga"); chips->ddc = ddc_init(i2c_gpio_get_bus(chips->i2c_ddc)); + + chips->flat_panel_regs[0x01] = 1; + + sizeof(chips->bitblt_regs); return chips; } From 2b0a494eded5f493240c7cdccc00709dcabfc97f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 13:24:51 +0600 Subject: [PATCH 015/690] Report linear mapping properly --- src/video/vid_c&t_69000.c | 57 ++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5e23c0710..9ce7f89b5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -707,46 +707,65 @@ uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { uint8_t index = chips->ext_index; + uint8_t val = chips->ext_regs[index]; switch (index) { case 0x00: - return 0x2C; + val = 0x2C; + break; case 0x01: - return 0x10; + val = 0x10; + break; case 0x02: - return 0xC0; + val = 0xC0; + break; case 0x03: - return 0x00; + val = 0x00; + break; case 0x04: - return 0x62; + val = 0x62; + break; case 0x05: + val = 0x00; + break; case 0x06: - return 0x00; + val = chips->linear_mapping.base >> 24; + break; case 0x08: - return 0x02; + val = 0x02; + break; case 0x0A: - return chips->ext_regs[index] & 0x37; + val = chips->ext_regs[index] & 0x37; + break; case 0x63: { - uint8_t val = chips->ext_regs[index]; + val = chips->ext_regs[index]; if (!(chips->ext_regs[0x62] & 0x8)) val = (val & ~8) | (i2c_gpio_get_scl(chips->i2c_ddc) << 3); if (!(chips->ext_regs[0x62] & 0x4)) val = (val & ~4) | (i2c_gpio_get_sda(chips->i2c_ddc) << 2); - return val; + break; } case 0x70: - return 0x3; + val = 0x3; + break; case 0x71: - return 0x0; + val = 0x0; + break; } - return chips->ext_regs[index]; + //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { + //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + //&& (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -809,6 +828,8 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0xD2: + break; default: chips->ext_regs[chips->ext_index] = val; break; @@ -1002,11 +1023,13 @@ chips_69000_pci_read(int func, int addr, void *p) { switch (addr) { case 0x00: + return 0x2C; case 0x01: - return (0x102C >> ((addr & 1) * 8)) & 0xFF; + return 0x10; case 0x02: + return 0xC0; case 0x03: - return (0x00C0 >> ((addr & 1) * 8)) & 0xFF; + return 0x00; case 0x04: return chips->pci_conf_status; case 0x07: @@ -1074,6 +1097,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { + if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { + chips->linear_mapping.base = val << 24; + break; + } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } From a9b3fdd945dd6aa9be691bff9aa7ebfa815f2eb6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 16:34:34 +0600 Subject: [PATCH 016/690] BitBLT work --- src/video/vid_c&t_69000.c | 274 +++++++++++++++++++------------------- 1 file changed, 138 insertions(+), 136 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 9ce7f89b5..cab0f0f21 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -36,10 +36,55 @@ #include <86box/vid_ddc.h> #include +#pragma pack(push, 1) +typedef struct chips_69000_bitblt_t +{ + /* BR00 - Source and Destination Span Register. */ + uint16_t source_span; + uint16_t destination_span; + + /* BR01 - Pattern/Source Expansion Background Color & Transparency Key Register. */ + uint32_t pattern_source_key_bg; + + /* BR02 - Pattern/Source Expansion Foreground Color Register. */ + uint32_t pattern_source_key_fg; + + /* BR03 - Monochrome Source Control Register. */ + uint8_t monochrome_source_left_clip; + uint8_t monochrome_source_right_clip; + uint8_t monochrome_source_initial_discard; + uint8_t monochrome_source_alignment : 3; + uint8_t monochrome_source_expansion_color_reg_select : 1; + uint8_t dummy_8 : 4; + + /* BR04 - BitBLT Control Register. */ + uint32_t bitblt_control; + + /* BR05 - Pattern Address Register. */ + uint32_t pat_addr; + + /* BR06 - Source Address Register. */ + uint32_t source_addr; + + /* BR07 - Destination Address Register. */ + uint32_t destination_addr; + + /* BR08 - Destination Width & Height Register. */ + uint16_t destination_width; + uint16_t destination_height; + + /* BR09 - Source Expansion Background Color & Transparency Key Register. */ + uint32_t source_key_bg; + + /* BR0A - Source Expansion Foreground Color Register. */ + uint32_t source_key_fg; +}; +#pragma pack(pop) + typedef struct chips_69000_t { svga_t svga; uint8_t pci_conf_status; - uint8_t slot; + uint8_t slot, irq_state; uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; @@ -65,11 +110,21 @@ typedef struct chips_69000_t { uint8_t mem_regs_b[4 * 4]; }; union { - uint32_t bitblt_regs[16]; - uint16_t bitblt_regs_w[16 * 2]; - uint8_t bitblt_regs_b[16 * 4]; + uint32_t bitblt_regs[11]; + uint16_t bitblt_regs_w[11 * 2]; + uint8_t bitblt_regs_b[11 * 4]; + struct chips_69000_bitblt_t bitblt; }; + struct + { + struct chips_69000_bitblt_t bitblt; + + uint32_t actual_source_height; + uint32_t actual_destination_height; + uint8_t bytes_per_pixel; + } bitblt_running; + union { uint16_t subsys_vid; uint8_t subsys_vid_b[2]; @@ -145,6 +200,20 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) chips->flat_panel_regs[chips->flat_panel_index] = val; } +void +chips_69000_interrupt(chips_69000_t* chips) +{ + pci_irq(chips->slot, PCI_INTA, 0, !!((chips->mem_regs[0] & chips->mem_regs[1]) & 0x80004040), &chips->irq_state); +} + +void +chips_69000_bitblt_interrupt(chips_69000_t* chips) +{ + chips->mem_regs[1] |= 1 << 31; + + chips_69000_interrupt(chips); +} + void chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) { @@ -199,63 +268,6 @@ chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) } } -void -chips_69000_do_rop_15bpp(uint16_t *dst, uint16_t src, uint8_t rop) -{ - uint16_t orig_dst = *dst & 0x8000; - switch (rop) { - case 0x00: - *dst = 0; - break; - case 0x11: - *dst = ~(*dst) & ~src; - break; - case 0x22: - *dst &= ~src; - break; - case 0x33: - *dst = ~src; - break; - case 0x44: - *dst = src & ~(*dst); - break; - case 0x55: - *dst = ~*dst; - break; - case 0x66: - *dst ^= src; - break; - case 0x77: - *dst = ~src | ~(*dst); - break; - case 0x88: - *dst &= src; - break; - case 0x99: - *dst ^= ~src; - break; - case 0xAA: - break; /* No-op. */ - case 0xBB: - *dst |= ~src; - break; - case 0xCC: - *dst = src; - break; - case 0xDD: - *dst = src | ~(*dst); - break; - case 0xEE: - *dst |= src; - break; - case 0xFF: - *dst = ~0; - break; - } - *dst &= 0x7FFF; - *dst |= orig_dst; -} - void chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) { @@ -424,66 +436,6 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } } -void -chips_69000_do_rop_15bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) -{ - uint16_t orig_dst = *dst & 0x8000; - switch (rop) { - case 0x00: - *dst = 0; - break; - case 0x05: - *dst = ~(*dst) & ~src; - break; - case 0x0A: - *dst &= ~src; - break; - case 0x0F: - *dst = ~src; - break; - case 0x50: - *dst = src & ~(*dst); - break; - case 0x55: - *dst = ~*dst; - break; - case 0x5A: - *dst ^= src; - break; - case 0x5F: - *dst = ~src | ~(*dst); - break; - case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); - break; - case 0xA0: - *dst &= src; - break; - case 0xA5: - *dst ^= ~src; - break; - case 0xAA: - break; /* No-op. */ - case 0xAF: - *dst |= ~src; - break; - case 0xF0: - *dst = src; - break; - case 0xF5: - *dst = src | ~(*dst); - break; - case 0xFA: - *dst |= src; - break; - case 0xFF: - *dst = 0xFF; - break; - } - *dst &= 0x7FFF; - *dst |= orig_dst; -} - void chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) { @@ -703,6 +655,24 @@ chips_69000_recalc_banking(chips_69000_t *chips) }*/ } +void +chips_69000_setup_bitblt(chips_69000_t* chips) +{ + chips->engine_active = 1; + chips->bitblt_running.bitblt = chips->bitblt; + chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; + chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; + + if (!chips->bitblt_running.actual_destination_height) { + chips->bitblt_running.actual_destination_height = 1; + } + + + /*Stubbed!*/ + chips->engine_active = 0; + chips_69000_bitblt_interrupt(chips); +} + uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { @@ -736,6 +706,11 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x0A: val = chips->ext_regs[index] & 0x37; break; + case 0x20: + val &= ~1; + val |= !!(chips->bitblt.bitblt_control & (1 << 31)); + /* TODO: Handle BitBLT reset, if required. */ + break; case 0x63: { val = chips->ext_regs[index]; @@ -983,7 +958,6 @@ chips_69000_in(uint16_t addr, void *p) if (svga->adv_flags & FLAG_RAMDAC_SHIFT) temp >>= 2; break; -#if 1 case 0x3D0: return chips->flat_panel_index; case 0x3D1: @@ -992,7 +966,6 @@ chips_69000_in(uint16_t addr, void *p) return chips->mm_index; case 0x3D3: return chips_69000_read_multimedia(chips); -#endif case 0x3D4: temp = svga->crtcreg; break; @@ -1146,6 +1119,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: return chips->bitblt_regs_b[addr & 0xFF]; @@ -1208,6 +1182,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) uint16_t chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); @@ -1218,6 +1193,7 @@ chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) uint32_t chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); @@ -1228,13 +1204,44 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; - if ((addr & 0xFFF) == 0x023) - pclog("BitBLT/Draw operation\n"); + if ((addr & 0xFFF) == 0x023) { + uint8_t cntr = 0; + pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); + chips_69000_setup_bitblt(chips); + } break; case 0x600 ... 0x60F: + switch (addr & 0xFFF) + { + case 0x600 ... 0x603: + { + chips->mem_regs_b[addr & 0xF] = val; + chips->mem_regs[addr >> 2] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x604 ... 0x607: + { + chips->mem_regs_b[addr & 0xF] &= ~val; + chips->mem_regs[addr >> 2] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x60c ... 0x60f: + { + chips->mem_regs_b[addr & 0xF] = val; + break; + } + + } chips->mem_regs_b[addr & 0xF] = val; break; case 0x768: @@ -1293,6 +1300,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: chips_69000_writeb_mmio(addr, val, chips); @@ -1304,6 +1312,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) void chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: chips_69000_writew_mmio(addr, val, chips); @@ -1384,19 +1393,13 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_writel_linear(addr & 0x1FFFFF, val, p); } -void -chips_69000_vsync_start(svga_t *svga) -{ - /* TODO: PCI interrupts for this. */ - chips_69000_t *chips = (chips_69000_t *) svga->priv; - -} - void chips_69000_vblank_start(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; - /* Needed? */ + chips->mem_regs[1] |= 1 << 14; + + chips_69000_interrupt(chips); } static void * @@ -1425,7 +1428,6 @@ chips_69000_init(const device_t *info) chips->svga.bpp = 8; chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; - chips->svga.vsync_callback = chips_69000_vsync_start; chips->svga.vblank_start = chips_69000_vblank_start; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); @@ -1444,7 +1446,7 @@ chips_69000_init(const device_t *info) chips->flat_panel_regs[0x01] = 1; - sizeof(chips->bitblt_regs); + sizeof(struct chips_69000_bitblt_t); return chips; } From 2b6cf4846c4ba36c41e9b14198043366ef881c25 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 01:53:17 +0600 Subject: [PATCH 017/690] No more nonsense getting DWORD-written --- src/video/vid_c&t_69000.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index cab0f0f21..bc660283e 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -729,18 +729,18 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x0; break; } - //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - //&& (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); + if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1119,6 +1119,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { + pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1204,6 +1205,7 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { + pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1310,7 +1312,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) } void -chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { addr &= 0xFFF; switch (addr & 0xFFF) { From 10de00c984d32f544f33e25c66c1b751aa416746 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 15:19:23 +0600 Subject: [PATCH 018/690] BitBlt works, but improperly --- src/video/vid_c&t_69000.c | 232 +++++++++++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 16 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index bc660283e..fde218ed8 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -78,7 +78,7 @@ typedef struct chips_69000_bitblt_t /* BR0A - Source Expansion Foreground Color Register. */ uint32_t source_key_fg; -}; +} chips_69000_bitblt_t; #pragma pack(pop) typedef struct chips_69000_t { @@ -122,6 +122,13 @@ typedef struct chips_69000_t { uint32_t actual_source_height; uint32_t actual_destination_height; + + uint32_t actual_destination_width; + + uint32_t count_x, count_y; + uint32_t x, y; + int x_dir, y_dir; + uint8_t bytes_per_pixel; } bitblt_running; @@ -144,6 +151,13 @@ typedef struct chips_69000_t { static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +uint8_t chips_69000_readb_linear(uint32_t addr, void *p); +uint16_t chips_69000_readw_linear(uint32_t addr, void *p); +uint32_t chips_69000_readl_linear(uint32_t addr, void *p); +void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p); +void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p); +void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p); + /* Multimedia handling. */ uint8_t chips_69000_read_multimedia(chips_69000_t* chips) @@ -209,6 +223,7 @@ chips_69000_interrupt(chips_69000_t* chips) void chips_69000_bitblt_interrupt(chips_69000_t* chips) { + chips->engine_active = 0; chips->mem_regs[1] |= 1 << 31; chips_69000_interrupt(chips); @@ -382,6 +397,10 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) void chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) { + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_8bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -439,6 +458,10 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ void chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) { + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -497,6 +520,11 @@ void chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; + + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_24bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -655,6 +683,99 @@ chips_69000_recalc_banking(chips_69000_t *chips) }*/ } +void +chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) +{ + uint32_t pattern_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t pattern_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + uint8_t pattern_data = 0; + uint8_t pattern_data_8bpp[8][8]; + uint16_t pattern_data_16bpp[8][8]; + uint32_t pattern_pixel = 0; + uint32_t dest_pixel = 0; + uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + dest_pixel |= chips_69000_readb_linear(dest_addr + 2, chips) << 16; + break; + } + } + + /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { + uint8_t is_true = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) + pattern_data = 0; + else + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (vert_pat_alignment + chips->bitblt_running.count_y), chips); + + is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { + return; + } + + pattern_pixel = is_true ? pattern_fg : pattern_bg; + + pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_do_rop_8bpp_patterned((uint8_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_do_rop_16bpp_patterned((uint16_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_do_rop_24bpp_patterned((uint32_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 2, (dest_pixel >> 16) & 0xFF, chips); + break; + } + } +} + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -662,14 +783,90 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; + chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; - if (!chips->bitblt_running.actual_destination_height) { - chips->bitblt_running.actual_destination_height = 1; + if (chips->bitblt.bitblt_control & (1 << 23)) { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); + } else { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->ext_regs[0x20] >> 4) & 3); } - - /*Stubbed!*/ - chips->engine_active = 0; + chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; + + switch ((chips->bitblt.bitblt_control >> 8) & 3) { + case 0: + chips->bitblt_running.x = 0; + chips->bitblt_running.y = 0; + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = 1; + break; + case 1: + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + chips->bitblt_running.y = 0; + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = 1; + break; + case 2: + chips->bitblt_running.x = 0; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = -1; + break; + case 3: + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = -1; + break; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } + + /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { + chips_69000_bitblt_interrupt(chips); + return; + } + + do { + do { + uint32_t pixel = 0; + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.y * chips->bitblt.source_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + pixel |= chips_69000_readb_linear(source_addr + 2, chips) << 16; + break; + } + } + + chips_69000_process_pixel(chips, pixel); + + chips->bitblt_running.x += chips->bitblt_running.x_dir; + } while ((chips->bitblt_running.count_x++) < chips->bitblt_running.actual_destination_width); + + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_x = 0; + } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + chips_69000_bitblt_interrupt(chips); } @@ -708,7 +905,7 @@ chips_69000_read_ext_reg(chips_69000_t* chips) break; case 0x20: val &= ~1; - val |= !!(chips->bitblt.bitblt_control & (1 << 31)); + val |= !!chips->engine_active; /* TODO: Handle BitBLT reset, if required. */ break; case 0x63: @@ -729,18 +926,18 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x0; break; } - if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); + // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1119,10 +1316,13 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { - pclog("C&T Read 0x%X\n", addr); + //pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: + if (addr == 0x10) { + return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); + } return chips->bitblt_regs_b[addr & 0xFF]; case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; @@ -1205,12 +1405,12 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { - pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); + //pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; - if ((addr & 0xFFF) == 0x023) { + if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { uint8_t cntr = 0; pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); chips_69000_setup_bitblt(chips); From 2dba92221fdc2ffc4997dda1f52397c745efa6c5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 19:48:09 +0600 Subject: [PATCH 019/690] Try fixing overdrawing --- src/video/vid_c&t_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fde218ed8..75848a7f5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -861,11 +861,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_process_pixel(chips, pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - } while ((chips->bitblt_running.count_x++) < chips->bitblt_running.actual_destination_width); + } while ((++chips->bitblt_running.count_x) < chips->bitblt_running.actual_destination_width); chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); chips_69000_bitblt_interrupt(chips); } From e0503e6381b4e3562b15e51612167bee7a1cde12 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 01:44:51 +0600 Subject: [PATCH 020/690] Patterns now are blitted correctly --- src/video/vid_c&t_69000.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 75848a7f5..05c549d2f 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -130,6 +130,9 @@ typedef struct chips_69000_t { int x_dir, y_dir; uint8_t bytes_per_pixel; + + /* Byte counter for BitBLT port writes. */ + uint8_t bytes_written; } bitblt_running; union { @@ -693,7 +696,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint16_t pattern_data_16bpp[8][8]; uint32_t pattern_pixel = 0; uint32_t dest_pixel = 0; - uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; switch (chips->bitblt_running.bytes_per_pixel) { @@ -723,7 +726,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (vert_pat_alignment + chips->bitblt_running.count_y), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.count_y) & 7), chips); is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); @@ -793,7 +796,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; - switch ((chips->bitblt.bitblt_control >> 8) & 3) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 8) & 3) { case 0: chips->bitblt_running.x = 0; chips->bitblt_running.y = 0; @@ -808,13 +811,13 @@ chips_69000_setup_bitblt(chips_69000_t* chips) break; case 2: chips->bitblt_running.x = 0; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = -1; break; case 3: chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; break; @@ -865,7 +868,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); chips_69000_bitblt_interrupt(chips); } From 2690132bc37b1785740adb179ca1c8843b6bb1d8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 02:28:32 +0600 Subject: [PATCH 021/690] WIP BitBLT port work --- src/video/vid_c&t_69000.c | 66 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 05c549d2f..c3912fa77 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -133,6 +133,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint8_t bytes_port[4]; } bitblt_running; union { @@ -721,14 +722,15 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ + /* Also: is horizontal pattern alignment a requirement? */ if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { uint8_t is_true = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.count_y) & 7), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.y) & 7), chips); - is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); + is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { return; @@ -737,6 +739,12 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) pattern_pixel = is_true ? pattern_fg : pattern_bg; pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + } else { + if (chips->bitblt_running.bytes_per_pixel == 1) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7) + + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); + } } switch (chips->bitblt_running.bytes_per_pixel) { @@ -787,6 +795,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; + chips->bitblt_running.bytes_written = 0; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -877,6 +886,43 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_bitblt_interrupt(chips); } +void +chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { + + if (!chips->engine_active) + return; + + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { + uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + if (chips->bitblt_running.bytes_per_pixel == 1) + source_pixel = (chips->bitblt_running.bytes_port[1] << 8); + if (chips->bitblt_running.bytes_per_pixel == 2) + source_pixel = (chips->bitblt_running.bytes_port[2] << 16); + + chips_69000_process_pixel(chips, source_pixel); + chips->bitblt_running.x += chips->bitblt_running.x_dir; + chips->bitblt_running.count_x++; + + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_y++; + + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + + if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) { + chips_69000_bitblt_interrupt(chips); + return; + } + } + } +} + uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { @@ -1413,6 +1459,10 @@ void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { //pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1509,6 +1559,11 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { default: @@ -1521,6 +1576,13 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 24) & 0xFF); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { default: From 08660004af780143a2a15dfa97f1bf2d7daa4c56 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 12:32:13 +0600 Subject: [PATCH 022/690] Fix BitBLT status read --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index c3912fa77..786a28778 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1373,7 +1373,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: - if (addr == 0x10) { + if (addr == 0x13) { return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } return chips->bitblt_regs_b[addr & 0xFF]; From 08d784fe07fd655b9d1cb6e17b2a8093bb1e7abb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 13:20:24 +0600 Subject: [PATCH 023/690] Working (but with pitch troubles) BitBLT emulation --- src/video/vid_c&t_69000.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 786a28778..e35f28227 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -460,7 +460,7 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } void -chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpattern_src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); @@ -521,7 +521,7 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpatte } void -chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpattern_src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; @@ -832,10 +832,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) break; } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; - } - /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) @@ -844,6 +840,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } + do { do { uint32_t pixel = 0; @@ -896,16 +896,15 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; - if (chips->bitblt_running.bytes_per_pixel == 1) - source_pixel = (chips->bitblt_running.bytes_port[1] << 8); if (chips->bitblt_running.bytes_per_pixel == 2) - source_pixel = (chips->bitblt_running.bytes_port[2] << 16); + source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); + if (chips->bitblt_running.bytes_per_pixel == 3) + source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - chips->bitblt_running.count_x++; - if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width - 1) { chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; From 33cba9ef5095c3c9575ee452b518fe0ebc4692fa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 15:31:42 +0600 Subject: [PATCH 024/690] More ROP codes --- src/video/vid_c&t_69000.c | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index e35f28227..b2cd62f07 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -133,6 +133,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint32_t bytes_counter; uint8_t bytes_port[4]; } bitblt_running; @@ -418,6 +419,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -430,6 +443,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -444,6 +469,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -479,6 +516,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -491,6 +540,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -505,6 +566,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -542,6 +615,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -554,6 +639,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -568,6 +665,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -796,6 +905,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; + chips->bitblt_running.bytes_counter = 0; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -892,6 +1002,10 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; + + chips->bitblt_running.bytes_counter++; + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) + return; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; From 323c179cee8096efd3fc5c0f735f40b10dbd18d7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:02:49 +0600 Subject: [PATCH 025/690] Force quadword alignment --- src/video/vid_c&t_69000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b2cd62f07..0f058b592 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1018,7 +1018,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width - 1) { + if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (chips->bitblt_running.bitblt.destination_width & 7) + chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; From 45b9cb1980c1c443e15c076d4c7e18ec3ea7702a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:27:46 +0600 Subject: [PATCH 026/690] Part 2 of quadword alignment fixing --- src/video/vid_c&t_69000.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 0f058b592..6fb3ad2a5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1002,7 +1002,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; - chips->bitblt_running.bytes_counter++; if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) return; @@ -1021,8 +1020,12 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { if (chips->bitblt_running.bitblt.destination_width & 7) chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); + else + chips->bitblt_running.bitblt.source_addr = 0; + chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; + chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.count_x = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { From 0bca52bfe5d08dfd8691c7b1ec3615933db1f290 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:45:52 +0600 Subject: [PATCH 027/690] Fix height counting --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 6fb3ad2a5..fae8c04bd 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1033,7 +1033,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } else chips->bitblt_running.x = 0; - if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) { + if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) { chips_69000_bitblt_interrupt(chips); return; } From ac0f7ec9e7f5e1a7d36a5f25db11ba317097f62c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 4 Feb 2024 01:23:26 +0600 Subject: [PATCH 028/690] Implement color transparency and 16/24-bpp color patterns --- src/video/vid_c&t_69000.c | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fae8c04bd..efa619491 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -854,6 +854,43 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7) + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); } + if (chips->bitblt_running.bytes_per_pixel == 2) { + pattern_pixel = chips_69000_readw_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + } + if (chips->bitblt_running.bytes_per_pixel == 3) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; + } + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 1: + case 3: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } } switch (chips->bitblt_running.bytes_per_pixel) { @@ -874,6 +911,25 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 0: + case 2: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } + } + switch (chips->bitblt_running.bytes_per_pixel) { case 1: /* 8 bits-per-pixel. */ { From 35cae93fed7f83c17e9c23facf1c9217abd75c2b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 4 Feb 2024 16:25:17 +0600 Subject: [PATCH 029/690] More monochrome source work Mostly correct now. --- src/video/vid_c&t_69000.c | 189 +++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index efa619491..b34c5c826 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -34,6 +34,7 @@ #include <86box/thread.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/plat_unused.h> #include #pragma pack(push, 1) @@ -134,7 +135,11 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint32_t bytes_counter; - uint8_t bytes_port[4]; + uint8_t bytes_port[8]; + + /* Monochrome sources. */ + uint8_t mono_is_first_quadword; + uint8_t mono_bit_cntr; } bitblt_running; union { @@ -952,6 +957,153 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } +void +chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) +{ + /* Notes: + Reserved value of 0b000 for monochrome source alignment makes it use Destination Scanline Width. + + TODO: + Actually implement this. + + Figure out how alignment works. The example provided is unclear about non-quadword alignment. + (Outside of the one xf86-video-chips already documents). + Maybe it merely advances the source address pointer by alignment after consuming a byte. + + Edit: It actually consumes all 8 bytes of the quadword before incrementing the pitch. + Which begs the next question: Are those 8 bytes for same-scanline drawing or for y-incremented drawing? + And is 4-byte-or-less alignment relevant for our purposes? The Monochrome Source Register only talks about quadwords, nothing else. + */ + + uint64_t i = 0; + uint8_t is_true = 0; + int orig_x = chips->bitblt_running.x; + int orig_y = chips->bitblt_running.y; + uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + + int orig_count_x = chips->bitblt_running.count_x; + int orig_count_y = chips->bitblt_running.count_y; + + chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; + + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { + source_fg = chips->bitblt_running.bitblt.source_key_fg; + source_bg = chips->bitblt_running.bitblt.source_key_bg; + } + + for (i = 0; i < 64; i++) { + uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) + goto increment; + + if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) + goto increment; + + if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) + goto increment; + + is_true = !!(val & (1 << (i))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + goto increment; + } + + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips->bitblt_running.x = orig_x + (chips->bitblt_running.count_x); + chips->bitblt_running.y = orig_y + chips->bitblt_running.count_y; + + if ((orig_count_x + (chips->bitblt_running.count_x)) < chips->bitblt_running.actual_destination_width + && (orig_count_y + chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height) + chips_69000_process_pixel(chips, pixel); + +increment: + chips->bitblt_running.count_x++; + if (chips->bitblt_running.count_x == 8) { + chips->bitblt_running.count_x = 0; + chips->bitblt_running.count_y++; + } + } + chips->bitblt_running.x = orig_x; + chips->bitblt_running.y = orig_y; + chips->bitblt_running.count_x = orig_count_x; + chips->bitblt_running.count_y = orig_count_y; + chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; + chips->bitblt_running.count_x += 8; + chips->bitblt_running.mono_is_first_quadword = 0; + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.count_y += 8; + chips->bitblt_running.y += chips->bitblt_running.y_dir * 8; + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) + chips_69000_bitblt_interrupt(chips); + } +} + +void +chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t val) +{ + uint64_t i = 0; + uint8_t is_true = 0; + int orig_x = chips->bitblt_running.x; + int orig_y = chips->bitblt_running.y; + uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { + source_fg = chips->bitblt_running.bitblt.source_key_fg; + source_bg = chips->bitblt_running.bitblt.source_key_bg; + } + + for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { + uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) + continue; + + if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) + continue; + + if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) + continue; + + is_true = !!(val & (1 << (8 - (i & 7)))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + continue; + } + + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips->bitblt_running.x = orig_x + (i & 7); + + //if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) + chips_69000_process_pixel(chips, pixel); + } + chips->bitblt_running.mono_bit_cntr += 8; + chips->bitblt_running.x = orig_x; + chips->bitblt_running.y = orig_y; + chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; + chips->bitblt_running.count_x += 8; + if (chips->bitblt_running.mono_bit_cntr >= 64) { + chips->bitblt_running.mono_is_first_quadword = 0; + chips->bitblt_running.mono_bit_cntr = 0; + } + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.count_y += 1; + chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) + chips_69000_bitblt_interrupt(chips); + } +} + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -962,6 +1114,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.mono_is_first_quadword = 1; + chips->bitblt_running.mono_bit_cntr = 0; + int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -1010,6 +1165,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit\n"); + } + do { do { uint32_t pixel = 0; @@ -1048,7 +1207,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } else chips->bitblt_running.x = 0; } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); - + cycles = orig_cycles; chips_69000_bitblt_interrupt(chips); } @@ -1058,6 +1217,27 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 + && chips->bitblt_running.bytes_written == 4) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + } else if (chips->bitblt_running.bytes_written == 8) { + chips->bitblt_running.bytes_written = 0; + uint64_t mono_data = chips->bitblt_running.bytes_port[0]; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[1] << 8ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[2] << 16ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[3] << 24ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[4] << 32ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[5] << 40ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[6] << 48ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; + chips_69000_process_mono_data(chips, mono_data); + } + return; + } + chips->bitblt_running.bytes_counter++; if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) return; @@ -1291,7 +1471,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); chips_69000_recalc_banking(chips); return; -#if 1 case 0x3D0: chips->flat_panel_index = val; return; @@ -1302,7 +1481,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) return; case 0x3D3: return chips_69000_write_multimedia(chips, val); -#endif case 0x3D4: svga->crtcreg = val & 0xff; return; @@ -1751,6 +1929,9 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("BitBLT mono 0x%08X\n", val); + } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); chips_69000_bitblt_write(chips, (val >> 16) & 0xFF); From 485d17e117ee743a9c3da831fccfcdfa9048dd60 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 13:03:34 +0600 Subject: [PATCH 030/690] Fix height overdrawing and BitBlt direction --- src/video/vid_c&t_69000.c | 59 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b34c5c826..a101232b9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -127,7 +127,7 @@ typedef struct chips_69000_t { uint32_t actual_destination_width; uint32_t count_x, count_y; - uint32_t x, y; + int x, y; int x_dir, y_dir; uint8_t bytes_per_pixel; @@ -1079,7 +1079,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va chips->bitblt_running.x = orig_x + (i & 7); - //if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) + if ((chips->bitblt_running.count_x + (i & 7)) <= chips->bitblt_running.actual_destination_width) chips_69000_process_pixel(chips, pixel); } chips->bitblt_running.mono_bit_cntr += 8; @@ -1095,10 +1095,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va chips->bitblt_running.count_y += 1; chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; + chips->bitblt_running.x = 0; if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) chips_69000_bitblt_interrupt(chips); } @@ -1126,28 +1123,23 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; + chips->bitblt_running.x = 0; + chips->bitblt_running.y = 0; + switch ((chips->bitblt_running.bitblt.bitblt_control >> 8) & 3) { case 0: - chips->bitblt_running.x = 0; - chips->bitblt_running.y = 0; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = 1; break; case 1: - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = 0; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; break; case 2: - chips->bitblt_running.x = 0; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = -1; break; case 3: - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; break; @@ -1161,12 +1153,21 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " + "monochrome left clip = %d, " + "monochrome right clip = %d, " + "monochrome initial discard = %d, " + "destination_width = %d, destination_height = %d\n", chips->bitblt_running.bitblt.monochrome_source_alignment, + chips->bitblt_running.bitblt.monochrome_source_left_clip, + chips->bitblt_running.bitblt.monochrome_source_right_clip, + chips->bitblt_running.bitblt.monochrome_source_initial_discard, + chips->bitblt_running.bitblt.destination_width, + chips->bitblt_running.bitblt.destination_height); } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { - pclog("C&T: Monochrome blit\n"); + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; } do { @@ -1202,11 +1203,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; - } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + chips->bitblt_running.x = 0; + } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); cycles = orig_cycles; chips_69000_bitblt_interrupt(chips); } @@ -1223,6 +1221,12 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { && chips->bitblt_running.bytes_written == 4) { chips->bitblt_running.bytes_written = 0; chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + if (chips->bitblt_running.actual_destination_width > 16) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); + if (chips->bitblt_running.actual_destination_width > 24) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); } else if (chips->bitblt_running.bytes_written == 8) { chips->bitblt_running.bytes_written = 0; uint64_t mono_data = chips->bitblt_running.bytes_port[0]; @@ -1264,10 +1268,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; + chips->bitblt_running.x = 0; if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) { chips_69000_bitblt_interrupt(chips); @@ -1820,8 +1821,6 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { - uint8_t cntr = 0; - pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); chips_69000_setup_bitblt(chips); } break; @@ -1929,7 +1928,7 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) && chips->bitblt_running.bitblt.destination_width > 8) { pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); From d6e1d6aa322f51edb2e5c9a7faa5de883e8c2b15 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 15:23:36 +0600 Subject: [PATCH 031/690] Monochrome drawing is now finally fixed --- src/video/vid_c&t_69000.c | 196 +++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index a101232b9..afdc748e6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -405,10 +405,10 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) } void -chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_8bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_8bpp(dst, src, rop); } switch (rop) { @@ -416,84 +416,84 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -502,10 +502,10 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } void -chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_16bpp(dst, src, rop); } switch (rop) { @@ -513,84 +513,84 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -599,12 +599,12 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt } void -chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_24bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_24bpp(dst, src, rop); } switch (rop) { @@ -612,84 +612,84 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -1048,7 +1048,6 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va uint64_t i = 0; uint8_t is_true = 0; int orig_x = chips->bitblt_running.x; - int orig_y = chips->bitblt_running.y; uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; @@ -1059,6 +1058,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) continue; @@ -1068,7 +1068,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) continue; - is_true = !!(val & (1 << (8 - (i & 7)))); + is_true = !!(val & (1 << (7 - (i & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { continue; @@ -1077,14 +1077,13 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va pixel = is_true ? source_fg : source_bg; pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - chips->bitblt_running.x = orig_x + (i & 7); + chips->bitblt_running.x = (orig_x + (i & 7) * chips->bitblt_running.x_dir); - if ((chips->bitblt_running.count_x + (i & 7)) <= chips->bitblt_running.actual_destination_width) + if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) chips_69000_process_pixel(chips, pixel); } chips->bitblt_running.mono_bit_cntr += 8; chips->bitblt_running.x = orig_x; - chips->bitblt_running.y = orig_y; chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; chips->bitblt_running.count_x += 8; if (chips->bitblt_running.mono_bit_cntr >= 64) { @@ -1147,11 +1146,15 @@ chips_69000_setup_bitblt(chips_69000_t* chips) /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) - && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) - && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { - chips_69000_bitblt_interrupt(chips); - return; - } + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { + chips_69000_bitblt_interrupt(chips); + return; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " @@ -1166,10 +1169,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; - } - do { do { uint32_t pixel = 0; @@ -1212,8 +1211,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) void chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { - if (!chips->engine_active) + if (!chips->engine_active) { return; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -1928,8 +1928,8 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { - if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) && chips->bitblt_running.bitblt.destination_width > 8) { - pclog("BitBLT mono 0x%08X\n", val); + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + //pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); From 7b05547e5931c5f856875ec3dfba5b59e66322a2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 15:41:10 +0600 Subject: [PATCH 032/690] Use bytes to count image --- src/video/vid_c&t_69000.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index afdc748e6..f47de012d 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -135,6 +135,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint32_t bytes_counter; + uint32_t bytes_in_line_written; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1112,6 +1113,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.mono_is_first_quadword = 1; chips->bitblt_running.mono_bit_cntr = 0; + chips->bitblt_running.bytes_in_line_written = 0; int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { @@ -1153,6 +1155,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + } return; } @@ -1253,11 +1258,13 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); if (chips->bitblt_running.bytes_per_pixel == 3) source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); + + chips->bitblt_running.bytes_in_line_written += chips->bitblt_running.bytes_per_pixel; chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { if (chips->bitblt_running.bitblt.destination_width & 7) chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); else @@ -1266,6 +1273,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; From cd03088873117e86aebb58fe2f483803f8a62b27 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 00:51:17 +0600 Subject: [PATCH 033/690] Source offset trouble fixed WIP hardware cursor --- src/video/vid_c&t_69000.c | 115 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index f47de012d..f3e3132b2 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -134,8 +134,10 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint8_t bytes_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; + uint32_t bytes_in_line_counter; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1114,6 +1116,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.mono_is_first_quadword = 1; chips->bitblt_running.mono_bit_cntr = 0; chips->bitblt_running.bytes_in_line_written = 0; + chips->bitblt_running.bytes_skip = 0; int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { @@ -1156,12 +1159,17 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); + chips->bitblt_running.bytes_in_line_counter = (chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.destination_width + 7) & ~7; + if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) + chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } return; } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " "monochrome right clip = %d, " @@ -1172,6 +1180,12 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.monochrome_source_initial_discard, chips->bitblt_running.bitblt.destination_width, chips->bitblt_running.bitblt.destination_height); + + while (chips->engine_active) { + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + + source_addr += chips->bitblt_running.x_dir; + } } do { @@ -1248,8 +1262,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { return; + } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; @@ -1265,8 +1280,11 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.x += chips->bitblt_running.x_dir; if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { - if (chips->bitblt_running.bitblt.destination_width & 7) - chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); + if (chips->bitblt_running.bytes_skip) { + chips->bitblt_running.bitblt.source_addr = chips->bitblt_running.bytes_skip; + } + else if (chips->bitblt_running.bitblt.destination_width & 7) + chips->bitblt_running.bitblt.source_addr = 8 - ((chips->bitblt_running.bitblt.destination_width) & 7); else chips->bitblt_running.bitblt.source_addr = 0; @@ -1416,6 +1434,34 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0xA0: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); + break; + case 0xA2: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = (val << 8) | ((chips->ext_regs[0xA3] & 0x3F) << 16); + break; + case 0xA3: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = ((chips->ext_regs[0xA2]) << 8) | ((val & 0x3F) << 16); + break; + case 0xA4: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = val | (chips->ext_regs[0xA5] & 7) << 8; + break; + case 0xA5: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = chips->ext_regs[0xA4] | (val & 7) << 8; + break; + case 0xA6: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; + break; + case 0xA7: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; + break; case 0xD2: break; default: @@ -2035,6 +2081,66 @@ chips_69000_vblank_start(svga_t *svga) chips_69000_interrupt(chips); } +static void +chips_69000_hwcursor_draw(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x; + + if ((chips->ext_regs[0xA0] & 7) == 1) { + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + dat[0] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 31))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + else if (dat[0] & (1ULL << 31)) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + return; + } + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (chips->ext_regs[0xA0] & 7) == 1 ? 8 : 16; + + dat[0] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += 16; + switch (chips->ext_regs[0xa0] & 7) { + case 0b101: + for (uint8_t x = 0; x < 64; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[1]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[0]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; + + default: + break; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + static void * chips_69000_init(const device_t *info) { @@ -2062,6 +2168,7 @@ chips_69000_init(const device_t *info) chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; chips->svga.vblank_start = chips_69000_vblank_start; + chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From 614241b8b29cf154660544a2e568cc93f1b50de8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:25:54 +0600 Subject: [PATCH 034/690] Non-CPU-driven monochrome source blits --- src/video/vid_c&t_69000.c | 76 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index f3e3132b2..d73042552 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -137,7 +137,6 @@ typedef struct chips_69000_t { uint8_t bytes_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; - uint32_t bytes_in_line_counter; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1103,6 +1102,8 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va } } +void chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data); + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -1161,7 +1162,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); - chips->bitblt_running.bytes_in_line_counter = (chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.destination_width + 7) & ~7; if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } @@ -1182,9 +1182,49 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); while (chips->engine_active) { - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { + case 0: /* Source-span aligned. */ + { + /* TODO: This is handled purely on a best case basis. */ + uint32_t orig_count_y = chips->bitblt_running.count_y; + uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; + while (orig_count_y == chips->bitblt_running.count_y) { + uint8_t data = chips_69000_readb_linear(orig_source_addr, chips); + orig_source_addr++; + chips_69000_bitblt_write(chips, data & 0xFF); + if ((source_addr + chips->bitblt_running.bitblt.source_span) == orig_source_addr) + break; + } - source_addr += chips->bitblt_running.x_dir; + source_addr = chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.source_span; + chips->bitblt_running.bitblt.source_addr = source_addr; + break; + } + case 4: /* Doubleword-aligned*/ + { + uint32_t data = chips_69000_readl_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + source_addr += 4; + break; + } + case 5: /* Quadword-aligned*/ + { + uint64_t data = (uint64_t)chips_69000_readl_linear(source_addr, chips) | ((uint64_t)chips_69000_readl_linear(source_addr + 4, chips) << 32ull); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 32ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 40ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 48ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 56ull) & 0xFF); + source_addr += 8; + break; + } + } } } @@ -1236,7 +1276,16 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + chips->bitblt_running.bytes_written &= 7; + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 + && chips->bitblt_running.bytes_written == 2) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 && chips->bitblt_running.bytes_written == 4) { chips->bitblt_running.bytes_written = 0; chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); @@ -1246,6 +1295,23 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); if (chips->bitblt_running.actual_destination_width > 24) chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5 && chips->bitblt_running.bytes_written == 8) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + if (chips->bitblt_running.actual_destination_width > 16) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); + if (chips->bitblt_running.actual_destination_width > 24) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + if (chips->bitblt_running.actual_destination_width > 32) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[4]); + if (chips->bitblt_running.actual_destination_width > 40) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[5]); + if (chips->bitblt_running.actual_destination_width > 48) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[6]); + if (chips->bitblt_running.actual_destination_width > 52) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[7]); } else if (chips->bitblt_running.bytes_written == 8) { chips->bitblt_running.bytes_written = 0; uint64_t mono_data = chips->bitblt_running.bytes_port[0]; From df91185e7505812a52d6508f1504475cc16dc26a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:32:46 +0600 Subject: [PATCH 035/690] Minor line fix --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index d73042552..b01be7adb 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1278,7 +1278,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - chips->bitblt_running.bytes_written &= 7; + chips->bitblt_running.bytes_written = 0; } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 && chips->bitblt_running.bytes_written == 2) { chips->bitblt_running.bytes_written = 0; From 1808498370edfeba58f03d6d10f48acb61f8272c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:40:15 +0600 Subject: [PATCH 036/690] Add note about bytes_skip calculation --- src/video/vid_c&t_69000.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b01be7adb..ee83ba6a9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1160,8 +1160,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); - //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); + /* Yes, the NT 4.0 and Linux drivers will send this many amount of bytes to the video adapter on quadword-boundary-crossing image blits. + This weird calculation is intended and deliberate. + */ if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } From 2da7b196ac1609fc2bafb4ccd24b147dd040de87 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 25 Jan 2024 18:06:47 +0500 Subject: [PATCH 037/690] Rename unnamed MSR vars to real names where known --- src/cpu/cpu.c | 69 +++++++++++++++++++++++++++++++-------------------- src/cpu/cpu.h | 29 ++++++++++++---------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index e05ec0d9c..7322ad89d 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2717,8 +2717,8 @@ cpu_RDMSR(void) EDX = tsc >> 32; break; case 0x00000083: - EAX = msr.ecx83 & 0xffffffff; - EDX = msr.ecx83 >> 32; + EAX = msr.amd_hwcr & 0xffffffff; + EDX = msr.amd_hwcr >> 32; break; case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; @@ -2868,15 +2868,15 @@ amd_k_invalid_rdmsr: } break; case 0x79: - EAX = msr.ecx79 & 0xffffffff; - EDX = msr.ecx79 >> 32; + EAX = msr.bios_updt & 0xffffffff; + EDX = msr.bios_updt >> 32; break; case 0x88: case 0x89: case 0x8a: case 0x8b: - EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; - EDX = msr.ecx8x[ECX - 0x88] >> 32; + EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; + EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; case 0xc1: case 0xc2: @@ -2894,19 +2894,28 @@ amd_k_invalid_rdmsr: EDX = msr.mtrr_cap >> 32; break; case 0x116: - EAX = msr.ecx116 & 0xffffffff; - EDX = msr.ecx116 >> 32; + EAX = msr.bbl_cr_addr & 0xffffffff; + EDX = msr.bbl_cr_addr >> 32; break; case 0x118: + EAX = msr.bbl_cr_decc & 0xffffffff; + EDX = msr.bbl_cr_decc >> 32; + break; case 0x119: + EAX = msr.bbl_cr_ctl & 0xffffffff; + EDX = msr.bbl_cr_ctl >> 32; + break; case 0x11a: + EAX = msr.bbl_cr_trig & 0xffffffff; + EDX = msr.bbl_cr_trig >> 32; + break; case 0x11b: - EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; - EDX = msr.ecx11x[ECX - 0x118] >> 32; + EAX = msr.bbl_cr_busy & 0xffffffff; + EDX = msr.bbl_cr_busy >> 32; break; case 0x11e: - EAX = msr.ecx11e & 0xffffffff; - EDX = msr.ecx11e >> 32; + EAX = msr.bbl_cr_ctl3 & 0xffffffff; + EDX = msr.bbl_cr_ctl3 >> 32; break; case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -2941,20 +2950,20 @@ amd_k_invalid_rdmsr: EDX = msr.mcg_ctl >> 32; break; case 0x186: - EAX = msr.ecx186 & 0xffffffff; - EDX = msr.ecx186 >> 32; + EAX = msr.evntsel0 & 0xffffffff; + EDX = msr.evntsel0 >> 32; break; case 0x187: - EAX = msr.ecx187 & 0xffffffff; - EDX = msr.ecx187 >> 32; + EAX = msr.evntsel1 & 0xffffffff; + EDX = msr.evntsel1 >> 32; break; case 0x1d9: EAX = msr.debug_ctl & 0xffffffff; EDX = msr.debug_ctl >> 32; break; case 0x1e0: - EAX = msr.ecx1e0 & 0xffffffff; - EDX = msr.ecx1e0 >> 32; + EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; + EDX = msr.rob_cr_bkuptmpdr6 >> 32; break; case 0x200: case 0x201: @@ -3207,7 +3216,7 @@ cpu_WRMSR(void) tsc = EAX | ((uint64_t) EDX << 32); break; case 0x83: - msr.ecx83 = EAX | ((uint64_t) EDX << 32); + msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); @@ -3319,13 +3328,13 @@ amd_k_invalid_wrmsr: case 0x2a: break; case 0x79: - msr.ecx79 = EAX | ((uint64_t) EDX << 32); + msr.bios_updt = EAX | ((uint64_t) EDX << 32); break; case 0x88: case 0x89: case 0x8a: case 0x8b: - msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; case 0xc1: case 0xc2: @@ -3341,16 +3350,22 @@ amd_k_invalid_wrmsr: msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); break; case 0x116: - msr.ecx116 = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_addr = EAX | ((uint64_t) EDX << 32); break; case 0x118: + msr.bbl_cr_decc = EAX | ((uint64_t) EDX << 32); + break; case 0x119: + msr.bbl_cr_ctl = EAX | ((uint64_t) EDX << 32); + break; case 0x11a: + msr.bbl_cr_trig = EAX | ((uint64_t) EDX << 32); + break; case 0x11b: - msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_busy = EAX | ((uint64_t) EDX << 32); break; case 0x11e: - msr.ecx11e = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3380,16 +3395,16 @@ amd_k_invalid_wrmsr: msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); break; case 0x186: - msr.ecx186 = EAX | ((uint64_t) EDX << 32); + msr.evntsel0 = EAX | ((uint64_t) EDX << 32); break; case 0x187: - msr.ecx187 = EAX | ((uint64_t) EDX << 32); + msr.evntsel1 = EAX | ((uint64_t) EDX << 32); break; case 0x1d9: msr.debug_ctl = EAX | ((uint64_t) EDX << 32); break; case 0x1e0: - msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); + msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); break; case 0x200: case 0x201: diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8e378ebce..24b365693 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -239,15 +239,15 @@ typedef struct { like a real Deschutes does. */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx79; /* 0x00000079 */ + uint64_t bios_updt; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ + uint64_t amd_hwcr; /* 0x00000083 - AMD K5 and K6 MSR's. */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ + uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ @@ -255,9 +255,12 @@ typedef struct { uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx116; /* 0x00000116 */ - uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ - uint64_t ecx11e; /* 0x0000011e */ + uint64_t bbl_cr_addr; /* 0x00000116 */ + uint64_t bbl_cr_decc; /* 0x00000118 */ + uint64_t bbl_cr_ctl; /* 0x00000119 */ + uint64_t bbl_cr_trig; /* 0x0000011a */ + uint64_t bbl_cr_busy; /* 0x0000011b */ + uint64_t bbl_cr_ctl3; /* 0x0000011e */ /* Pentium II Klamath and Pentium II Deschutes MSR's */ uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ @@ -265,13 +268,13 @@ typedef struct { uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ - uint64_t ecx186; /* 0x00000186, 0x00000187 */ - uint64_t ecx187; /* 0x00000186, 0x00000187 */ + uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + uint64_t evntsel0; /* 0x00000186 */ + uint64_t evntsel1; /* 0x00000187 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ - uint64_t ecx1e0; /* 0x000001e0 */ + uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ From 032a161c4acc4214c3457a12b4b793fd665bc95e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 16:58:45 +0500 Subject: [PATCH 038/690] Implement IDT/VIA FCR2 CPUID family/model spoofing --- src/cpu/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 7322ad89d..b76e56077 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1961,7 +1961,7 @@ cpu_CPUID(void) EDX = 0x48727561; } } else if (EAX == 1) { - EAX = 0x540; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -1987,7 +1987,7 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -2464,7 +2464,7 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) From a1540eee92e2bb81208a97d77edf697124cde001 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 17:02:22 +0500 Subject: [PATCH 039/690] Remove the machine check CPUID flag from the P24T --- src/cpu/cpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b76e56077..ce549b798 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2038,7 +2038,9 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + if (cpu_s->cpu_type != CPU_P24T) + EDX |= CPUID_MCE; } else EAX = EBX = ECX = EDX = 0; break; From 37cf0b684538d423dc734dd7c1f39b1c382d5203 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 22:06:05 +0500 Subject: [PATCH 040/690] Separate Pentium and Cx6x86 MSR handling --- src/cpu/cpu.c | 60 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ce549b798..027c6de13 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2782,14 +2782,7 @@ amd_k_invalid_rdmsr: case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - if (cpu_s->cpu_type < CPU_Cx6x86) -#endif - EAX = EDX = 0; + EAX = EDX = 0; switch (ECX) { case 0x00: case 0x01: @@ -2802,6 +2795,24 @@ amd_k_invalid_rdmsr: cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + break; +#endif + case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: @@ -3276,12 +3287,6 @@ amd_k_invalid_wrmsr: case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: -#endif cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { case 0x00: @@ -3291,18 +3296,29 @@ amd_k_invalid_wrmsr: tsc = EAX | ((uint64_t) EDX << 32); break; case 0x8b: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type < CPU_Cx6x86) { -#endif - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - } -#endif + cpu_log("WRMSR: Invalid MSR: 0x8B\n"); + x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ break; } break; +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + } + break; +#endif + case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: From aef257378ef8bab586ef493973100e87adaf3732 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:37:31 +0500 Subject: [PATCH 041/690] Add PGE to AMD K5 and K6-2C/III/2+/III+ --- src/cpu/cpu.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 027c6de13..f00f7227a 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -57,12 +57,15 @@ enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), + CPUID_DE = (1 << 2), CPUID_PSE = (1 << 3), CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_PAE = (1 << 6), CPUID_MCE = (1 << 7), CPUID_CMPXCHG8B = (1 << 8), + CPUID_APIC = (1 << 9), + CPUID_AMDPGE = (1 << 9), CPUID_AMDSEP = (1 << 10), CPUID_SEP = (1 << 11), CPUID_MTRR = (1 << 12), @@ -1605,11 +1608,16 @@ cpu_set(void) cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); if (cpu_s->cpu_type <= CPU_K6) cpu_CR4_mask |= CR4_PCE; - } + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; + } else + cpu_CR4_mask |= CR4_PGE; #else cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; if (cpu_s->cpu_type == CPU_K6) cpu_CR4_mask |= CR4_PCE; + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; #endif #ifdef USE_DYNAREC @@ -2055,7 +2063,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE; } else EAX = EBX = ECX = EDX = 0; break; @@ -2069,14 +2077,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; @@ -2154,6 +2162,8 @@ cpu_CPUID(void) EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000000: EAX = 0x80000005; @@ -2163,6 +2173,8 @@ cpu_CPUID(void) EAX = CPUID + 0x100; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ @@ -2199,7 +2211,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; @@ -2208,7 +2220,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -2250,7 +2262,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; @@ -2259,7 +2271,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ From 963525ff2e81deb6431bdbce154f1c1318b5fd18 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:42:37 +0500 Subject: [PATCH 042/690] Correct the CPUID SEP bit on AMD K6-2 and later They use the standard bit 11, not he AMD-specific bit 10 --- src/cpu/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f00f7227a..bf36b119d 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2172,7 +2172,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW; if (cpu_s->cpu_type == CPU_K6_2C) EDX |= CPUID_PGE; break; @@ -2220,7 +2220,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -2271,7 +2271,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ From 1bb31f39378f3c93d2f3f82b323ad9fb921595ef Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:44:26 +0500 Subject: [PATCH 043/690] Remove the AP61 hack completely It's no longer needed --- src/cpu/cpu.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index bf36b119d..45ea87b98 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2391,20 +2391,14 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - /* if (!strcmp(machine_get_internal_name(), "ap61")) { - EAX = 0x00000001; - EDX = 0x00000000; - } else */ { - EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries - Instruction TLB: 4 MB pages, fully associative, 2 entries - Data TLB: 4 KB pages, 4-way set associative, 64 entries */ - EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size - 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size - Data TLB: 4 MB pages, 4-way set associative, 8 entries - 1st-level instruction cache:8 KB, 4-way set associative, 32-byte line size */ - } - + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ EBX = ECX = 0; + EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size + 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache: 8 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; From b86015635092be623abc105353a489e87357502f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 31 Jan 2024 13:45:04 +0500 Subject: [PATCH 044/690] Remove an accidentally committed duplicate file --- src/cpu/x886seg_2386.c | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/cpu/x886seg_2386.c diff --git a/src/cpu/x886seg_2386.c b/src/cpu/x886seg_2386.c deleted file mode 100644 index 335c757e4..000000000 --- a/src/cpu/x886seg_2386.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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" From 1e4455d98cecf86b140ebdd53c8104a367b72340 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 1 Feb 2024 18:34:58 +0500 Subject: [PATCH 045/690] Add comments with MSR and CPUID flag names Reorganize the MSR struct --- src/cpu/386_common.c | 6 +- src/cpu/cpu.c | 377 ++++++++++++++++++++++++++----------------- src/cpu/cpu.h | 120 ++++++-------- 3 files changed, 276 insertions(+), 227 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 4b4037207..f9ca3408d 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -128,9 +128,9 @@ uint32_t addr64a_2[8]; static pc_timer_t *cpu_fast_off_timer = NULL; static double cpu_fast_off_period = 0.0; -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +#define AMD_SYSCALL_EIP (msr.amd_star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.amd_star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.amd_star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 45ea87b98..5a68ecf38 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -55,30 +55,31 @@ #define CCR3_NMI_EN (1 << 1) enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_DE = (1 << 2), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_PAE = (1 << 6), - CPUID_MCE = (1 << 7), - CPUID_CMPXCHG8B = (1 << 8), - CPUID_APIC = (1 << 9), - CPUID_AMDPGE = (1 << 9), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_MTRR = (1 << 12), - CPUID_PGE = (1 << 13), - CPUID_MCA = (1 << 14), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) + CPUID_FPU = (1 << 0), /* On-chip Floating Point Unit */ + CPUID_VME = (1 << 1), /* Virtual 8086 mode extensions */ + CPUID_DE = (1 << 2), /* Debugging extensions */ + CPUID_PSE = (1 << 3), /* Page Size Extension */ + CPUID_TSC = (1 << 4), /* Time Stamp Counter */ + CPUID_MSR = (1 << 5), /* Model-specific registers */ + CPUID_PAE = (1 << 6), /* Physical Address Extension */ + CPUID_MCE = (1 << 7), /* Machine Check Exception */ + CPUID_CMPXCHG8B = (1 << 8), /* CMPXCHG8B instruction */ + CPUID_APIC = (1 << 9), /* On-chip APIC */ + CPUID_AMDPGE = (1 << 9), /* Global Page Enable (AMD K5 Model 0 only) */ + CPUID_AMDSEP = (1 << 10), /* SYSCALL and SYSRET instructions (AMD K6 only) */ + CPUID_SEP = (1 << 11), /* SYSENTER and SYSEXIT instructions (SYSCALL and SYSRET if EAX=80000001h) */ + CPUID_MTRR = (1 << 12), /* Memory type range registers */ + CPUID_PGE = (1 << 13), /* Page Global Enable */ + CPUID_MCA = (1 << 14), /* Machine Check Architecture */ + CPUID_CMOV = (1 << 15), /* Conditional move instructions */ + CPUID_PAT = (1 << 16), /* Page Attribute Table */ + CPUID_MMX = (1 << 23), /* MMX technology */ + CPUID_FXSR = (1 << 24) /* FXSAVE and FXRSTOR instructions */ }; -/*Addition flags returned by CPUID function 0x80000001*/ -#define CPUID_3DNOW (1UL << 31UL) -#define CPUID_3DNOWE (1UL << 30UL) +/* Additional flags returned by CPUID function 0x80000001 */ +#define CPUID_3DNOWE (1UL << 30UL) /* Extended 3DNow! instructions */ +#define CPUID_3DNOW (1UL << 31UL) /* 3DNow! instructions */ /* Make sure this is as low as possible. */ cpu_state_t cpu_state; @@ -2560,14 +2561,17 @@ cpu_RDMSR(void) case CPU_IBM486BL: EAX = EDX = 0; switch (ECX) { + /* Processor Operation Register */ case 0x1000: EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); break; + /* Cache Region Control Register */ case 0x1001: EAX = msr.ibm_crcr & 0xffffffffff; break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) EAX = msr.ibm_por2 & 0x3f000000; @@ -2579,26 +2583,33 @@ cpu_RDMSR(void) case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { + /* TR1 - Test Register 1 */ case 0x02: EAX = msr.tr1; break; + /* TR12 - Test Register 12 */ case 0x0e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ case 0x11: EAX = msr.cesr; break; + /* Feature Control Register */ case 0x107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; + /* Feature Control Register 4 */ case 0x10a: EAX = cpu_multi & 3; break; @@ -2608,13 +2619,17 @@ cpu_RDMSR(void) case CPU_CYRIX3S: EAX = EDX = 0; switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2641,29 +2656,18 @@ cpu_RDMSR(void) if (cpu_busspeed >= 84000000) EAX |= (1 << 19); break; + /* Feature Control Register */ case 0x1107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x1108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -2672,29 +2676,27 @@ cpu_RDMSR(void) EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; @@ -2714,35 +2716,44 @@ cpu_RDMSR(void) case CPU_K6_3P: EAX = EDX = 0; switch (ECX) { + /* Machine Check Address Register */ case 0x00000000: + /* Machine Check Type Register */ case 0x00000001: break; + /* Test Register 12 */ case 0x0000000e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x00000010: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Hardware Configuration Register */ case 0x00000083: EAX = msr.amd_hwcr & 0xffffffff; EDX = msr.amd_hwcr >> 32; break; + /* Extended Feature Enable Register */ case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; EDX = msr.amd_efer >> 32; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_rdmsr; - EAX = msr.star & 0xffffffff; - EDX = msr.star >> 32; + EAX = msr.amd_star & 0xffffffff; + EDX = msr.amd_star >> 32; break; + /* Write-Handling Control Register */ case 0xc0000082: EAX = msr.amd_whcr & 0xffffffff; EDX = msr.amd_whcr >> 32; break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2750,6 +2761,7 @@ cpu_RDMSR(void) EAX = msr.amd_uwccr & 0xffffffff; EDX = msr.amd_uwccr >> 32; break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_rdmsr; @@ -2757,6 +2769,7 @@ cpu_RDMSR(void) EAX = msr.amd_epmr & 0xffffffff; EDX = msr.amd_epmr >> 32; break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2764,6 +2777,7 @@ cpu_RDMSR(void) EAX = msr.amd_psor & 0xffffffff; EDX = msr.amd_psor >> 32; break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2771,6 +2785,7 @@ cpu_RDMSR(void) EAX = msr.amd_pfir & 0xffffffff; EDX = msr.amd_pfir >> 32; break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_rdmsr; @@ -2790,9 +2805,12 @@ amd_k_invalid_rdmsr: case CPU_PENTIUMMMX: EAX = EDX = 0; switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2807,9 +2825,12 @@ amd_k_invalid_rdmsr: case CPU_CxGX1: case CPU_Cx6x86MX: switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2826,13 +2847,17 @@ amd_k_invalid_rdmsr: /* Per RichardG's probing of a real Deschutes using my RDMSR tool, we have discovered that the top 18 bits are filtered out. */ switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* IA32_PLATFORM_ID - Platform ID */ case 0x17: if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; @@ -2842,16 +2867,18 @@ amd_k_invalid_rdmsr: else if (cpu_f->package == CPU_PKG_SOCKET370) EDX |= 0x100000; break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1B: EAX = msr.apic_base & 0xffffffff; EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; - /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ case 0x20: EAX = msr.ecx20 & 0xffffffff; EDX = msr.ecx20 >> 32; break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2886,56 +2913,58 @@ amd_k_invalid_rdmsr: EAX |= (1 << 19); } break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: EAX = msr.bios_updt & 0xffffffff; EDX = msr.bios_updt >> 32; break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: + /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ + case 0xc1 ... 0xc8: EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; break; + /* MTRRcap */ case 0xfe: EAX = msr.mtrr_cap & 0xffffffff; EDX = msr.mtrr_cap >> 32; break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: EAX = msr.bbl_cr_addr & 0xffffffff; EDX = msr.bbl_cr_addr >> 32; break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: EAX = msr.bbl_cr_decc & 0xffffffff; EDX = msr.bbl_cr_decc >> 32; break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: EAX = msr.bbl_cr_ctl & 0xffffffff; EDX = msr.bbl_cr_ctl >> 32; break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: EAX = msr.bbl_cr_trig & 0xffffffff; EDX = msr.bbl_cr_trig >> 32; break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: EAX = msr.bbl_cr_busy & 0xffffffff; EDX = msr.bbl_cr_busy >> 32; break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: EAX = msr.bbl_cr_ctl3 & 0xffffffff; EDX = msr.bbl_cr_ctl3 >> 32; break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2944,6 +2973,7 @@ amd_k_invalid_rdmsr: EAX |= msr.sysenter_cs; EDX = 0x00000000; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2951,6 +2981,7 @@ amd_k_invalid_rdmsr: EAX = msr.sysenter_esp; EDX = 0x00000000; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2958,48 +2989,42 @@ amd_k_invalid_rdmsr: EAX = msr.sysenter_eip; EDX = 0x00000000; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: EAX = 0x00000105; EDX = 0x00000000; break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: EAX = msr.mcg_ctl & 0xffffffff; EDX = msr.mcg_ctl >> 32; break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: EAX = msr.evntsel0 & 0xffffffff; EDX = msr.evntsel0 >> 32; break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: EAX = msr.evntsel1 & 0xffffffff; EDX = msr.evntsel1 >> 32; break; + /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: EAX = msr.debug_ctl & 0xffffffff; EDX = msr.debug_ctl >> 32; break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; EDX = msr.rob_cr_bkuptmpdr6 >> 32; break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -3008,56 +3033,71 @@ amd_k_invalid_rdmsr: EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* Page Attribute Table */ case 0x277: EAX = msr.pat & 0xffffffff; EDX = msr.pat >> 32; break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: break; + /* Unknown */ case 0x570: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; @@ -3086,13 +3126,16 @@ cpu_WRMSR(void) case CPU_IBM486BL: case CPU_IBM486SLC: switch (ECX) { + /* Processor Operation Register */ case 0x1000: msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); cpu_cache_int_enabled = (EAX & (1 << 7)); break; + /* Cache Region Control Register */ case 0x1001: msr.ibm_crcr = EAX & 0xffffffffff; break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) msr.ibm_por2 = EAX & 0x3f000000; @@ -3103,18 +3146,23 @@ cpu_WRMSR(void) case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) { + /* TR1 - Test Register 1 */ case 0x02: msr.tr1 = EAX & 2; break; + /* TR12 - Test Register 12 */ case 0x0e: msr.tr12 = EAX & 0x228; break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Performance Monitor - Control and Event Select */ case 0x11: msr.cesr = EAX & 0xff00ff; break; + /* Feature Control Register */ case 0x107: msr.fcr = EAX; if (EAX & (1 << 9)) @@ -3134,9 +3182,11 @@ cpu_WRMSR(void) else CPUID = cpu_s->cpuid_model; break; + /* Feature Control Register 2 */ case 0x108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; @@ -3145,12 +3195,16 @@ cpu_WRMSR(void) case CPU_CYRIX3S: switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register */ case 0x1107: msr.fcr = EAX; if (EAX & (1 << 1)) @@ -3162,52 +3216,39 @@ cpu_WRMSR(void) else cpu_CR4_mask &= ~CR4_PGE; break; + /* Feature Control Register 2 */ case 0x1108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x1109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26A: - case 0x26B: - case 0x26C: - case 0x26D: - case 0x26E: - case 0x26F: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; @@ -3225,18 +3266,24 @@ cpu_WRMSR(void) case CPU_K6_2P: case CPU_K6_3P: switch (ECX) { + /* Machine Check Address Register */ case 0x00: + /* Machine Check Type Register */ case 0x01: break; + /* Test Register 12 */ case 0x0e: msr.tr12 = EAX & 0x228; break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Hardware Configuration Register */ case 0x83: msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; + /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); if (temp & ~1ULL) @@ -3244,39 +3291,46 @@ cpu_WRMSR(void) else msr.amd_efer = temp; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_wrmsr; - msr.star = EAX | ((uint64_t) EDX << 32); + msr.amd_star = EAX | ((uint64_t) EDX << 32); break; + /* Write-Handling Control Register */ case 0xc0000082: msr.amd_whcr = EAX | ((uint64_t) EDX << 32); break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_uwccr = EAX | ((uint64_t) EDX << 32); break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_wrmsr; msr.amd_epmr = EAX | ((uint64_t) EDX << 32); break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_psor = EAX | ((uint64_t) EDX << 32); break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_pfir = EAX | ((uint64_t) EDX << 32); break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_wrmsr; @@ -3295,12 +3349,16 @@ amd_k_invalid_wrmsr: case CPU_PENTIUMMMX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* BIOS Update Signature */ case 0x8b: cpu_log("WRMSR: Invalid MSR: 0x8B\n"); x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ @@ -3315,9 +3373,12 @@ amd_k_invalid_wrmsr: case CPU_Cx6x86MX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; @@ -3331,171 +3392,189 @@ amd_k_invalid_wrmsr: /* Per RichardG's probing of a real Deschutes using my RDMSR tool, we have discovered that the top 18 bits are filtered out. */ switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); #if 0 msr.apic_base = EAX | ((uint64_t) EDX << 32); #endif break; - /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ case 0x20: msr.ecx20 = EAX | ((uint64_t) EDX << 32); break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: msr.bios_updt = EAX | ((uint64_t) EDX << 32); break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: + /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ + case 0xc1 ... 0xc8: msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRcap */ case 0xfe: msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: msr.bbl_cr_addr = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: msr.bbl_cr_decc = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: msr.bbl_cr_ctl = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: msr.bbl_cr_trig = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: msr.bbl_cr_busy = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_cs = EAX & 0xFFFF; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_esp = EAX; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_eip = EAX; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: if (EAX || EDX) x86gpf(NULL, 0); break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: msr.evntsel0 = EAX | ((uint64_t) EDX << 32); break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: msr.evntsel1 = EAX | ((uint64_t) EDX << 32); break; + /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: msr.debug_ctl = EAX | ((uint64_t) EDX << 32); break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* Page Attribute Table */ case 0x277: msr.pat = EAX | ((uint64_t) EDX << 32); break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t) EDX << 32); break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Unknown */ case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 24b365693..429741839 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -226,35 +226,41 @@ typedef union { } MMX_REG; typedef struct { - /* IDT WinChip and WinChip 2 MSR's */ - uint32_t tr1; /* 0x00000002, 0x0000000e */ - uint32_t tr12; /* 0x00000002, 0x0000000e */ - uint32_t cesr; /* 0x00000011 */ + /* IBM 386SLC/486SLC/486BL MSRs */ + uint64_t ibm_por; /* 0x00001000 - 386SLC and later */ + uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */ + uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ - - /* Weird long MSR's used by the Hyper-V BIOS. */ - uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits - like a real Deschutes does. */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t bios_updt; /* 0x00000079 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_hwcr; /* 0x00000083 - AMD K5 and K6 MSR's. */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ - - /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ + /* IDT WinChip C6/2/VIA Cyrix III MSRs */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + /* AMD K5/K6 MSRs */ + uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ + + uint64_t amd_efer; /* 0xc0000080 - all K5 and K6 */ + uint64_t amd_star; /* 0xc0000081 - K6-2 and later */ + uint64_t amd_whcr; /* 0xc0000082 - all K5 and K6 */ + uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */ + uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */ + uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */ + uint64_t amd_pfir; /* 0xc0000088 - K6-2C and later */ + uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */ + + /* Pentium/Pentium MMX MSRs */ + uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ + uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 */ + uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 */ + + /* Pentium Pro/II MSRs */ + uint64_t apic_base; /* 0x0000001b */ + uint64_t bios_updt; /* 0x00000079 */ + + uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ + uint64_t bbl_cr_addr; /* 0x00000116 */ uint64_t bbl_cr_decc; /* 0x00000118 */ uint64_t bbl_cr_ctl; /* 0x00000119 */ @@ -262,68 +268,32 @@ typedef struct { uint64_t bbl_cr_busy; /* 0x0000011b */ uint64_t bbl_cr_ctl3; /* 0x0000011e */ - /* Pentium II Klamath and Pentium II Deschutes MSR's */ - uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + uint16_t sysenter_cs; /* 0x00000174 - Pentium II and later */ + uint32_t sysenter_esp; /* 0x00000175 - Pentium II and later */ + uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ - uint64_t evntsel0; /* 0x00000186 */ - uint64_t evntsel1; /* 0x00000187 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t mcg_ctl; /* 0x0000017b */ + uint64_t evntsel0; /* 0x00000186 */ + uint64_t evntsel1; /* 0x00000187 */ + uint64_t debug_ctl; /* 0x000001d9 */ uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + /* MTTR-related MSRs also present on the VIA Cyrix III */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */ uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ uint64_t mtrr_fix64k_8000; /* 0x00000250 */ uint64_t mtrr_fix16k_8000; /* 0x00000258 */ uint64_t mtrr_fix16k_a000; /* 0x00000259 */ uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + uint64_t mtrr_deftype; /* 0x000002ff */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t pat; /* 0x00000277 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_deftype; /* 0x000002ff */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ + uint64_t pat; /* 0x00000277 - Pentium II Deschutes and later */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 */ uint64_t ecx570; /* 0x00000570 */ - /* IBM 386SLC, 486SLC, and 486BL MSR's */ - uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ - uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ - - /* IBM 486SLC and 486BL MSR's */ - uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_efer; /* 0xc0000080 */ - - /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t star; /* 0xc0000081 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_whcr; /* 0xc0000082 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_uwccr; /* 0xc0000085 */ - - /* AMD K6-2P and K6-3P MSR's */ - uint64_t amd_epmr; /* 0xc0000086 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_psor; /* 0xc0000087, 0xc0000088 */ - uint64_t amd_pfir; /* 0xc0000087, 0xc0000088 */ - - /* K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_l2aar; /* 0xc0000089 */ + /* Other/Unclassified MSRs */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ } msr_t; typedef struct { From 2a3d13d306ff911ca3f5e46dea47be171c93d935 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 1 Feb 2024 21:08:28 +0500 Subject: [PATCH 046/690] Various consistency changes --- src/cpu/cpu.c | 222 +++++++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 101 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 5a68ecf38..f57c874a8 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1915,7 +1915,7 @@ cpu_CPUID(void) case CPU_i486SX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -1929,7 +1929,7 @@ cpu_CPUID(void) case CPU_i486DX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -1945,21 +1945,21 @@ cpu_CPUID(void) case CPU_ENH_Am486DX: if (!EAX) { - EAX = 1; - EBX = 0x68747541; + EAX = 0x00000001; + EBX = 0x68747541;/* AuthenticAMD */ ECX = 0x444D4163; EDX = 0x69746E65; } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ + EDX = CPUID_FPU; } else EAX = EBX = ECX = EDX = 0; break; case CPU_WINCHIP: if (!EAX) { - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -1984,7 +1984,7 @@ cpu_CPUID(void) case CPU_WINCHIP2: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -2041,7 +2041,7 @@ cpu_CPUID(void) case CPU_PENTIUM: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2058,7 +2058,7 @@ cpu_CPUID(void) case CPU_K5: if (!EAX) { EAX = 0x00000001; - EBX = 0x68747541; + EBX = 0x68747541; /* AuthenticAMD */ EDX = 0x69746E65; ECX = 0x444D4163; } else if (EAX == 1) { @@ -2070,91 +2070,111 @@ cpu_CPUID(void) break; case CPU_5K86: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x7428354B; - ECX = 0x5020296D; - EDX = 0x65636F72; - } else if (EAX == 0x80000003) { - EAX = 0x726F7373; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000004) - EAX = EBX = ECX = EDX = 0; - else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x04800000; - ECX = 0x08040120; - EDX = 0x10040120; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K5(tm) Proce */ + EBX = 0x7428354B; + ECX = 0x5020296D; + EDX = 0x65636F72; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x726F7373; /* ssor */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x04800000; /* TLBs */ + ECX = 0x08040120; /* L1 data cache */ + EDX = 0x10040120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; #endif case CPU_K6: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x6D74364B; - ECX = 0x202F7720; - EDX = 0x746C756D; - } else if (EAX == 0x80000003) { - EAX = 0x64656D69; - EBX = 0x65206169; - ECX = 0x6E657478; - EDX = 0x6E6F6973; - } else if (EAX == 0x80000004) { - EAX = 0x73; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x02800140; - ECX = 0x20020220; - EDX = 0x20020220; - } else if (EAX == 0x8FFFFFFF) { - EAX = 0x4778654E; - EBX = 0x72656E65; - ECX = 0x6F697461; - EDX = 0x444D416E; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K6tm w/ mult */ + EBX = 0x6D74364B; + ECX = 0x202F7720; + EDX = 0x746C756D; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x64656D69; /* imedia extension */ + EBX = 0x65206169; + ECX = 0x6E657478; + EDX = 0x6E6F6973; + break; + case 0x80000004: /* Processor name string */ + EAX = 0x73; /* s */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x8FFFFFFF: /* Easter egg */ + EAX = 0x4778654E; /* NexGenerationAMD */ + EBX = 0x72656E65; + ECX = 0x6F697461; + EDX = 0x444D416E; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; case CPU_K6_2: case CPU_K6_2C: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2189,11 +2209,11 @@ cpu_CPUID(void) ECX = 0x00000000; EDX = 0x00000000; break; - case 0x80000005: /*Cache information*/ + case 0x80000005: /* Cache information */ EAX = 0; - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; default: EAX = EBX = ECX = EDX = 0; @@ -2204,7 +2224,7 @@ cpu_CPUID(void) case CPU_K6_3: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2238,8 +2258,8 @@ cpu_CPUID(void) case 0x80000005: /* Cache information */ EAX = 0; EBX = 0x02800140; /* TLBs */ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; case 0x80000006: /* L2 Cache information */ EAX = EBX = EDX = 0; @@ -2255,7 +2275,7 @@ cpu_CPUID(void) case CPU_K6_3P: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2312,7 +2332,7 @@ cpu_CPUID(void) case CPU_PENTIUMMMX: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2327,7 +2347,7 @@ cpu_CPUID(void) case CPU_Cx6x86: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2341,7 +2361,7 @@ cpu_CPUID(void) case CPU_Cx6x86L: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2355,7 +2375,7 @@ cpu_CPUID(void) case CPU_CxGX1: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2369,7 +2389,7 @@ cpu_CPUID(void) case CPU_Cx6x86MX: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2384,7 +2404,7 @@ cpu_CPUID(void) case CPU_PENTIUMPRO: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2407,7 +2427,7 @@ cpu_CPUID(void) case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2430,7 +2450,7 @@ cpu_CPUID(void) case CPU_PENTIUM2D: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2461,7 +2481,7 @@ cpu_CPUID(void) case CPU_CYRIX3S: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; From 8520e6be85dcf2bedf8000105f1b5f531f3eb7ee Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 3 Feb 2024 21:35:32 +0500 Subject: [PATCH 047/690] Show actual clocks for CPUs w/ Performance Ratings --- src/cpu/cpu_table.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 7a478f6f0..521732eee 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1398,9 +1398,9 @@ const cpu_family_t cpu_families[] = { .name = "Am5x86", .internal_name = "am5x86", .cpus = (const CPU[]) { - {"P75", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"P75+", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ - {"P90", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"133 (P75)", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"150 (P75+)", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"160 (P90)", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ {"", 0} } }, { @@ -1774,12 +1774,12 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86", .internal_name = "cx6x86", .cpus = (const CPU[]) { - {"P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"80 (PR90+)", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"100 (PR120+)", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"110 (PR133+)", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -1788,10 +1788,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86L", .internal_name = "cx6x86l", .cpus = (const CPU[]) { - {"PR133+", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"110 (PR133+)", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -1800,10 +1800,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86MX", .internal_name = "cx6x86mx", .cpus = (const CPU[]) { - {"PR166", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"PR233", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, - {"PR266", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"133 (PR166)", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"166 (PR200)", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"187.5 (PR233)", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"208.3 (PR266)", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, {"", 0} } }, { @@ -1812,11 +1812,11 @@ const cpu_family_t cpu_families[] = { .name = "MII", .internal_name = "mii", .cpus = (const CPU[]) { - {"PR300", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, - {"PR333", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, - {"PR366", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, - {"PR400", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, - {"PR433", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"233 (PR300)", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"250/83 (PR333)", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"250/100 (PR366)", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"285 (PR400)", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"300 (PR433)", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, {"", 0} } }, From 8143ccdc9b0d9bfa8dc61669cc60daca22b9fa70 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 5 Feb 2024 13:18:00 +0500 Subject: [PATCH 048/690] K5 reorganization Rename SSA/5 to Model 0 and 5k86 to Model 1/2/3 and swap their ordering Remove the Model 0 CPUs from the Model 1 (5k86) table --- src/cpu/cpu_table.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 521732eee..502b2c86e 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1615,23 +1615,7 @@ const cpu_family_t cpu_families[] = { { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", - .name = "K5 (5k86)", - .internal_name = "k5_5k86", - .cpus = (const CPU[]) { - {"75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"", 0} - } - }, { - .package = CPU_PKG_SOCKET5_7, - .manufacturer = "AMD", - .name = "K5 (SSA/5)", + .name = "K5 (Model 0)", .internal_name = "k5_ssa5", .cpus = (const CPU[]) { {"75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -1639,6 +1623,19 @@ const cpu_family_t cpu_families[] = { {"100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, {"", 0} } + }, { + .package = CPU_PKG_SOCKET5_7, + .manufacturer = "AMD", + .name = "K5 (Model 1/2/3)", + .internal_name = "k5_5k86", + .cpus = (const CPU[]) { + {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"116.7 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", 0} + } }, #endif { From 1b9bf568f2a9024cc1b5d4fceba837223ca35084 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 3 Feb 2024 21:39:40 +0500 Subject: [PATCH 049/690] Implement missing Pentium MSRs Includes obscure behavior, like undocumented "high" MSRs --- src/cpu/cpu.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++--- src/cpu/cpu.h | 23 +++- 2 files changed, 304 insertions(+), 18 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f57c874a8..fbdb85aa2 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -248,8 +248,7 @@ uint32_t cache_index = 0; uint8_t _cache[2048]; uint64_t cpu_CR4_mask; -uint64_t tsc = 0; -uint64_t pmc[2] = { 0, 0 }; +uint64_t tsc = 0; double cpu_dmulti; double cpu_busspeed; @@ -2824,17 +2823,159 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM: case CPU_PENTIUMMMX: EAX = EDX = 0; - switch (ECX) { + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { /* Machine Check Exception Address */ - case 0x00: + case 0x00000000: + case 0x80000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; /* Machine Check Exception Type */ - case 0x01: + case 0x00000001: + case 0x80000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; + msr.mctr &= ~0x1; /* clear the machine check pending bit */ + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + EAX = msr.tr1; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_rdmsr; + EAX = msr.tr2; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + EAX = msr.tr3; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + EAX = msr.tr4; + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + EAX = msr.tr5; + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + EAX = msr.tr6; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + EAX = msr.tr7; + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + EAX = msr.tr9; + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + EAX = msr.tr10; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + EAX = msr.tr11; + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + EAX = msr.tr12; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: + case 0x80000010: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_rdmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + EAX = ((cr0 & (1 << 31)) ? 0x00000008 : 0x00000004); + break; + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + EAX = 0; + break; + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + EAX = 0; + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt; + break; + /* Unknown */ + case 0x8000001c: + EAX = 0x00000004; + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + EAX = msr.ecx8000001e; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + EAX = msr.ecx8000001f; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + EAX = (ECX & 0x1f) * 2; + break; + default: +pentium_invalid_rdmsr: + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; @@ -3368,20 +3509,150 @@ amd_k_invalid_wrmsr: case CPU_PENTIUM: case CPU_PENTIUMMMX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); - switch (ECX) { + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { /* Machine Check Exception Address */ - case 0x00: + case 0x00000000: + case 0x80000000: /* Machine Check Exception Type */ - case 0x01: + case 0x00000001: + case 0x80000001: + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + msr.tr1 = EAX & 0x3fff; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_wrmsr; + msr.tr2 = EAX & 0xf; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + msr.tr3 = EAX; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + msr.tr4 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffff1f : 0xffffff07); + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + msr.tr5 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0x87fff : 0x7fff); + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + msr.tr6 = EAX & 0xffffff07; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + msr.tr7 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xfffffc7f : 0xffffff9c); + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + msr.tr9 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffffff : 0xffffffc3); + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + msr.tr10 = EAX; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + msr.tr11 = EAX & ((cpu_s->cpu_type >= CPU_PENTIUMMMX) ? 0x3001fcf : 0xfcf); + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + temp = EAX & 0x38034f; + else if ((CPUID & 0xfff) >= 0x52b) + temp = EAX & 0x20435f; + else if ((CPUID & 0xfff) >= 0x520) + temp = EAX & 0x20035f; + else + temp = EAX & 0x20030f; + msr.tr12 = temp; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: + case 0x80000010: tsc = EAX | ((uint64_t) EDX << 32); break; - /* BIOS Update Signature */ - case 0x8b: - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + msr.cesr = EAX & 0x3ff03ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_wrmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt & 0x7ff; + break; + /* Unknown */ + case 0x8000001c: + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl & 0x7; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + msr.ecx8000001e = EAX; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + msr.ecx8000001f = EAX; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + break; + default: +pentium_invalid_wrmsr: + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); break; } break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 429741839..42246d6ed 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -249,9 +249,25 @@ typedef struct { uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */ /* Pentium/Pentium MMX MSRs */ - uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ - uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 */ - uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 */ + uint64_t mcar; /* 0x00000000 - also on K5 and (R/W) K6 */ + uint64_t mctr; /* 0x00000001 - also on K5 and (R/W) K6 */ + uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ + uint32_t tr2; /* 0x00000004 - reserved on PMMX */ + uint32_t tr3; /* 0x00000005 */ + uint32_t tr4; /* 0x00000006 */ + uint32_t tr5; /* 0x00000007 */ + uint32_t tr6; /* 0x00000008 */ + uint32_t tr7; /* 0x00000009 */ + uint32_t tr9; /* 0x0000000b */ + uint32_t tr10; /* 0x0000000c */ + uint32_t tr11; /* 0x0000000d */ + uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 and K6 */ + uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 and Cx6x86MX */ + uint64_t pmc[2]; /* 0x00000012, 0x00000013 - also on WinChip C6/2 and Cx6x86MX */ + uint32_t fp_last_xcpt; /* 0x8000001b - undocumented */ + uint32_t probe_ctl; /* 0x8000001d - undocumented */ + uint32_t ecx8000001e; /* 0x8000001e - undocumented */ + uint32_t ecx8000001f; /* 0x8000001f - undocumented */ /* Pentium Pro/II MSRs */ uint64_t apic_base; /* 0x0000001b */ @@ -559,7 +575,6 @@ extern double bus_timing; extern double isa_timing; extern double pci_timing; extern double agp_timing; -extern uint64_t pmc[2]; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; extern uint32_t esp_msr; From 65f40ca71d5ea23380ef43aff8de7d76cc97e797 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 17:19:12 +0500 Subject: [PATCH 050/690] Implement missing WinChip C6/2 and Cyrix III MSRs --- src/cpu/cpu.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++---- src/cpu/cpu.h | 8 ++-- 2 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index fbdb85aa2..be322635f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2538,9 +2538,12 @@ cpu_ven_reset(void) switch (cpu_s->cpu_type) { case CPU_WINCHIP: case CPU_WINCHIP2: - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - if (cpu_s->cpu_type == CPU_WINCHIP2) - msr.fcr |= (1 << 18) | (1 << 20); + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msr.mcr_ctrl = 0xf8000000; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + msr.fcr |= (1 << 18) | (1 << 20); + msr.mcr_ctrl |= (1 << 17); + } break; case CPU_K6_2P: @@ -2602,11 +2605,11 @@ cpu_RDMSR(void) case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { - /* TR1 - Test Register 1 */ + /* Pentium Processor Parity Reversal Register */ case 0x02: EAX = msr.tr1; break; - /* TR12 - Test Register 12 */ + /* Pentium Processor New Feature Control */ case 0x0e: EAX = msr.tr12; break; @@ -2619,6 +2622,16 @@ cpu_RDMSR(void) case 0x11: EAX = msr.cesr; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; /* Feature Control Register */ case 0x107: EAX = msr.fcr; @@ -2632,6 +2645,17 @@ cpu_RDMSR(void) case 0x10a: EAX = cpu_multi & 3; break; + /* Memory Configuration Register Control */ + case 0x120: + EAX = msr.mcr_ctrl; + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; @@ -2675,6 +2699,29 @@ cpu_RDMSR(void) if (cpu_busspeed >= 84000000) EAX |= (1 << 19); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + EAX = tsc & 0xffffffff; + EDX = (tsc >> 32) & 0xff; + break; + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + EAX = msr.ia32_pmc[1] & 0xffffffff; + EDX = msr.ia32_pmc[1] >> 32; + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + EAX = 0x800000; /* L2 cache disabled */ + break; + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + EAX = 0x470079; + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + EAX = msr.evntsel1 & 0xffffffff; + EDX = msr.evntsel1 >> 32; + break; /* Feature Control Register */ case 0x1107: EAX = msr.fcr; @@ -3307,13 +3354,13 @@ cpu_WRMSR(void) case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) { - /* TR1 - Test Register 1 */ + /* Pentium Processor Parity Reversal Register */ case 0x02: msr.tr1 = EAX & 2; break; - /* TR12 - Test Register 12 */ + /* Pentium Processor New Feature Control */ case 0x0e: - msr.tr12 = EAX & 0x228; + msr.tr12 = EAX & 0x248; break; /* Time Stamp Counter */ case 0x10: @@ -3323,6 +3370,14 @@ cpu_WRMSR(void) case 0x11: msr.cesr = EAX & 0xff00ff; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; /* Feature Control Register */ case 0x107: msr.fcr = EAX; @@ -3351,6 +3406,28 @@ cpu_WRMSR(void) case 0x109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; + /* Memory Configuration Register 0..7 */ + case 0x110 ... 0x117: + temp = ECX - 0x110; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + if (EAX & 0x1f) + msr.mcr_ctrl |= (1 << (temp + 9)); + else + msr.mcr_ctrl &= ~(1 << (temp + 9)); + } + msr.mcr[temp] = EAX | ((uint64_t) EDX << 32); + break; + /* Memory Configuration Register Control */ + case 0x120: + msr.mcr_ctrl = EAX & ((cpu_s->cpu_type == CPU_WINCHIP2) ? 0x1df : 0x1f); + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; @@ -3365,6 +3442,22 @@ cpu_WRMSR(void) case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + break; + /* PERFCTR0 - Performance Counter Register 1 */ + case 0xc2: + msr.ia32_pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + break; /* Feature Control Register */ case 0x1107: msr.fcr = EAX; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 42246d6ed..8ff02d40d 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -232,9 +232,11 @@ typedef struct { uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ /* IDT WinChip C6/2/VIA Cyrix III MSRs */ - uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ - uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ - uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t mcr[8]; /* 0x00000110 - 0x00000117 (IDT) */ + uint32_t mcr_ctrl; /* 0x00000120 (IDT) */ /* AMD K5/K6 MSRs */ uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ From e54b57641c109b616410cbad2c6b2248ba6b6aef Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 21:39:07 +0500 Subject: [PATCH 051/690] Implement missing IBM, AMD and Cyrix MSRs --- src/cpu/cpu.c | 139 +++++++++++++++++++++++++++++++++++++++++++------- src/cpu/cpu.h | 10 ++-- 2 files changed, 127 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index be322635f..9b01b8ab7 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2590,7 +2590,8 @@ cpu_RDMSR(void) /* Cache Region Control Register */ case 0x1001: - EAX = msr.ibm_crcr & 0xffffffffff; + EAX = msr.ibm_crcr & 0xffffffff; + EDX = (msr.ibm_crcr >> 32) & 0x0000ffff; break; /* Processor Operation Register */ @@ -2598,6 +2599,12 @@ cpu_RDMSR(void) if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) EAX = msr.ibm_por2 & 0x3f000000; break; + + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + EAX = msr.ibm_pcr & 0x00d6001a; + break; } break; @@ -2780,12 +2787,20 @@ cpu_RDMSR(void) case CPU_K6_3: case CPU_K6_2P: case CPU_K6_3P: - EAX = EDX = 0; + EAX = 0; + /* EDX is left unchanged when reading this MSR! */ + if (ECX != 0x82) + EDX = 0; switch (ECX) { /* Machine Check Address Register */ case 0x00000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; /* Machine Check Type Register */ case 0x00000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; break; /* Test Register 12 */ case 0x0000000e: @@ -2796,11 +2811,32 @@ cpu_RDMSR(void) EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_aar & 0xffffffff; + /* EDX is left unchanged! */ + break; /* Hardware Configuration Register */ case 0x00000083: EAX = msr.amd_hwcr & 0xffffffff; EDX = msr.amd_hwcr >> 32; break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_watmcr & 0xffffffff; + EDX = msr.amd_watmcr >> 32; + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_wapmrr & 0xffffffff; + EDX = msr.amd_wapmrr >> 32; + break; /* Extended Feature Enable Register */ case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; @@ -3033,16 +3069,37 @@ pentium_invalid_rdmsr: case CPU_CxGX1: case CPU_Cx6x86MX: switch (ECX) { - /* Machine Check Exception Address */ - case 0x00: - /* Machine Check Exception Type */ - case 0x01: + /* Test Data */ + case 0x03: + EAX = msr.tr3; + break; + /* Test Address */ + case 0x04: + EAX = msr.tr4; + break; + /* Test Command/Status */ + case 0x05: + EAX = msr.tr5; break; /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ + case 0x11: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; @@ -3331,8 +3388,8 @@ cpu_WRMSR(void) switch (cpu_s->cpu_type) { case CPU_IBM386SLC: - case CPU_IBM486BL: case CPU_IBM486SLC: + case CPU_IBM486BL: switch (ECX) { /* Processor Operation Register */ case 0x1000: @@ -3341,13 +3398,18 @@ cpu_WRMSR(void) break; /* Cache Region Control Register */ case 0x1001: - msr.ibm_crcr = EAX & 0xffffffffff; + msr.ibm_crcr = EAX | ((uint64_t) (EDX & 0x0000ffff) << 32); break; /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) msr.ibm_por2 = EAX & 0x3f000000; break; + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + msr.ibm_pcr = EAX & 0x00d6001a; + break; } break; @@ -3521,22 +3583,45 @@ cpu_WRMSR(void) case CPU_K6_3P: switch (ECX) { /* Machine Check Address Register */ - case 0x00: + case 0x00000000: + if (cpu_s->cpu_type > CPU_5K86) + msr.mcar = EAX | ((uint64_t) EDX << 32); + break; /* Machine Check Type Register */ - case 0x01: + case 0x00000001: + if (cpu_s->cpu_type > CPU_5K86) + msr.mctr = EAX | ((uint64_t) EDX << 32); break; /* Test Register 12 */ - case 0x0e: - msr.tr12 = EAX & 0x228; + case 0x0000000e: + msr.tr12 = EAX & 0x8; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_aar = EAX | ((uint64_t) EDX << 32); + break; /* Hardware Configuration Register */ - case 0x83: + case 0x00000083: msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_watmcr = EAX | ((uint64_t) EDX << 32); + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_wapmrr = EAX | ((uint64_t) EDX << 32); + break; /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); @@ -3757,15 +3842,31 @@ pentium_invalid_wrmsr: case CPU_Cx6x86MX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { - /* Machine Check Exception Address */ - case 0x00: - /* Machine Check Exception Type */ - case 0x01: - break; + /* Test Data */ + case 0x03: + msr.tr3 = EAX; + /* Test Address */ + case 0x04: + msr.tr4 = EAX; + /* Test Command/Status */ + case 0x05: + msr.tr5 = EAX & 0x008f0f3b; /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Performance Monitor - Control and Event Select */ + case 0x11: + msr.cesr = EAX & 0x7ff07ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; } break; #endif diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8ff02d40d..3a6d73cd4 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -230,6 +230,7 @@ typedef struct { uint64_t ibm_por; /* 0x00001000 - 386SLC and later */ uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */ uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ + uint64_t ibm_pcr; /* 0x00001004 - 486BL3 */ /* IDT WinChip C6/2/VIA Cyrix III MSRs */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ @@ -239,11 +240,14 @@ typedef struct { uint32_t mcr_ctrl; /* 0x00000120 (IDT) */ /* AMD K5/K6 MSRs */ - uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ + uint64_t amd_aar; /* 0x00000082 - all K5 */ + uint64_t amd_hwcr; /* 0x00000083 - all K5 and all K6 */ + uint64_t amd_watmcr; /* 0x00000085 - K5 Model 1 and later */ + uint64_t amd_wapmrr; /* 0x00000086 - K5 Model 1 and later */ - uint64_t amd_efer; /* 0xc0000080 - all K5 and K6 */ + uint64_t amd_efer; /* 0xc0000080 - all K5 and all K6 */ uint64_t amd_star; /* 0xc0000081 - K6-2 and later */ - uint64_t amd_whcr; /* 0xc0000082 - all K5 and K6 */ + uint64_t amd_whcr; /* 0xc0000082 - all K5 and all K6 */ uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */ uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */ uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */ From 996769095bff9330c9673a5ec2031bc9bd03bc08 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 5 Feb 2024 17:03:10 +0500 Subject: [PATCH 052/690] Implement most missing P6 MSRs Remove the 6 extraneous performance counter MSRs which haven't existed on P6 --- src/cpu/cpu.c | 163 ++++++++++++++++++++++++++++++++++++++++---------- src/cpu/cpu.h | 11 ++-- 2 files changed, 139 insertions(+), 35 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 9b01b8ab7..4398df36c 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2713,8 +2713,8 @@ cpu_RDMSR(void) break; /* PERFCTR1 - Performance Counter Register 1 */ case 0xc2: - EAX = msr.ia32_pmc[1] & 0xffffffff; - EDX = msr.ia32_pmc[1] >> 32; + EAX = msr.perfctr[1] & 0xffffffff; + EDX = msr.perfctr[1] >> 32; break; /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: @@ -2726,8 +2726,8 @@ cpu_RDMSR(void) break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - EAX = msr.evntsel1 & 0xffffffff; - EDX = msr.evntsel1 >> 32; + EAX = msr.evntsel[1] & 0xffffffff; + EDX = msr.evntsel[1] >> 32; break; /* Feature Control Register */ case 0x1107: @@ -3124,13 +3124,16 @@ pentium_invalid_rdmsr: break; /* IA32_PLATFORM_ID - Platform ID */ case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) + if (cpu_s->cpu_type < CPU_PENTIUM2D) goto i686_invalid_rdmsr; if (cpu_f->package == CPU_PKG_SLOT2) - EDX |= 0x80000; + EDX |= (1 << 19); else if (cpu_f->package == CPU_PKG_SOCKET370) - EDX |= 0x100000; + EDX |= (1 << 20); + break; + /* Unknown */ + case 0x18: break; /* IA32_APIC_BASE - APIC Base Address */ case 0x1B: @@ -3143,6 +3146,11 @@ pentium_invalid_rdmsr: EAX = msr.ecx20 & 0xffffffff; EDX = msr.ecx20 >> 32; break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; @@ -3178,6 +3186,21 @@ pentium_invalid_rdmsr: EAX |= (1 << 19); } break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + EAX = msr.test_ctl; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: EAX = msr.bios_updt & 0xffffffff; @@ -3189,10 +3212,15 @@ pentium_invalid_rdmsr: EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; - /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ - case 0xc1 ... 0xc8: - EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + /* Unknown */ + case 0xae: + break; + /* PERFCTR0 - Performance Counter Register 0 */ + case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + EAX = msr.perfctr[ECX - 0xC1] & 0xffffffff; + EDX = msr.perfctr[ECX - 0xC1] >> 32; break; /* MTRRcap */ case 0xfe: @@ -3229,6 +3257,13 @@ pentium_invalid_rdmsr: EAX = msr.bbl_cr_ctl3 & 0xffffffff; EDX = msr.bbl_cr_ctl3 >> 32; break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: + break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3269,23 +3304,30 @@ pentium_invalid_rdmsr: break; /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - EAX = msr.evntsel0 & 0xffffffff; - EDX = msr.evntsel0 >> 32; - break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - EAX = msr.evntsel1 & 0xffffffff; - EDX = msr.evntsel1 >> 32; + EAX = msr.evntsel[ECX - 0x186] & 0xffffffff; + EDX = msr.evntsel[ECX - 0x186] >> 32; + break; + /* Unknown */ + case 0x1d3: break; /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: - EAX = msr.debug_ctl & 0xffffffff; - EDX = msr.debug_ctl >> 32; + EAX = msr.debug_ctl; + break; + /* LASTBRANCHFROMIP - address from which a branch was last taken */ + case 0x1db: + /* LASTBRANCHTOIP - destination address of the last taken branch instruction */ + case 0x1dc: + /* LASTINTFROMIP - address at which an interrupt last occurred */ + case 0x1dd: + /* LASTINTTOIP - address to which the last interrupt caused a branch */ + case 0x1de: break; /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; - EDX = msr.rob_cr_bkuptmpdr6 >> 32; + EAX = msr.rob_cr_bkuptmpdr6; break; /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ @@ -3320,9 +3362,16 @@ pentium_invalid_rdmsr: break; /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_rdmsr; EAX = msr.pat & 0xffffffff; EDX = msr.pat >> 32; break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; @@ -3367,6 +3416,12 @@ pentium_invalid_rdmsr: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: + break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3509,7 +3564,7 @@ cpu_WRMSR(void) break; /* PERFCTR0 - Performance Counter Register 1 */ case 0xc2: - msr.ia32_pmc[1] = EAX | ((uint64_t) EDX << 32); + msr.perfctr[1] = EAX | ((uint64_t) EDX << 32); break; /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: @@ -3518,7 +3573,7 @@ cpu_WRMSR(void) break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + msr.evntsel[1] = EAX | ((uint64_t) EDX << 32); break; /* Feature Control Register */ case 0x1107: @@ -3888,6 +3943,9 @@ pentium_invalid_wrmsr: case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x18: + break; /* IA32_APIC_BASE - APIC Base Address */ case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); @@ -3899,9 +3957,29 @@ pentium_invalid_wrmsr: case 0x20: msr.ecx20 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + msr.test_ctl = EAX; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: msr.bios_updt = EAX | ((uint64_t) EDX << 32); @@ -3911,9 +3989,14 @@ pentium_invalid_wrmsr: case 0x88 ... 0x8b: msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; - /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ - case 0xc1 ... 0xc8: - msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); + /* Unknown */ + case 0xae: + break; + /* PERFCTR0 - Performance Counter Register 0 */ + case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + msr.perfctr[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); break; /* MTRRcap */ case 0xfe: @@ -3943,6 +4026,13 @@ pentium_invalid_wrmsr: case 0x11e: msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: + break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3978,19 +4068,19 @@ pentium_invalid_wrmsr: break; /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - msr.evntsel0 = EAX | ((uint64_t) EDX << 32); - break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + msr.evntsel[ECX - 0x186] = EAX | ((uint64_t) EDX << 32); + break; + case 0x1d3: break; /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: - msr.debug_ctl = EAX | ((uint64_t) EDX << 32); + msr.debug_ctl = EAX; break; /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); + msr.rob_cr_bkuptmpdr6 = EAX; break; /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ @@ -4018,8 +4108,15 @@ pentium_invalid_wrmsr: break; /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_wrmsr; msr.pat = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); @@ -4063,6 +4160,12 @@ pentium_invalid_wrmsr: case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: + break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 3a6d73cd4..c829a0e17 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -277,10 +277,11 @@ typedef struct { /* Pentium Pro/II MSRs */ uint64_t apic_base; /* 0x0000001b */ + uint32_t test_ctl; /* 0x00000033 */ uint64_t bios_updt; /* 0x00000079 */ uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t perfctr[2]; /* 0x000000c1, 0x000000c2 */ uint64_t mtrr_cap; /* 0x000000fe */ uint64_t bbl_cr_addr; /* 0x00000116 */ @@ -295,10 +296,10 @@ typedef struct { uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */ uint64_t mcg_ctl; /* 0x0000017b */ - uint64_t evntsel0; /* 0x00000186 */ - uint64_t evntsel1; /* 0x00000187 */ - uint64_t debug_ctl; /* 0x000001d9 */ - uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ + uint64_t evntsel[2]; /* 0x00000186, 0x00000187 */ + + uint32_t debug_ctl; /* 0x000001d9 */ + uint32_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ /* MTTR-related MSRs also present on the VIA Cyrix III */ uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */ From 5ce8b9e1a1f398314d63d4155daa30c825f8607f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 00:34:29 +0600 Subject: [PATCH 053/690] 24-bpp image blit fixes --- src/video/vid_c&t_69000.c | 130 +++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 38 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index ee83ba6a9..60afb8d65 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -35,6 +35,7 @@ #include <86box/i2c.h> #include <86box/vid_ddc.h> #include <86box/plat_unused.h> +#include <86box/bswap.h> #include #pragma pack(push, 1) @@ -352,7 +353,6 @@ chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) void chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) { - uint32_t orig_dst = *dst & 0xFF000000; switch (rop) { case 0x00: *dst = 0; @@ -402,8 +402,6 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) *dst = 0xFF; break; } - *dst &= 0xFFFFFF; - *dst |= orig_dst; } void @@ -868,15 +866,15 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } if (chips->bitblt_running.bytes_per_pixel == 3) { pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; } } @@ -962,21 +960,6 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) void chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) { - /* Notes: - Reserved value of 0b000 for monochrome source alignment makes it use Destination Scanline Width. - - TODO: - Actually implement this. - - Figure out how alignment works. The example provided is unclear about non-quadword alignment. - (Outside of the one xf86-video-chips already documents). - Maybe it merely advances the source address pointer by alignment after consuming a byte. - - Edit: It actually consumes all 8 bytes of the quadword before incrementing the pitch. - Which begs the next question: Are those 8 bytes for same-scanline drawing or for y-incremented drawing? - And is 4-byte-or-less alignment relevant for our purposes? The Monochrome Source Register only talks about quadwords, nothing else. - */ - uint64_t i = 0; uint8_t is_true = 0; int orig_x = chips->bitblt_running.x; @@ -1276,6 +1259,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + int orig_cycles = cycles; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); @@ -1325,6 +1309,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; chips_69000_process_mono_data(chips, mono_data); } + cycles = orig_cycles; return; } @@ -1334,16 +1319,18 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { + int orig_cycles = cycles; uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; - if (chips->bitblt_running.bytes_per_pixel == 2) + if (chips->bitblt_running.bytes_per_pixel >= 2) source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); - if (chips->bitblt_running.bytes_per_pixel == 3) + if (chips->bitblt_running.bytes_per_pixel >= 3) source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); chips->bitblt_running.bytes_in_line_written += chips->bitblt_running.bytes_per_pixel; chips_69000_process_pixel(chips, source_pixel); + cycles = orig_cycles; chips->bitblt_running.x += chips->bitblt_running.x_dir; if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { @@ -1504,6 +1491,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA0: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); + chips->svga.hwcursor.cur_xsize = chips->svga.hwcursor.cur_ysize = ((val & 7) == 0b1) ? 32 : 64; break; case 0xA2: chips->ext_regs[chips->ext_index] = val; @@ -1529,6 +1517,12 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; break; + case 0xC8: + case 0xC9: + case 0xCB: + chips->ext_regs[chips->ext_index] = val; + svga_recalctimings(&chips->svga); + break; case 0xD2: break; default: @@ -1575,6 +1569,14 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) val <<= 2; svga->fullchange = svga->monitor->mon_changeframecount; switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; case 2: index = svga->dac_addr & 7; chips->cursor_palette[index].r = svga->dac_r; @@ -2153,44 +2155,49 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) { chips_69000_t *chips = (chips_69000_t *) svga->priv; uint64_t dat[2]; - int offset = svga->hwcursor_latch.x; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; +#if 0 if ((chips->ext_regs[0xA0] & 7) == 1) { + uint32_t oddaddr = (displine - svga->hwcursor_latch.y) & 1; + uint32_t dat_32[2]; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - dat[0] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += oddaddr ? 4 : 8; for (uint8_t x = 0; x < 32; x++) { - if (!(dat[1] & (1ULL << 31))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); - else if (dat[0] & (1ULL << 31)) + if (!(dat_32[1] & (1ULL << 31))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat_32[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + else if (dat_32[0] & (1ULL << 31)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; offset++; - dat[0] <<= 1; - dat[1] <<= 1; + dat_32[0] <<= 1; + dat_32[1] <<= 1; } if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + svga->hwcursor_latch.addr += oddaddr ? 8 : 4; return; } +#endif if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (chips->ext_regs[0xA0] & 7) == 1 ? 8 : 16; + svga->hwcursor_latch.addr += 16; - dat[0] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; switch (chips->ext_regs[0xa0] & 7) { + case 0b1: case 0b101: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[1]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[0]); + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; @@ -2208,6 +2215,51 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static float +chips_69000_getclock(int clock, void *priv) +{ + const chips_69000_t *chips = (chips_69000_t *) priv; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + + int m = chips->ext_regs[0xc8]; + int n = chips->ext_regs[0xc9]; + int pl = (chips->ext_regs[0xcb] >> 4) & 7; + + float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2)); + if (chips->ext_regs[0xcb] & 4) + fvco *= 4.0; + float fo = fvco / (float)(1 << pl); + + return fo; +} + +uint32_t +chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; +} + static void * chips_69000_init(const device_t *info) { @@ -2236,6 +2288,8 @@ chips_69000_init(const device_t *info) chips->svga.recalctimings_ex = chips_69000_recalctimings; chips->svga.vblank_start = chips_69000_vblank_start; chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; + chips->svga.getclock = chips_69000_getclock; + chips->svga.conv_16to32 = chips_69000_conv_16to32; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From 89cc2a3956e5d9dda3d0939765dd1fcbf96cb38f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 7 Feb 2024 20:45:45 +0100 Subject: [PATCH 054/690] NEC CD-ROM: Make command DAh not also set speed. --- src/scsi/scsi_cdrom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index f52401785..a6420fb01 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1864,7 +1864,9 @@ begin: cdrom_audio_pause_resume(dev->drv, 0x00); dev->drv->audio_op = 0x01; scsi_cdrom_command_complete(dev); - break; + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) + scsi_cdrom_buf_free(dev); + return; } fallthrough; case GPCMD_SET_SPEED: From ca11dae903736cabc34adb3321630e2f57162162 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 7 Feb 2024 20:56:25 +0100 Subject: [PATCH 055/690] Fix SVGA code warnings. See above. --- src/video/vid_svga.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d982a1ada..edb05086a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -573,10 +573,10 @@ svga_recalctimings(svga_t *svga) double _dispontime; double _dispofftime; double disptime; - double crtcconst8514; - double _dispontime8514; - double _dispofftime8514; - double disptime8514; + double crtcconst8514 = 0.0; + double _dispontime8514 = 0.0; + double _dispofftime8514 = 0.0; + double disptime8514 = 0.0; #ifdef ENABLE_SVGA_LOG int vsyncend; int vblankend; @@ -998,7 +998,6 @@ void svga_poll(void *priv) { svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; xga_t *xga = (xga_t *) svga->xga; uint32_t x; uint32_t blink_delay; From 395941aa54a30aaba1709f3db42ac67c2f9f2abf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 02:07:49 +0600 Subject: [PATCH 056/690] HWCursor work --- src/video/vid_c&t_69000.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 60afb8d65..df41e9095 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -207,6 +207,8 @@ chips_69000_read_flat_panel(chips_69000_t* chips) case 0: /* Report no presence of flat panel module. */ return 0; + case 1: + return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; } @@ -745,6 +747,10 @@ chips_69000_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x70] & 0x80); + if (svga->dispend == 2002 && svga->hdisp == 1024) { + svga->dispend = 1280; + } + switch (chips->ext_regs[0x81] & 0xF) { case 0b0010: svga->bpp = 8; @@ -1413,6 +1419,9 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x71: val = 0x0; break; + case 0xD0: + val |= 1; + break; } // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) @@ -2189,13 +2198,21 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; - dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); - dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); - svga->hwcursor_latch.addr += 16; + if ((svga->hwcursor_on & 1) && (chips->ext_regs[0xa0] & 7) == 0b1) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr - 16])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[(svga->hwcursor_latch.addr - 16) + 8])); + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } + else { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + } switch (chips->ext_regs[0xa0] & 7) { case 0b1: case 0b101: - for (uint8_t x = 0; x < 64; x++) { + for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); else if (dat[0] & (1ULL << 63)) From a0078e6d2b6e915afd15edb633f5812904dfb52d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 13:22:01 +0600 Subject: [PATCH 057/690] Fix inverted hardware cursor color --- src/video/vid_c&t_69000.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index df41e9095..8128c8086 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1157,6 +1157,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } return; } + + if (chips->bitblt_running.x_dir == -1 && chips->bitblt_running.bytes_per_pixel == 3) { + //chips->bitblt_running.actual_destination_width++; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; @@ -2168,14 +2172,12 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) #if 0 if ((chips->ext_regs[0xA0] & 7) == 1) { - uint32_t oddaddr = (displine - svga->hwcursor_latch.y) & 1; + uint32_t evenline = svga->hwcursor_latch.cur_ysize - ((svga->hwcursor_on) & ~1) >> 1; uint32_t dat_32[2]; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr])); - dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); - svga->hwcursor_latch.addr += oddaddr ? 4 : 8; + dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); + dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8 + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); + svga->hwcursor_latch.addr = svga->hwcursor.addr + (evenline * 16); for (uint8_t x = 0; x < 32; x++) { if (!(dat_32[1] & (1ULL << 31))) @@ -2188,9 +2190,6 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) dat_32[1] <<= 1; } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - return; } #endif @@ -2214,7 +2213,7 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) case 0b101: for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; From 4a087b81c64f0d5195127367ccf9d620799bcd28 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 15:51:15 +0600 Subject: [PATCH 058/690] Fix RTL BitBlt on 16+ bpp --- src/video/vid_c&t_69000.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 8128c8086..2e11764d9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1128,6 +1128,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 1: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; case 2: chips->bitblt_running.x_dir = 1; @@ -1136,6 +1138,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 3: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; } @@ -1517,18 +1521,26 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA4: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.x = val | (chips->ext_regs[0xA5] & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; break; case 0xA5: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.x = chips->ext_regs[0xA4] | (val & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; break; case 0xA6: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; break; case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; break; case 0xC8: case 0xC9: @@ -2213,9 +2225,9 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) case 0b101: for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; dat[0] <<= 1; From 3e098b190e25553f4a4491660bcc0fd1a48a51ca Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 16:08:05 +0600 Subject: [PATCH 059/690] HW cursor position fixing --- src/video/vid_c&t_69000.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 2e11764d9..4f8254477 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1533,8 +1533,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA6: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80) - chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; + chips->svga.hwcursor.y = 0; + } break; case 0xA7: chips->ext_regs[chips->ext_index] = val; From da3203a6c10c48426d1296a7abaf2a74da3878c2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 9 Feb 2024 00:20:59 +0600 Subject: [PATCH 060/690] Force interlace to be off at 1280x1024 --- src/video/vid_c&t_69000.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 4f8254477..cbfb7b6d6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -747,8 +747,8 @@ chips_69000_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x70] & 0x80); - if (svga->dispend == 2002 && svga->hdisp == 1024) { - svga->dispend = 1280; + if (svga->hdisp == 1280 && svga->dispend == 1024) { + svga->interlace = 0; } switch (chips->ext_regs[0x81] & 0xF) { @@ -1541,8 +1541,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80) - chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + if (chips->ext_regs[0xA7] & 0x80){ + chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; + chips->svga.hwcursor.y = 0; + } break; case 0xC8: case 0xC9: From d646efc2888fdf9aedff7450d33507634b08f616 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 9 Feb 2024 12:44:43 +0600 Subject: [PATCH 061/690] Fix hardware cursor in interlaced modes Report 1280*1024 Dual Scan STN Color Panel for now --- src/video/vid_c&t_69000.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index cbfb7b6d6..9968e5205 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -209,6 +209,8 @@ chips_69000_read_flat_panel(chips_69000_t* chips) return 0; case 1: return 1; + case 0x10: + return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; } @@ -1425,7 +1427,7 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x3; break; case 0x71: - val = 0x0; + val = 0b01101000; break; case 0xD0: val |= 1; @@ -2186,29 +2188,26 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) uint64_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; -#if 0 - if ((chips->ext_regs[0xA0] & 7) == 1) { - uint32_t evenline = svga->hwcursor_latch.cur_ysize - ((svga->hwcursor_on) & ~1) >> 1; - uint32_t dat_32[2]; - - dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); - dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8 + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); - svga->hwcursor_latch.addr = svga->hwcursor.addr + (evenline * 16); - + if (svga->interlace && (chips->ext_regs[0xa0] & 7) == 0b1) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + if (svga->hwcursor_oddeven) { + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } for (uint8_t x = 0; x < 32; x++) { - if (!(dat_32[1] & (1ULL << 31))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat_32[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); - else if (dat_32[0] & (1ULL << 31)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; - dat_32[0] <<= 1; - dat_32[1] <<= 1; + dat[0] <<= 1; + dat[1] <<= 1; } - return; } -#endif if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -2339,8 +2338,6 @@ chips_69000_init(const device_t *info) chips->flat_panel_regs[0x01] = 1; - sizeof(struct chips_69000_bitblt_t); - return chips; } From 5a3d74d64f0a09c4aedbad794f3e94da89976c59 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 12:14:35 +0100 Subject: [PATCH 062/690] 286/386 interpreter fixes - the correct opcode arrays are now used and fixed the debug registers. --- src/cpu/386.c | 14 +-- src/cpu/386_common.c | 10 +- src/cpu/386_common.h | 58 ++++++++--- src/cpu/386_ops.h | 12 ++- src/cpu/cpu.h | 1 + src/cpu/x86.c | 6 ++ src/cpu/x86_ops_fpu_2386.h | 113 ++++++++++++++++++++ src/cpu/x86_ops_misc.h | 17 +++ src/cpu/x86_ops_mov_ctrl_2386.h | 154 +++++++++++++++++++++------ src/cpu/x86_ops_mov_seg.h | 8 ++ src/cpu/x86_ops_prefix_2386.h | 179 ++++++++++++++++++++++++++++++++ src/cpu/x86_ops_rep_2386.h | 4 +- src/cpu/x86_ops_stack.h | 8 ++ src/include/86box/mem.h | 1 + src/mem/mmu_2386.c | 146 +++++++++++++------------- src/mem/rom.c | 6 ++ 16 files changed, 597 insertions(+), 140 deletions(-) create mode 100644 src/cpu/x86_ops_fpu_2386.h create mode 100644 src/cpu/x86_ops_prefix_2386.h diff --git a/src/cpu/386.c b/src/cpu/386.c index b5a1e61e3..c7e31de22 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -25,6 +25,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> +#include <86box/plat_fallthrough.h> #include <86box/gdbstub.h> #ifndef OPS_286_386 # define OPS_286_386 @@ -262,11 +263,10 @@ exec386_2386(int32_t cycs) CHECK_READ_CS(MIN(ol, 4)); ins_fetch_fault = cpu_386_check_instruction_fault(); - if (!cpu_state.abrt && ins_fetch_fault) { - x86gen(); + /* Breakpoint fault has priority over other faults. */ + if (ins_fetch_fault) { ins_fetch_fault = 0; - /* No instructions executed at this point. */ - goto block_ended; + cpu_state.abrt = 1; } if (!cpu_state.abrt) { @@ -279,7 +279,8 @@ exec386_2386(int32_t cycs) trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + cpu_state.eflags &= ~(RF_FLAG); + x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); if (x86_was_reset) break; } @@ -319,8 +320,7 @@ block_ended: #endif } } - if (!x86_was_reset && ins_fetch_fault) - x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */ +according to the manual. */ } else if (trap) { flags_rebuild(); if (trap & 2) dr[6] |= 0x8000; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index f9ca3408d..d74b181bf 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1412,7 +1412,7 @@ x86_int(int num) cpu_state.pc = cpu_state.oldpc; if (msw & 1) - is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0); + cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0); else { addr = (num << 2) + idt.base; @@ -1445,7 +1445,7 @@ x86_int(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); } } @@ -1462,7 +1462,7 @@ x86_int_sw(int num) cycles -= timing_int; if (msw & 1) - is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1); + cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1); else { addr = (num << 2) + idt.base; @@ -1487,7 +1487,7 @@ x86_int_sw(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cycles -= timing_int_rm; } } @@ -1529,7 +1529,7 @@ x86_int_sw_rm(int num) cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; - is486 ? loadcs(new_cs) : loadcs_2386(new_cs); + cpu_use_exec ? loadcs(new_cs) : loadcs_2386(new_cs); #ifndef USE_NEW_DYNAREC oxpc = cpu_state.pc; #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 35d4f7cc8..a98a3e930 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -225,19 +225,37 @@ int checkio(uint32_t port, int mask); static __inline uint8_t fastreadb(uint32_t a) { - return readmembl_2386(a); + uint8_t ret; + read_type = 1; + ret = readmembl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } static __inline uint16_t fastreadw(uint32_t a) { - return readmemwl_2386(a); + uint16_t ret; + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } static __inline uint32_t fastreadl(uint32_t a) { - return readmemll_2386(a); + uint32_t ret; + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } #else static __inline uint8_t @@ -342,31 +360,41 @@ extern int opcode_length[256]; static __inline uint16_t fastreadw_fetch(uint32_t a) { - uint16_t val; + uint16_t ret; if ((a & 0xFFF) > 0xFFE) { - val = fastreadb(a); - if (opcode_length[val & 0xff] > 1) - val |= ((uint16_t) fastreadb(a + 1) << 8); - return val; + ret = fastreadb(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1)) + ret |= ((uint16_t) fastreadb(a + 1) << 8); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; } - return readmemwl_2386(a); + return ret; } static __inline uint32_t fastreadl_fetch(uint32_t a) { - uint32_t val; + uint32_t ret; if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { - val = fastreadw_fetch(a); - if (opcode_length[val & 0xff] > 2) - val |= ((uint32_t) fastreadw(a + 2) << 16); - return val; + ret = fastreadw_fetch(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2)) + ret |= ((uint32_t) fastreadw(a + 2) << 16); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; } - return readmemll_2386(a); + return ret; } #else static __inline uint16_t diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 1bb3c167f..3e0d191f2 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -186,7 +186,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #else # include "x86_ops_flag.h" #endif -#include "x86_ops_fpu.h" +#ifdef OPS_286_386 +# include "x86_ops_fpu_2386.h" +#else +# include "x86_ops_fpu.h" +#endif #include "x86_ops_inc_dec.h" #include "x86_ops_int.h" #include "x86_ops_io.h" @@ -216,7 +220,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #include "x86_ops_mul.h" #include "x86_ops_pmode.h" -#include "x86_ops_prefix.h" +#ifdef OPS_286_386 +# include "x86_ops_prefix_2386.h" +#else +# include "x86_ops_prefix.h" +#endif #ifdef IS_DYNAREC # include "x86_ops_rep_dyn.h" #else diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index c829a0e17..db11b6135 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -174,6 +174,7 @@ typedef struct { #define VIP_FLAG 0x0010 /* in EFLAGS */ #define VID_FLAG 0x0020 /* in EFLAGS */ +#define EM_FLAG 0x00004 /* in CR0 */ #define WP_FLAG 0x10000 /* in CR0 */ #define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 64ff6be4c..8e4a5b547 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -275,6 +275,12 @@ reset_common(int hard) cr4 = 0; cpu_state.eflags = 0; cgate32 = 0; + if (is386 && !is486) { + for (uint8_t i = 0; i < 4; i++) + dr[i] = 0x00000000; + dr[6] = 0xffff1ff0; + dr[7] = 0x00000400; + } if (is286) { if (is486) loadcs(0xF000); diff --git a/src/cpu/x86_ops_fpu_2386.h b/src/cpu/x86_ops_fpu_2386.h new file mode 100644 index 000000000..52c24d995 --- /dev/null +++ b/src/cpu/x86_ops_fpu_2386.h @@ -0,0 +1,113 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +static int +opESCAPE_d8_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_d8_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_d9_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_d9_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_da_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_da_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_db_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_db_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_dc_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_dc_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_dd_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_dd_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_de_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_de_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_df_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_df_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat); +} + +static int +opWAIT(uint32_t fetchdat) +{ + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + +#if 0 + if (!cpu_use_dynarec && fpu_softfloat) { +#endif + if (fpu_softfloat) { + if (fpu_state.swd & FPU_SW_Summary) { + if (cr0 & 0x20) { + x86_int(16); + return 1; + } + } + } + CLOCK_CYCLES(4); + return 0; +} diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index cbd2b3fbe..87dddefd8 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -726,6 +726,22 @@ opHLT(uint32_t fetchdat) return 0; } +#ifdef OPS_286_386 +static int +opLOCK(uint32_t fetchdat) +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + ILLEGAL_ON((fetchdat & 0xff) == 0x90); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +#else static int opLOCK(uint32_t fetchdat) { @@ -740,6 +756,7 @@ opLOCK(uint32_t fetchdat) PREFETCH_PREFIX(); return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } +#endif static int opBOUND_w_a16(uint32_t fetchdat) diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index c57dc8226..cae6c9957 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -82,18 +82,41 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; } - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); return 0; @@ -101,18 +124,41 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_32(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; } - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); return 0; @@ -236,24 +282,41 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { - dr[7] |= 0x2000; - dr[6] &= ~0x2000; - x86gen(); + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; return 1; } fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: x86illegal(); - else - cpu_reg += 2; + return 1; } - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); CPU_BLOCK_END(); @@ -262,18 +325,41 @@ opMOV_DRx_r_a16(uint32_t fetchdat) static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; } - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); CPU_BLOCK_END(); diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 2a798db5c..7fcc92312 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -195,7 +195,11 @@ opMOV_seg_w_a16(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ op_loadseg(new_seg, &cpu_state.seg_fs); @@ -240,7 +244,11 @@ opMOV_seg_w_a32(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ op_loadseg(new_seg, &cpu_state.seg_fs); diff --git a/src/cpu/x86_ops_prefix_2386.h b/src/cpu/x86_ops_prefix_2386.h new file mode 100644 index 000000000..7c87f0bf3 --- /dev/null +++ b/src/cpu/x86_ops_prefix_2386.h @@ -0,0 +1,179 @@ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) +op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) + +op_seg(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) + +op_seg(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) + // clang-format on + +static int +op_66(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} diff --git a/src/cpu/x86_ops_rep_2386.h b/src/cpu/x86_ops_rep_2386.h index b6f64e90d..fe5048340 100644 --- a/src/cpu/x86_ops_rep_2386.h +++ b/src/cpu/x86_ops_rep_2386.h @@ -836,7 +836,7 @@ REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) static int opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; @@ -850,7 +850,7 @@ opREPNE(uint32_t fetchdat) static int opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 13eb883d3..fbf603ddb 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -667,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } @@ -695,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 15afcb160..bc949834f 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -303,6 +303,7 @@ extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint32_t pages_sz; /* #pages in table */ +extern int read_type; extern int mem_a20_state; extern int mem_a20_alt; diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 9ed26edfa..7c286b605 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -39,52 +39,43 @@ #include <86box/rom.h> #include <86box/gdbstub.h> -/* Set trap for data address breakpoints. */ -void -mem_debug_check_addr(uint32_t addr, int write) -{ - int i = 0; - int set_trap = 0; +/* As below, 1 = exec, 4 = read. */ +int read_type = 4; - if (!(dr[7] & 0xFF)) +/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */ +void +mem_debug_check_addr(uint32_t addr, int flags) +{ + uint32_t bp_addr; + uint32_t bp_mask; + uint32_t len_type_pair; + int bp_enabled; + uint8_t match_flags[4] = { 0, 2, 0, 6 }; + char *bp_types[5] = { "N/A 0", "EXEC ", "WRITE", "N/A 3", "READ " }; + + if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) return; - for (i = 0; i < 4; i++) { - uint32_t dr_addr = dr[i]; - int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); - int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); - if (!breakpoint_enabled) - continue; - if (!write && (len_type_pair & 3) != 3) - continue; - if ((len_type_pair & 3) != 1) - continue; - - switch ((len_type_pair >> 2) & 3) - { - case 0x00: - if (dr_addr == addr) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x01: - if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x03: - dr_addr &= ~3; - if (addr >= dr_addr && addr < (dr_addr + 4)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; + if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) { + bp_addr = dr[i]; + bp_enabled = (dr[7] >> (i << 1)) & 0x03; + len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f; + bp_mask = ~((len_type_pair >> 2) & 0x03); + + if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) { + /* + From the Intel i386 documemntation: + + (Note that the processor sets Bn regardless of whether Gn or + Ln is set. If more than one breakpoint condition occurs at one time and if + the breakpoint trap occurs due to an enabled condition other than n, Bn may + be set, even though neither Gn nor Ln is set.) + */ + dr[6] |= (1 << i); + if (bp_enabled) + trap |= (read_type == 1) ? 8 : 4; } } - if (set_trap) - trap |= 4; } uint8_t @@ -291,7 +282,7 @@ readmembl_2386(uint32_t addr) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr, read_type); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -319,7 +310,7 @@ writemembl_2386(uint32_t addr, uint8_t val) mem_mapping_t *map; uint64_t a; - mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr, 2); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); addr64 = (uint64_t) addr; @@ -397,8 +388,8 @@ readmemwl_2386(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); + mem_debug_check_addr(addr, read_type); + mem_debug_check_addr(addr + 1, read_type); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -419,7 +410,8 @@ readmemwl_2386(uint32_t addr) } } - return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); + return readmembl_no_mmut_2386(addr, addr64a[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, addr64a[1])) << 8); } } @@ -454,8 +446,8 @@ writememwl_2386(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); + mem_debug_check_addr(addr, 2); + mem_debug_check_addr(addr + 1, 2); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -482,8 +474,8 @@ writememwl_2386(uint32_t addr, uint16_t val) /* 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); + writemembl_no_mmut_2386(addr, addr64a[0], val); + writemembl_no_mmut_2386(addr + 1, addr64a[1], val >> 8); return; } } @@ -531,7 +523,8 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) return 0xffff; } - return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); + return readmembl_no_mmut_2386(addr, a64[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, a64[1])) << 8); } } @@ -574,8 +567,8 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) return; } - writemembl_no_mmut(addr, a64[0], val); - writemembl_no_mmut(addr + 1, a64[1], val >> 8); + writemembl_no_mmut_2386(addr, a64[0], val); + writemembl_no_mmut_2386(addr + 1, a64[1], val >> 8); return; } } @@ -611,7 +604,7 @@ readmemll_2386(uint32_t addr) for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); + mem_debug_check_addr(addr + i, read_type); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); @@ -619,8 +612,8 @@ readmemll_2386(uint32_t addr) high_page = 0; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -647,7 +640,8 @@ readmemll_2386(uint32_t addr) /* 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); + return readmemwl_no_mmut_2386(addr, addr64a) | + (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); } } @@ -684,7 +678,7 @@ writememll_2386(uint32_t addr, uint32_t val) for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); + mem_debug_check_addr(addr + i, 2); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); @@ -692,8 +686,8 @@ writememll_2386(uint32_t addr, uint32_t val) high_page = 0; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -724,8 +718,8 @@ writememll_2386(uint32_t addr, uint32_t val) /* 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); + writememwl_no_mmut_2386(addr, &(addr64a[0]), val); + writememwl_no_mmut_2386(addr + 2, &(addr64a[2]), val >> 16); return; } } @@ -770,8 +764,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) mem_logical_addr = addr; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -779,7 +773,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) return 0xffffffff; } - return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); + return readmemwl_no_mmut_2386(addr, a64) | + ((uint32_t) (readmemwl_no_mmut_2386(addr + 2, &(a64[2]))) << 16); } } @@ -815,8 +810,8 @@ 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) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -824,8 +819,8 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) return; } - writememwl_no_mmut(addr, &(a64[0]), val); - writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); + writememwl_no_mmut_2386(addr, &(a64[0]), val); + writememwl_no_mmut_2386(addr + 2, &(a64[2]), val >> 16); return; } } @@ -867,7 +862,7 @@ readmemql_2386(uint32_t addr) for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); + mem_debug_check_addr(addr + i, read_type); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); @@ -902,7 +897,8 @@ readmemql_2386(uint32_t addr) /* 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); + return readmemll_no_mmut_2386(addr, addr64a) | + (((uint64_t) readmemll_no_mmut_2386(addr + 4, &(addr64a[4]))) << 32); } } @@ -932,7 +928,7 @@ writememql_2386(uint32_t addr, uint64_t val) for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); + mem_debug_check_addr(addr + i, 2); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); @@ -971,8 +967,8 @@ writememql_2386(uint32_t addr, uint64_t val) /* 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); + writememll_no_mmut_2386(addr, addr64a, val); + writememll_no_mmut_2386(addr + 4, &(addr64a[4]), val >> 32); return; } } @@ -1019,7 +1015,7 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - mem_debug_check_addr(addr, write); + mem_debug_check_addr(addr, write ? 2 : read_type); for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; diff --git a/src/mem/rom.c b/src/mem/rom.c index 4a20e8ebc..f9718b7ce 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -296,6 +296,12 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); if (fread(ptr + addr, sz >> 1, 1, fp) > (sz >> 1)) fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + if (sz == 0x40000) { + if (fread(ptr + addr + 0x30000, 1, sz >> 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); + if (fread(ptr + addr + 0x20000, sz >> 1, 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + } } (void) fclose(fp); From 30e7a495584ecb684288578ea27e3f9cb0413024 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 12:15:28 +0100 Subject: [PATCH 063/690] Fix compile-breaking mistakes in cpu/386.c. --- src/cpu/386.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index c7e31de22..ad310d31e 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -297,7 +297,6 @@ exec386_2386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; -block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -320,7 +319,6 @@ block_ended: #endif } } -according to the manual. */ } else if (trap) { flags_rebuild(); if (trap & 2) dr[6] |= 0x8000; From 3f8952a558ddfaf1adda3b92b8604a35add52c67 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 18:02:33 +0100 Subject: [PATCH 064/690] More (S)VGA horizontal blanking fixes and CPU CR0 bit 4 fixes. --- src/cpu/x86.c | 2 ++ src/cpu/x86_ops_mov_ctrl.h | 4 ++-- src/include/86box/vid_svga.h | 2 ++ src/video/vid_cl54xx.c | 6 +++--- src/video/vid_s3.c | 22 +++++++++------------- src/video/vid_s3_virge.c | 34 +++++++++++++++++++--------------- src/video/vid_svga.c | 34 ++++++++++++++++++---------------- src/video/vid_voodoo_banshee.c | 6 +++--- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 8e4a5b547..2c8c29d49 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -270,6 +270,8 @@ reset_common(int hard) cr0 = 1 << 30; else cr0 = 0; + if (is386 && !is486 && (fpu_type == FPU_387)) + cr0 |= 0x10; cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index eafe3cdde..b0c841f83 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -124,7 +124,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; @@ -181,7 +181,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 624e85a1b..2f8a83a1d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -171,6 +171,8 @@ typedef struct svga_t { double clock; double clock8514; + double multiplier; + hwcursor_t hwcursor; hwcursor_t hwcursor_latch; hwcursor_t dac_hwcursor; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 49899b7b4..b8db0440d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1762,11 +1762,11 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | (((svga->crtc[0x1a] >> 4) & 3) << 6); - svga->hblank_end_mask = 0x0000007f; + svga->hblank_end_mask = 0x000000ff; if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d8691ad77..ca737e7fe 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3262,9 +3262,9 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4108,11 +4108,11 @@ s3_trio64v_recalctimings(svga_t *svga) break; } - if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4204,15 +4204,11 @@ s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3184a1ccd..1cb6424fb 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -826,9 +826,9 @@ s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -862,19 +862,21 @@ s3_virge_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 24: @@ -921,15 +923,17 @@ s3_virge_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index edb05086a..a3ad2edd8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -773,6 +773,8 @@ svga_recalctimings(svga_t *svga) } else svga->dots_per_clock = 1; + svga->multiplier = 1.0; + if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -813,26 +815,26 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on[0] || dev->on[1]) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000003f; - dev->hblank_sub = 0; + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; - while (1) { - if (dot8514 == dev->h_total) - dot = 0; + while (1) { + if (dot8514 == dev->h_total) + dot = 0; - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) - break; + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; - dot8514++; - adj_dot8514++; - } + dot8514++; + adj_dot8514++; + } - dev->h_disp -= dev->hblank_sub; + dev->h_disp -= dev->hblank_sub; } } } @@ -889,7 +891,7 @@ svga_recalctimings(svga_t *svga) svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, svga->hblankstart, svga->hblankend); - disptime = svga->htotal; + disptime = svga->htotal * svga->multiplier; _dispontime = svga->hdisp_time; if (ibm8514_active && (svga->dev8514 != NULL)) { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 9fec8c073..f03f6efd4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -557,14 +557,14 @@ banshee_recalctimings(svga_t *svga) /* Video processing mode - assume timings akin to Cirrus' special blanking mode, that is, no overscan and relying on display end to blank. */ if (banshee->vgaInit0 & 0x40) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; svga->hblank_end_mask = 0x0000003f; } - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) From a330860b2ed9000489276eb40c2bb1b9b5c25d18 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 9 Feb 2024 18:28:09 +0100 Subject: [PATCH 065/690] Fixed the Cirrus banking issue for good (really) A bit controversial regarding extra_banks but this should be enough to fix everything in the banks of the CL-GD54xx (up to 5480). --- src/video/vid_cl54xx.c | 44 ++++++++++++++---------------------------- src/video/vid_svga.c | 13 ++++--------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index b8db0440d..5d376effe 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -816,7 +816,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->seqregs[svga->seqaddr] &= 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; - gd54xx_recalc_banking(gd54xx); + gd54xx_set_svga_fast(gd54xx); svga_recalctimings(svga); break; @@ -1642,8 +1642,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) } else svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - - svga->write_bank = svga->read_bank = svga->extra_banks[0]; } static void @@ -1977,11 +1975,16 @@ gd54xx_recalctimings(svga_t *svga) svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { + if (svga->seqregs[1] & 8) svga->render = svga_render_text_40; - } else + else svga->render = svga_render_text_80; } + + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { + svga->extra_banks[0] = 0; + svga->extra_banks[1] = 0x8000; + } } static void @@ -2192,13 +2195,8 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) return; } - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { - svga_write(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; - svga_write_linear(addr, val, svga); } @@ -2214,11 +2212,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) return; } - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { - svga_writew(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2243,11 +2237,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writel(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2769,12 +2759,10 @@ gd54xx_read(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_read(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); } @@ -2786,15 +2774,13 @@ gd54xx_readw(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint16_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_readw(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } @@ -2806,9 +2792,6 @@ gd54xx_readl(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_readl(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; @@ -2817,6 +2800,7 @@ gd54xx_readl(uint32_t addr, void *priv) return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a3ad2edd8..81cc50bc4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1406,15 +1406,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) { - if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - } else { - if (write) - addr += svga->write_bank; - else - addr += svga->read_bank; - } + if (write) + addr += svga->write_bank; + else + addr += svga->read_bank; } return addr; From 2ab99dda0b7091cb7a80e59406ae259d8bc6ff62 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Feb 2024 03:05:56 +0100 Subject: [PATCH 066/690] Made LOCK instruction legality more accurate on 386, closes #4132. --- src/cpu/386_common.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 12 +++++++++++ src/cpu/x86_ops_misc.h | 41 ++++++++++++++++++++++++++++++++++-- src/mem/mmu_2386.c | 1 - 4 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index d74b181bf..77d984048 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -120,6 +120,53 @@ int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ +/* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */ +int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */ + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */ + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x2x */ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3 }; /* 0xfx */ + +int lock_legal_0f[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* 0xfx */ + +/* (modrm >> 3) & 0x07 */ +int lock_legal_ba[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + +/* Also applies to 81, 82, and 83 */ +int lock_legal_80[8] = { 1, 1, 1, 1, 1, 1, 1, 0 }; + +/* Also applies to F7 */ +int lock_legal_f6[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; + +/* Also applies to FF */ +int lock_legal_fe[8] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + uint32_t addr64; uint32_t addr64_2; uint32_t addr64a[8]; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index db11b6135..1456d2ee8 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -763,6 +763,11 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); #define SMHR_VALID (1 << 0) #define SMHR_ADDR_MASK (0xfffffffc) +typedef union { + uint32_t fd; + uint8_t b[4]; +} fetch_dat_t; + typedef struct { struct { uint32_t base; @@ -817,4 +822,11 @@ extern void prefetch_flush(void); extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32); +extern int lock_legal[256]; +extern int lock_legal_0f[256]; +extern int lock_legal_ba[8]; +extern int lock_legal_80[8]; +extern int lock_legal_f6[8]; +extern int lock_legal_fe[8]; + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 87dddefd8..419ee7dc2 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -730,12 +730,49 @@ opHLT(uint32_t fetchdat) static int opLOCK(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + int legal; + fetch_dat_t fetch_dat; + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 0; cpu_state.pc++; - ILLEGAL_ON((fetchdat & 0xff) == 0x90); + fetch_dat.fd = fetchdat; + + legal = lock_legal[fetch_dat.b[0]]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal[fetch_dat.b[1]]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; + } + + ILLEGAL_ON(legal == 0); CLOCK_CYCLES(4); PREFETCH_PREFIX(); diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 7c286b605..abc34ff96 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -51,7 +51,6 @@ mem_debug_check_addr(uint32_t addr, int flags) uint32_t len_type_pair; int bp_enabled; uint8_t match_flags[4] = { 0, 2, 0, 6 }; - char *bp_types[5] = { "N/A 0", "EXEC ", "WRITE", "N/A 3", "READ " }; if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) return; From 4dc7342d5e97bb7726036b81a12afb33c70735b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Feb 2024 04:51:07 +0100 Subject: [PATCH 067/690] Split the NE1000 and NE2000 into the Novell and Compatible versions, with I/O base address and IRQ selections per the Windows 95 .INF file, and added the D-Link DL-220P ISA PnP NE2000 clone. --- src/include/86box/net_ne2000.h | 18 +- src/network/net_ne2000.c | 294 ++++++++++++++++++++++++++++++--- src/network/network.c | 3 + 3 files changed, 283 insertions(+), 32 deletions(-) diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index 350668ccb..907f1e9c1 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -37,18 +37,24 @@ #define NET_NE2000_H enum { - NE2K_NONE = 0, - NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ - NE2K_NE2000 = 2, /* 16-bit ISA NE2000 */ - NE2K_ETHERNEXT_MC = 3, /* 16-bit MCA EtherNext/MC */ - NE2K_RTL8019AS = 4, /* 16-bit ISA PnP Realtek 8019AS */ - NE2K_RTL8029AS = 5 /* 32-bit PCI Realtek 8029AS */ + NE2K_NONE = 0, + NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ + NE2K_NE1000_COMPAT = 2, /* 16-bit ISA NE2000-Compatible */ + NE2K_NE2000 = 3, /* 16-bit ISA NE2000 */ + NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ + NE2K_ETHERNEXT_MC = 5, /* 16-bit MCA EtherNext/MC */ + NE2K_RTL8019AS = 6, /* 16-bit ISA PnP Realtek 8019AS */ + NE2K_DE220P = 7, /* 16-bit ISA PnP D-Link DE-220P */ + NE2K_RTL8029AS = 8 /* 32-bit PCI Realtek 8029AS */ }; extern const device_t ne1000_device; +extern const device_t ne1000_compat_device; extern const device_t ne2000_device; +extern const device_t ne2000_compat_device; extern const device_t ethernext_mc_device; extern const device_t rtl8019as_device; +extern const device_t de220p_device; extern const device_t rtl8029as_device; #endif /*NET_NE2000_H*/ diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index c7fba404f..03327ac0c 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -82,19 +82,6 @@ #define PCI_DEVID 0x8029 /* RTL8029AS */ #define PCI_REGSIZE 256 /* size of PCI space */ -static uint8_t rtl8019as_pnp_rom[] = { - 0x4a, 0x8c, 0x80, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* RTL8019, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x22, 0x00, 'R', 'E', 'A', 'L', 'T', 'E', 'K', ' ', 'P', 'L', 'U', 'G', ' ', '&', ' ', 'P', 'L', 'A', 'Y', ' ', 'E', 'T', 'H', 'E', 'R', 'N', 'E', 'T', ' ', 'C', 'A', 'R', 'D', 0x00, /* ANSI identifier */ - - 0x16, 0x4a, 0x8c, 0x80, 0x19, 0x02, 0x00, /* logical device RTL8019 */ - 0x1c, 0x41, 0xd0, 0x80, 0xd6, /* compatible device PNP80D6 */ - 0x47, 0x00, 0x20, 0x02, 0x80, 0x03, 0x20, 0x20, /* I/O 0x220-0x380, decodes 10-bit, 32-byte alignment, 32 addresses */ - 0x23, 0x38, 0x9e, 0x01, /* IRQ 3/4/5/9/10/11/12/15, high true edge sensitive */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ -}; - typedef struct nic_t { dp8390_t *dp8390; @@ -947,7 +934,7 @@ nic_init(const device_t *info) if (dev->board != NE2K_ETHERNEXT_MC) { dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); - if (dev->board == NE2K_NE2000) { + if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT)) { dev->bios_addr = device_get_config_hex20("bios_addr"); dev->has_bios = !!dev->bios_addr; } else { @@ -993,6 +980,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); break; + case NE2K_NE1000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + dev->is_8bit = 1; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); + break; + case NE2K_NE2000: dev->maclocal[0] = 0x00; /* 00:00:D8 (Novell OID) */ dev->maclocal[1] = 0x00; @@ -1002,6 +999,15 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_NE2000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + rom = ROM_PATH_NE2000; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); + break; + case NE2K_ETHERNEXT_MC: dev->maclocal[0] = 0x00; /* 00:00:D8 (Networth Inc. OID) */ dev->maclocal[1] = 0x00; @@ -1013,6 +1019,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_DE220P: + dev->maclocal[0] = 0x00; /* 00:80:C8 (D-Link OID) */ + dev->maclocal[1] = 0x80; + dev->maclocal[2] = 0xC8; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CLEAR_IRQ); + dp8390_set_id(dev->dp8390, 0x50, 0x70); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); + break; + case NE2K_RTL8019AS: case NE2K_RTL8029AS: dev->is_pci = (dev->board == NE2K_RTL8029AS) ? 1 : 0; @@ -1043,7 +1059,7 @@ nic_init(const device_t *info) * Make this device known to the I/O system. * PnP and PCI devices start with address spaces inactive. */ - if (dev->board < NE2K_RTL8019AS && dev->board != NE2K_ETHERNEXT_MC) + if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC)) nic_ioset(dev, dev->base_address); /* Set up our BIOS ROM space, if any. */ @@ -1108,9 +1124,44 @@ nic_init(const device_t *info) dev->eeprom[0x78] = dev->eeprom[0x7C] = (PCI_VENDID & 0xff); dev->eeprom[0x79] = dev->eeprom[0x7D] = (PCI_VENDID >> 8); } else { - memcpy(&dev->eeprom[0x12], rtl8019as_pnp_rom, sizeof(rtl8019as_pnp_rom)); + const char *pnp_rom_file = NULL; + int pnp_rom_len = 0x4a; + switch (dev->board) { + case NE2K_RTL8019AS: + pnp_rom_file = "roms/network/rtl8019as/RTL8019A.BIN"; + break; - dev->pnp_card = isapnp_add_card(&dev->eeprom[0x12], sizeof(rtl8019as_pnp_rom), nic_pnp_config_changed, nic_pnp_csn_changed, nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, dev); + case NE2K_DE220P: + pnp_rom_file = "roms/network/de220p/dlk2201a.bin"; + pnp_rom_len = 0x43; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(&dev->eeprom[0x12], 1, pnp_rom_len, fp) == pnp_rom_len) + pnp_rom = &dev->eeprom[0x12]; + fclose(fp); + } + } + + switch (info->local) { + case NE2K_RTL8019AS: + case NE2K_DE220P: + dev->pnp_card = isapnp_add_card(pnp_rom, pnp_rom_len, + nic_pnp_config_changed, nic_pnp_csn_changed, + nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, + dev); + break; + + default: + break; + } } } @@ -1137,6 +1188,18 @@ nic_close(void *priv) free(dev); } +static int +rtl8019as_available(void) +{ + return rom_present("roms/network/rtl8019as/RTL8019A.BIN"); +} + +static int +de220p_available(void) +{ + return rom_present("roms/network/de220p/dlk2201a.bin"); +} + // clang-format off static const device_config_t ne1000_config[] = { { @@ -1148,12 +1211,11 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "0x280", .value = 0x280 }, + /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, - { .description = "0x380", .value = 0x380 }, { .description = "" } }, }, @@ -1166,12 +1228,71 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne1000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, - { .description = "IRQ 10", .value = 10 }, - { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 9", .value = 9 }, { .description = "" } }, }, @@ -1195,12 +1316,11 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "0x280", .value = 0x280 }, + /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, - { .description = "0x380", .value = 0x380 }, { .description = "" } }, }, @@ -1213,12 +1333,92 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0x00000 }, + { .description = "D000", .value = 0xD0000 }, + { .description = "D800", .value = 0xD8000 }, + { .description = "C800", .value = 0xC8000 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne2000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 10, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file - not giving impossible IRQ's + such as 6, 8, or 13. */ + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 14", .value = 14 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -1291,7 +1491,7 @@ static const device_config_t mca_mac_config[] = { const device_t ne1000_device = { .name = "Novell NE1000", - .internal_name = "ne1k", + .internal_name = "novell_ne1k", .flags = DEVICE_ISA, .local = NE2K_NE1000, .init = nic_init, @@ -1303,9 +1503,23 @@ const device_t ne1000_device = { .config = ne1000_config }; +const device_t ne1000_compat_device = { + .name = "NE1000 Compatible", + .internal_name = "ne1k", + .flags = DEVICE_ISA, + .local = NE2K_NE1000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne1000_compat_config +}; + const device_t ne2000_device = { .name = "Novell NE2000", - .internal_name = "ne2k", + .internal_name = "novell_ne2k", .flags = DEVICE_ISA | DEVICE_AT, .local = NE2K_NE2000, .init = nic_init, @@ -1317,6 +1531,20 @@ const device_t ne2000_device = { .config = ne2000_config }; +const device_t ne2000_compat_device = { + .name = "NE2000 Compatible", + .internal_name = "ne2k", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_NE2000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne2000_compat_config +}; + const device_t ethernext_mc_device = { .name = "NetWorth EtherNext/MC", .internal_name = "ethernextmc", @@ -1339,7 +1567,21 @@ const device_t rtl8019as_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + { .available = rtl8019as_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rtl8019as_config +}; + +const device_t de220p_device = { + .name = "D-Link DE-220P", + .internal_name = "de220p", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_DE220P, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = de220p_available }, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8019as_config diff --git a/src/network/network.c b/src/network/network.c index 4d11ba955..6b3a9fd1c 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -117,6 +117,9 @@ static const device_t *net_cards[] = { &threec503_device, &pcnet_am79c960_device, &pcnet_am79c961_device, + &de220p_device, + &ne1000_compat_device, + &ne2000_compat_device, &ne1000_device, &ne2000_device, &pcnet_am79c960_eb_device, From 18adcb8e0e37515e47bcb17bca6a72be5abc8a6a Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Sat, 10 Feb 2024 11:57:40 +0200 Subject: [PATCH 068/690] Add files via upload --- src/machine/machine_table.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 13a5d5452..24fa879bc 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2579,7 +2579,7 @@ const machine_t machines[] = { .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, .ram = { .min = 512, - .max = 16384, + .max = 15360, .step = 512 }, .nvrmask = 63, @@ -2729,8 +2729,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2740,8 +2740,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 640, - .max = 16384, - .step = 128 + .max = 14912, + .step = 64 }, .nvrmask = 127, .kbc_device = NULL, @@ -3093,8 +3093,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -3504,7 +3504,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, @@ -3544,7 +3544,7 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, @@ -3704,7 +3704,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, From 9b4f98cb044befc1f2831d3c7596d9c590c91662 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 11 Feb 2024 11:07:58 +0600 Subject: [PATCH 069/690] Rewritten monochrome source data handling, partially fixes text drawing under Windows 98 SE --- src/video/vid_c&t_69000.c | 334 ++++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 174 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 9968e5205..2935b7085 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -136,13 +136,12 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint8_t bytes_skip; + uint8_t mono_bytes_skip; + uint8_t mono_bits_skip_left; + uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; uint8_t bytes_port[8]; - - /* Monochrome sources. */ - uint8_t mono_is_first_quadword; - uint8_t mono_bit_cntr; } bitblt_running; union { @@ -933,6 +932,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) ? chips->bitblt_running.bitblt.source_key_bg : chips->bitblt_running.bitblt.pattern_source_key_bg; color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + dest_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { return; @@ -966,81 +966,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } void -chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) +chips_69000_process_mono_bit(chips_69000_t* chips, uint8_t val) { - uint64_t i = 0; - uint8_t is_true = 0; - int orig_x = chips->bitblt_running.x; - int orig_y = chips->bitblt_running.y; - uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; - uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; - - int orig_count_x = chips->bitblt_running.count_x; - int orig_count_y = chips->bitblt_running.count_y; - - chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; - - if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { - source_fg = chips->bitblt_running.bitblt.source_key_fg; - source_bg = chips->bitblt_running.bitblt.source_key_bg; - } - - for (i = 0; i < 64; i++) { - uint32_t pixel = 0x0; - if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) - goto increment; - - if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) - goto increment; - - if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) - goto increment; - - is_true = !!(val & (1 << (i))); - - if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { - goto increment; - } - - pixel = is_true ? source_fg : source_bg; - pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - - chips->bitblt_running.x = orig_x + (chips->bitblt_running.count_x); - chips->bitblt_running.y = orig_y + chips->bitblt_running.count_y; - - if ((orig_count_x + (chips->bitblt_running.count_x)) < chips->bitblt_running.actual_destination_width - && (orig_count_y + chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height) - chips_69000_process_pixel(chips, pixel); - -increment: - chips->bitblt_running.count_x++; - if (chips->bitblt_running.count_x == 8) { - chips->bitblt_running.count_x = 0; - chips->bitblt_running.count_y++; - } - } - chips->bitblt_running.x = orig_x; - chips->bitblt_running.y = orig_y; - chips->bitblt_running.count_x = orig_count_x; - chips->bitblt_running.count_y = orig_count_y; - chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; - chips->bitblt_running.count_x += 8; - chips->bitblt_running.mono_is_first_quadword = 0; - if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { - chips->bitblt_running.count_y += 8; - chips->bitblt_running.y += chips->bitblt_running.y_dir * 8; - chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) - chips_69000_bitblt_interrupt(chips); - } -} - -void -chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t val) -{ - uint64_t i = 0; - uint8_t is_true = 0; - int orig_x = chips->bitblt_running.x; + uint32_t pixel = 0x0; + uint8_t is_true = !!val; uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; @@ -1049,46 +978,35 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va source_bg = chips->bitblt_running.bitblt.source_key_bg; } - for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { - uint32_t pixel = 0x0; - - if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) - continue; - - if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) - continue; - - if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) - continue; - - is_true = !!(val & (1 << (7 - (i & 7)))); - - if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { - continue; - } - - pixel = is_true ? source_fg : source_bg; - pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - - chips->bitblt_running.x = (orig_x + (i & 7) * chips->bitblt_running.x_dir); - - if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) - chips_69000_process_pixel(chips, pixel); + if (chips->bitblt_running.bitblt.monochrome_source_initial_discard) { + chips->bitblt_running.bitblt.monochrome_source_initial_discard--; + return; } - chips->bitblt_running.mono_bit_cntr += 8; - chips->bitblt_running.x = orig_x; - chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; - chips->bitblt_running.count_x += 8; - if (chips->bitblt_running.mono_bit_cntr >= 64) { - chips->bitblt_running.mono_is_first_quadword = 0; - chips->bitblt_running.mono_bit_cntr = 0; + + if (chips->bitblt_running.mono_bits_skip_left) { + chips->bitblt_running.mono_bits_skip_left--; + return; } + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + goto advance; + } + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips_69000_process_pixel(chips, pixel); + +advance: + chips->bitblt_running.x += chips->bitblt_running.x_dir; + chips->bitblt_running.count_x += 1; if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { chips->bitblt_running.count_y += 1; chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; - if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) + chips->bitblt_running.mono_bytes_to_skip = chips->bitblt_running.mono_bytes_skip; + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + if (chips->bitblt_running.count_y >= (chips->bitblt_running.actual_destination_height)) chips_69000_bitblt_interrupt(chips); } } @@ -1099,18 +1017,25 @@ void chips_69000_setup_bitblt(chips_69000_t* chips) { chips->engine_active = 1; + + memset(&chips->bitblt_running, 0, sizeof(chips->bitblt_running)); + chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; chips->bitblt_running.bytes_counter = 0; - chips->bitblt_running.mono_is_first_quadword = 1; - chips->bitblt_running.mono_bit_cntr = 0; chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; + chips->bitblt_running.mono_bytes_skip = 0; + chips->bitblt_running.mono_bytes_to_skip = 0; + chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; + if (chips->bitblt_running.bitblt.source_span != chips->bitblt_running.bitblt.destination_span) + pclog("source_span = %d, destination_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); } else { @@ -1152,6 +1077,19 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_bitblt_interrupt(chips); return; } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " + "monochrome left clip = %d, " + "monochrome right clip = %d, " + "monochrome initial discard = %d, " + "destination_width = %d, destination_height = %d)\n", chips->bitblt_running.bitblt.monochrome_source_alignment, + chips->bitblt_running.bitblt.monochrome_source_left_clip, + chips->bitblt_running.bitblt.monochrome_source_right_clip, + chips->bitblt_running.bitblt.monochrome_source_initial_discard, + chips->bitblt_running.bitblt.destination_width, + chips->bitblt_running.bitblt.destination_height); + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { @@ -1160,26 +1098,18 @@ chips_69000_setup_bitblt(chips_69000_t* chips) */ if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); + } else { + chips->bitblt_running.mono_bytes_skip = (chips->bitblt_running.actual_destination_width <= 32 + && chips->bitblt_running.bitblt.monochrome_source_alignment == 0 + && chips->bitblt_running.actual_destination_width > 16) ? 4 : 0; + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; } + return; } - - if (chips->bitblt_running.x_dir == -1 && chips->bitblt_running.bytes_per_pixel == 3) { - //chips->bitblt_running.actual_destination_width++; - } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; - pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " - "monochrome left clip = %d, " - "monochrome right clip = %d, " - "monochrome initial discard = %d, " - "destination_width = %d, destination_height = %d\n", chips->bitblt_running.bitblt.monochrome_source_alignment, - chips->bitblt_running.bitblt.monochrome_source_left_clip, - chips->bitblt_running.bitblt.monochrome_source_right_clip, - chips->bitblt_running.bitblt.monochrome_source_initial_discard, - chips->bitblt_running.bitblt.destination_width, - chips->bitblt_running.bitblt.destination_height); while (chips->engine_active) { switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { @@ -1200,6 +1130,13 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.source_addr = source_addr; break; } + case 2: /* Byte-aligned */ + { + uint32_t data = chips_69000_readb_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + source_addr += 1; + break; + } case 4: /* Doubleword-aligned*/ { uint32_t data = chips_69000_readl_linear(source_addr, chips); @@ -1226,6 +1163,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } } } + return; } do { @@ -1276,54 +1214,75 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; + if (chips->bitblt_running.mono_bytes_to_skip) { + chips->bitblt_running.mono_bytes_to_skip--; + return; + } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint8_t val = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 && chips->bitblt_running.bytes_written == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint16_t val = (chips->bitblt_running.bytes_port[1]) | (chips->bitblt_running.bytes_port[0] << 8); chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + + for (i = 0; i < 16; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (15 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 && chips->bitblt_running.bytes_written == 4) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint32_t val = chips->bitblt_running.bytes_port[3] | (chips->bitblt_running.bytes_port[2] << 8) | (chips->bitblt_running.bytes_port[1] << 16) | (chips->bitblt_running.bytes_port[0] << 24); chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); - if (chips->bitblt_running.actual_destination_width > 16) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); - if (chips->bitblt_running.actual_destination_width > 24) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + + for (i = 0; i < 32; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (31 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5 && chips->bitblt_running.bytes_written == 8) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint64_t val = 0; + + val |= chips->bitblt_running.bytes_port[7]; + val |= chips->bitblt_running.bytes_port[6] << 8; + val |= chips->bitblt_running.bytes_port[5] << 16; + val |= chips->bitblt_running.bytes_port[4] << 24; + val |= (uint64_t)chips->bitblt_running.bytes_port[3] << 32ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[2] << 40ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[1] << 48ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[0] << 56ULL; + chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); - if (chips->bitblt_running.actual_destination_width > 16) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); - if (chips->bitblt_running.actual_destination_width > 24) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); - if (chips->bitblt_running.actual_destination_width > 32) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[4]); - if (chips->bitblt_running.actual_destination_width > 40) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[5]); - if (chips->bitblt_running.actual_destination_width > 48) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[6]); - if (chips->bitblt_running.actual_destination_width > 52) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[7]); - } else if (chips->bitblt_running.bytes_written == 8) { - chips->bitblt_running.bytes_written = 0; - uint64_t mono_data = chips->bitblt_running.bytes_port[0]; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[1] << 8ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[2] << 16ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[3] << 24ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[4] << 32ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[5] << 40ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[6] << 48ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; - chips_69000_process_mono_data(chips, mono_data); + + for (i = 0; i < 64; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (63 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } cycles = orig_cycles; return; @@ -1433,18 +1392,12 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val |= 1; break; } - // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1658,9 +1611,11 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) } } break; + case 0x3B6: case 0x3D6: chips->ext_index = val; return; + case 0x3B7: case 0x3D7: return chips_69000_write_ext_reg(chips, val); @@ -1732,9 +1687,11 @@ chips_69000_in(uint16_t addr, void *p) else temp = svga->crtc[svga->crtcreg]; break; + case 0x3B6: case 0x3D6: temp = chips->ext_index; break; + case 0x3B7: case 0x3D7: temp = chips_69000_read_ext_reg(chips); break; @@ -1876,7 +1833,6 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { - //pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1884,6 +1840,10 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } return chips->bitblt_regs_b[addr & 0xFF]; + case 0x3b: + return (chips->engine_active ? 0x80 : 0x00); + case 0x38: + return (0xFF - chips->ext_regs[0xD2]); case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; case 0x768: @@ -1937,7 +1897,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) case 0x7B4: return chips_69000_in(0x3da, chips); } - return 0xFF; + return 0x00; } uint16_t @@ -1978,6 +1938,9 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) chips_69000_setup_bitblt(chips); } break; + default: + pclog("C&T Write (unknown) 0x%X, val = 0x%02X\n", addr, val); + break; case 0x600 ... 0x60F: switch (addr & 0xFFF) { @@ -2065,6 +2028,9 @@ void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { if (addr & 0x10000) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + pclog("BitBLT mono 0x%04X\n", val); + } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); return; @@ -2083,7 +2049,7 @@ chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - //pclog("BitBLT mono 0x%08X\n", val); + pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); @@ -2118,6 +2084,13 @@ chips_69000_readw_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap16(chips_69000_readw_mmio(addr, chips)); + + return bswap16(svga_readw_linear(addr & 0x1FFFFF, p)); + } + if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -2130,6 +2103,13 @@ chips_69000_readl_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap32(chips_69000_readl_mmio(addr, chips)); + + return bswap32(svga_readl_linear(addr & 0x1FFFFF, p)); + } + if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -2154,6 +2134,9 @@ chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) + val = bswap16(val); + if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -2166,6 +2149,9 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) + val = bswap32(val); + if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); From 376b704ceab0f2edd8326b18500831b99563fb3e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 12 Feb 2024 01:25:27 +0600 Subject: [PATCH 070/690] Fix 16+ bpp text background drawing --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 2935b7085..94b5750ce 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -141,7 +141,7 @@ typedef struct chips_69000_t { uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; - uint8_t bytes_port[8]; + uint8_t bytes_port[256]; } bitblt_running; union { @@ -1835,7 +1835,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { addr &= 0xFFF; switch (addr & 0xFFF) { - case 0x00 ... 0x28: + case 0x00 ... 0x2B: if (addr == 0x13) { return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } @@ -1932,7 +1932,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) } addr &= 0xFFF; switch (addr & 0xFFF) { - case 0x00 ... 0x28: + case 0x00 ... 0x2B: chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { chips_69000_setup_bitblt(chips); From a9a6c9c1219b209dc0d49bf0d557589810bb9aa4 Mon Sep 17 00:00:00 2001 From: JoshuaMaitland Date: Mon, 12 Feb 2024 18:10:18 +0000 Subject: [PATCH 071/690] Bumped the minimum ram to 8MB on ASUS P5A It would cause a hang in the BIOS if it's lower than 8MB --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 24fa879bc..8baf908e6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12265,7 +12265,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_AGP, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { - .min = 1024, + .min = 8192, .max = 1572864, .step = 8192 }, From 40d7e626fc94e2b47d362f6a38488a7798fe799f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:15:53 +0600 Subject: [PATCH 072/690] Fix monochrome blits for real --- src/video/vid_c&t_69000.c | 62 +++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 94b5750ce..697d7d19b 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -137,6 +137,7 @@ typedef struct chips_69000_t { uint8_t bytes_written; uint8_t bytes_skip; uint8_t mono_bytes_skip; + uint32_t mono_bytes_pitch; uint8_t mono_bits_skip_left; uint8_t mono_bytes_to_skip; uint32_t bytes_counter; @@ -973,6 +974,9 @@ chips_69000_process_mono_bit(chips_69000_t* chips, uint8_t val) uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + if (!chips->engine_active) + return; + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { source_fg = chips->bitblt_running.bitblt.source_key_fg; source_bg = chips->bitblt_running.bitblt.source_key_bg; @@ -1019,7 +1023,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->engine_active = 1; memset(&chips->bitblt_running, 0, sizeof(chips->bitblt_running)); - chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; @@ -1029,13 +1032,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; chips->bitblt_running.mono_bytes_skip = 0; + chips->bitblt_running.mono_bytes_pitch = 0; chips->bitblt_running.mono_bytes_to_skip = 0; chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; - if (chips->bitblt_running.bitblt.source_span != chips->bitblt_running.bitblt.destination_span) - pclog("source_span = %d, destination_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); - if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); } else { @@ -1055,7 +1056,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 1: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; - chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; case 2: @@ -1065,7 +1067,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 3: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; - chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; } @@ -1078,6 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } +#if 0 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " @@ -1090,6 +1094,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_width, chips->bitblt_running.bitblt.destination_height); } +#endif if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { @@ -1099,10 +1104,12 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } else { - chips->bitblt_running.mono_bytes_skip = (chips->bitblt_running.actual_destination_width <= 32 - && chips->bitblt_running.bitblt.monochrome_source_alignment == 0 - && chips->bitblt_running.actual_destination_width > 16) ? 4 : 0; + chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + + if (!chips->bitblt_running.mono_bytes_skip && chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; + } } return; @@ -1119,9 +1126,15 @@ chips_69000_setup_bitblt(chips_69000_t* chips) uint32_t orig_count_y = chips->bitblt_running.count_y; uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; while (orig_count_y == chips->bitblt_running.count_y) { + int i = 0; uint8_t data = chips_69000_readb_linear(orig_source_addr, chips); orig_source_addr++; - chips_69000_bitblt_write(chips, data & 0xFF); + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(data & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + break; + } + } if ((source_addr + chips->bitblt_running.bitblt.source_span) == orig_source_addr) break; } @@ -1219,7 +1232,23 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0, j = 0; + uint8_t val = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + + for (j = 0; j < chips->bitblt_running.mono_bytes_pitch; j++) { + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(chips->bitblt_running.bytes_port[j] & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } + } + else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; @@ -1289,7 +1318,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -1843,7 +1872,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) case 0x3b: return (chips->engine_active ? 0x80 : 0x00); case 0x38: - return (0xFF - chips->ext_regs[0xD2]); + return 0x7F; case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; case 0x768: @@ -1933,6 +1962,9 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x2B: + if (addr <= 0x3) { + //pclog("[%04X:%08X] C&T Write span 0x%X, val = 0x%02X\n", CS, cpu_state.pc, addr, val); + } chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { chips_69000_setup_bitblt(chips); @@ -2029,7 +2061,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("BitBLT mono 0x%04X\n", val); + //pclog("BitBLT mono 0x%04X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); @@ -2049,7 +2081,7 @@ chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("BitBLT mono 0x%08X\n", val); + //pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); From 62135c5c8a4096d1f4feeb93b29094b5576d5560 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:28:14 +0600 Subject: [PATCH 073/690] Minor cleanup --- src/video/vid_c&t_69000.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 697d7d19b..973502f55 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -136,10 +136,8 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint8_t bytes_skip; - uint8_t mono_bytes_skip; uint32_t mono_bytes_pitch; uint8_t mono_bits_skip_left; - uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; uint8_t bytes_port[256]; @@ -1008,7 +1006,6 @@ advance: chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; - chips->bitblt_running.mono_bytes_to_skip = chips->bitblt_running.mono_bytes_skip; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; if (chips->bitblt_running.count_y >= (chips->bitblt_running.actual_destination_height)) chips_69000_bitblt_interrupt(chips); @@ -1031,9 +1028,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; - chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bytes_pitch = 0; - chips->bitblt_running.mono_bytes_to_skip = 0; chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; @@ -1104,10 +1099,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } else { - chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; - if (!chips->bitblt_running.mono_bytes_skip && chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; } } @@ -1227,10 +1221,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; - if (chips->bitblt_running.mono_bytes_to_skip) { - chips->bitblt_running.mono_bytes_to_skip--; - return; - } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; From 6e35d009420739e2acd29c5f77fa55dd1ef758c4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:49:43 +0600 Subject: [PATCH 074/690] Gamma correction support --- src/video/vid_c&t_69000.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 973502f55..6f41ba2df 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -752,6 +752,9 @@ chips_69000_recalctimings(svga_t *svga) } switch (chips->ext_regs[0x81] & 0xF) { + default: + svga->bpp = 8; + break; case 0b0010: svga->bpp = 8; svga->render = svga_render_8bpp_highres; @@ -1479,6 +1482,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0x82: + chips->ext_regs[chips->ext_index] = val & 0xf; + chips->svga.lut_map = !!(val & 0x8); + break; case 0xA0: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); From afa545ca25f164ba6ccffb271306b4791d441288 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:57:54 +0600 Subject: [PATCH 075/690] Bit-depth fixes --- src/video/vid_c&t_69000.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 6f41ba2df..273c5de5c 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -777,6 +777,8 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } + } else { + svga->bpp = 8; } } From fd33034915f36824d6d5c7ea60d9dc6c04895077 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 11:42:15 +0600 Subject: [PATCH 076/690] 1600x1200 resolution fixes Fix source address behaviour properly --- src/video/vid_c&t_69000.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 273c5de5c..0118bcd1f 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -15,6 +15,7 @@ * Copyright 2023-2024 Cacodemon345 */ #include +#include #include #include #include @@ -90,8 +91,8 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; - atomic_bool engine_active; - atomic_bool quit; + bool engine_active; + bool quit; thread_t *accel_thread; event_t *fifo_event, *fifo_data_event; pc_timer_t decrement_timer; @@ -1095,8 +1096,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); } #endif - + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + chips->bitblt_running.bitblt.source_addr &= 7; if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { /* Yes, the NT 4.0 and Linux drivers will send this many amount of bytes to the video adapter on quadword-boundary-crossing image blits. This weird calculation is intended and deliberate. @@ -1121,6 +1123,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { case 0: /* Source-span aligned. */ { + /* Note: This value means quadword-alignment when BitBLT port is the source. */ /* TODO: This is handled purely on a best case basis. */ uint32_t orig_count_y = chips->bitblt_running.count_y; uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; @@ -1142,6 +1145,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.source_addr = source_addr; break; } + case 1: /* Bit-aligned */ case 2: /* Byte-aligned */ { uint32_t data = chips_69000_readb_linear(source_addr, chips); @@ -1149,6 +1153,14 @@ chips_69000_setup_bitblt(chips_69000_t* chips) source_addr += 1; break; } + case 3: /* Word-aligned*/ + { + uint32_t data = chips_69000_readw_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + source_addr += 2; + break; + } case 4: /* Doubleword-aligned*/ { uint32_t data = chips_69000_readl_linear(source_addr, chips); @@ -1243,7 +1255,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } } } - else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) + || chips->bitblt_running.bitblt.monochrome_source_alignment == 2 + || chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; @@ -1251,7 +1265,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { for (i = 0; i < 8; i++) { chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); - if (orig_count_y != chips->bitblt_running.count_y) { + if (orig_count_y != chips->bitblt_running.count_y && chips->bitblt_running.bitblt.monochrome_source_alignment != 1) { cycles = orig_cycles; return; } @@ -1313,7 +1327,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) { + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -2308,6 +2322,16 @@ chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) return ret; } +static int +chips_69000_line_compare(svga_t* svga) +{ + /* Line compare glitches out at 1600x1200 and above. Disable it. */ + if (svga->dispend >= 1200) + return 0; + + return 1; +} + static void * chips_69000_init(const device_t *info) { @@ -2338,6 +2362,7 @@ chips_69000_init(const device_t *info) chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; chips->svga.getclock = chips_69000_getclock; chips->svga.conv_16to32 = chips_69000_conv_16to32; + chips->svga.line_compare = chips_69000_line_compare; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From b95139033c77702814ae0c3e99c37eed87df3284 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 11:45:28 +0600 Subject: [PATCH 077/690] Timing and name changes --- src/video/vid_c&t_69000.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 0118bcd1f..bbf1cfb3a 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -161,7 +161,8 @@ typedef struct chips_69000_t { uint8_t st01; } chips_69000_t; -static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +/* TODO: Probe timings on real hardware. */ +static video_timings_t timing_chips = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; uint8_t chips_69000_readb_linear(uint32_t addr, void *p); uint16_t chips_69000_readw_linear(uint32_t addr, void *p); @@ -1567,7 +1568,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA out: 0x%X, 0x%X\n", addr, val); switch (addr) { case 0x3c0: if (!(chips->ext_regs[0x09] & 0x02)) @@ -1675,7 +1675,6 @@ chips_69000_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA in: 0x%X\n", addr); switch (addr) { case 0x3C5: return svga->seqregs[svga->seqaddr]; @@ -2343,7 +2342,7 @@ chips_69000_init(const device_t *info) mem_mapping_disable(&chips->bios_rom.mapping); } - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_chips); svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ chips_69000_recalctimings, @@ -2421,7 +2420,7 @@ chips_69000_force_redraw(void *p) } const device_t chips_69000_device = { - .name = "Chips & Technologies 69000", + .name = "Chips & Technologies B69000", .internal_name = "c&t_69000", .flags = DEVICE_PCI, .local = 0, @@ -2435,7 +2434,7 @@ const device_t chips_69000_device = { }; const device_t chips_69000_onboard_device = { - .name = "Chips & Technologies 69000 (onboard)", + .name = "Chips & Technologies B69000 (onboard)", .internal_name = "c&t_69000_onboard", .flags = DEVICE_PCI, .local = 1, From baac839d892bfd7dea0fa0c14734f00d0f10bdae Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:04:53 +0600 Subject: [PATCH 078/690] Unused variables cleanup --- src/video/vid_c&t_69000.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index bbf1cfb3a..b15546a69 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -820,8 +820,6 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint32_t pattern_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t pattern_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; uint8_t pattern_data = 0; - uint8_t pattern_data_8bpp[8][8]; - uint16_t pattern_data_16bpp[8][8]; uint32_t pattern_pixel = 0; uint32_t dest_pixel = 0; uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); @@ -1243,7 +1241,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; int i = 0, j = 0; - uint8_t val = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; for (j = 0; j < chips->bitblt_running.mono_bytes_pitch; j++) { From 8ed622f67b681fe08b864609c772785e64bdda97 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:06:10 +0600 Subject: [PATCH 079/690] Move extern into video.h (part 1) --- src/include/86box/video.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 9e15a5cf9..47d237b10 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -579,6 +579,7 @@ extern const device_t wy700_device; /* Chips & Technologies */ extern const device_t chips_69000_device; +extern const device_t chips_69000_onboard_device; #endif From 49ab582234bb3589c1d3f9fee05547e154bfcc43 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:07:19 +0600 Subject: [PATCH 080/690] Move extern into video.h (part 2) --- src/machine/m_at_socket370.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 8344e6b8f..dce0034ff 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -355,7 +355,6 @@ machine_at_awo671r_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); if (gfxcard[0] == VID_INTERNAL) { - extern const device_t chips_69000_onboard_device; device_add(&chips_69000_onboard_device); } spd_register(SPD_TYPE_SDRAM, 0x3, 256); From 5acec5dfa42fcf7629645644892e2610424ebb43 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 18:40:07 +0500 Subject: [PATCH 081/690] qt: Remove the Direct3D 9 renderer --- src/qt/CMakeLists.txt | 3 +- src/qt/qt.c | 7 +- src/qt/qt_d3d9renderer.cpp | 200 ----------------------------------- src/qt/qt_d3d9renderer.hpp | 45 -------- src/qt/qt_main.cpp | 2 +- src/qt/qt_mainwindow.cpp | 29 +---- src/qt/qt_mainwindow.hpp | 2 - src/qt/qt_mainwindow.ui | 12 --- src/qt/qt_renderercommon.hpp | 3 - src/qt/qt_rendererstack.cpp | 95 ++--------------- src/qt/qt_rendererstack.hpp | 9 +- 11 files changed, 18 insertions(+), 389 deletions(-) delete mode 100644 src/qt/qt_d3d9renderer.cpp delete mode 100644 src/qt/qt_d3d9renderer.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index fb96de1ea..4f073cf4a 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -197,8 +197,7 @@ if(WIN32) else() target_sources(plat PRIVATE win_joystick_rawinput.c) endif() - target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp) - target_link_libraries(86Box hid d3d9) + target_link_libraries(86Box hid) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 diff --git a/src/qt/qt.c b/src/qt/qt.c index c2a5396da..47f5b9410 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -52,10 +52,8 @@ plat_vidapi(char *api) return 3; } else if (!strcasecmp(api, "qt_vulkan")) { return 4; - } else if (!strcasecmp(api, "qt_d3d9")) { - return 5; } else if (!strcasecmp(api, "vnc")) { - return 6; + return 5; } return 0; @@ -83,9 +81,6 @@ plat_vidapi_name(int api) name = "qt_vulkan"; break; case 5: - name = "qt_d3d9"; - break; - case 6: name = "vnc"; break; default: diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp deleted file mode 100644 index 868f58274..000000000 --- a/src/qt/qt_d3d9renderer.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include "qt_mainwindow.hpp" -#include "qt_d3d9renderer.hpp" -#include -#include - -extern "C" { -#include <86box/86box.h> -#include <86box/video.h> -} - -D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) - : QWidget { parent } - , RendererCommon() -{ - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::black); - setAutoFillBackground(true); - setPalette(pal); - - setAttribute(Qt::WA_NativeWindow); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_OpaquePaintEvent); - - windowHandle = (HWND) winId(); - surfaceInUse = true; - finalized = true; - - RendererCommon::parentWidget = parent; - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->m_monitor_index = monitor_index; - - d3d9surface = nullptr; - d3d9dev = nullptr; - d3d9 = nullptr; -} - -D3D9Renderer::~D3D9Renderer() -{ - finalize(); -} - -void -D3D9Renderer::finalize() -{ - if (!finalized) { - while (surfaceInUse) { } - finalized = true; - } - surfaceInUse = true; - if (d3d9surface) { - d3d9surface->Release(); - d3d9surface = nullptr; - } - if (d3d9dev) { - d3d9dev->Release(); - d3d9dev = nullptr; - } - if (d3d9) { - d3d9->Release(); - d3d9 = nullptr; - } -} - -void -D3D9Renderer::hideEvent(QHideEvent *event) -{ - finalize(); -} - -void -D3D9Renderer::showEvent(QShowEvent *event) -{ - if (d3d9) finalize(); - params = {}; - - if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) { - return error("Failed to create Direct3D 9 context"); - } - - params.Windowed = true; - params.SwapEffect = D3DSWAPEFFECT_FLIPEX; - params.BackBufferWidth = width() * devicePixelRatioF(); - params.BackBufferHeight = height() * devicePixelRatioF(); - params.BackBufferCount = 1; - params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - params.hDeviceWindow = (HWND) winId(); - - HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) - result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 device"); - } - - result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) - result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 surface"); - } - if (!alreadyInitialized) { - emit initialized(); - alreadyInitialized = true; - } - surfaceInUse = false; - finalized = false; -} - -void -D3D9Renderer::paintEvent(QPaintEvent *event) -{ - IDirect3DSurface9 *backbuffer = nullptr; - RECT srcRect; - RECT dstRect; - HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - - if (FAILED(result)) { - return; - } - - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - dstRect.top = destination.top() * devicePixelRatioF(); - dstRect.bottom = destination.bottom() * devicePixelRatioF(); - dstRect.left = destination.left() * devicePixelRatioF(); - dstRect.right = destination.right() * devicePixelRatioF(); - d3d9dev->BeginScene(); - d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); - while (surfaceInUse) { } - surfaceInUse = true; - d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR); - result = d3d9dev->EndScene(); - surfaceInUse = false; - if (SUCCEEDED(result)) { - if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) { - finalize(); - showEvent(nullptr); - } - } -} - -bool -D3D9Renderer::event(QEvent *event) -{ - bool res = false; - if (!eventDelegate(event, res)) - return QWidget::event(event); - return res; -} - -void -D3D9Renderer::resizeEvent(QResizeEvent *event) -{ - onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF()); - - params.BackBufferWidth = event->size().width() * devicePixelRatioF(); - params.BackBufferHeight = event->size().height() * devicePixelRatioF(); - if (d3d9dev) - d3d9dev->Reset(¶ms); - QWidget::resizeEvent(event); -} - -void -D3D9Renderer::blit(int x, int y, int w, int h) -{ - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { - video_blit_complete_monitor(m_monitor_index); - return; - } - surfaceInUse = true; - auto origSource = source; - source.setRect(x, y, w, h); - RECT srcRect; - D3DLOCKED_RECT lockRect; - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - - if (monitors[m_monitor_index].mon_screenshots) { - video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index); - } - if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) { - for (int y1 = 0; y1 < h; y1++) { - video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); - } - video_blit_complete_monitor(m_monitor_index); - d3d9surface->UnlockRect(); - } else - video_blit_complete_monitor(m_monitor_index); - if (origSource != source) - onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); - surfaceInUse = false; - QTimer::singleShot(0, this, [this] { this->update(); }); -} diff --git a/src/qt/qt_d3d9renderer.hpp b/src/qt/qt_d3d9renderer.hpp deleted file mode 100644 index 37c27443b..000000000 --- a/src/qt/qt_d3d9renderer.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef D3D9RENDERER_HPP -#define D3D9RENDERER_HPP - -#include -#include "qt_renderercommon.hpp" - -#include -#include -#include - -class D3D9Renderer : public QWidget, public RendererCommon { - Q_OBJECT -public: - explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0); - ~D3D9Renderer(); - bool hasBlitFunc() override { return true; } - void blit(int x, int y, int w, int h) override; - void finalize() override; - -protected: - void showEvent(QShowEvent *event) override; - void hideEvent(QHideEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; - bool event(QEvent *event) override; - QPaintEngine *paintEngine() const override { return nullptr; } - -signals: - void initialized(); - void error(QString); - -private: - HWND windowHandle = 0; - D3DPRESENT_PARAMETERS params {}; - IDirect3D9Ex *d3d9 = nullptr; - IDirect3DDevice9Ex *d3d9dev = nullptr; - IDirect3DSurface9 *d3d9surface = nullptr; - - std::atomic surfaceInUse { false }; - std::atomic finalized { false }; - bool alreadyInitialized = false; - int m_monitor_index = 0; -}; - -#endif // D3D9RENDERER_HPP diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 4d02e2601..cafd4fd8e 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -342,7 +342,7 @@ main(int argc, char *argv[]) /* Set the PAUSE mode depending on the renderer. */ #ifdef USE_VNC - if (vnc_enabled && vid_api != 6) + if (vnc_enabled && vid_api != 5) plat_pause(1); else #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index eb4634dee..ace052a32 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -157,8 +157,6 @@ keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) static BMessageFilter *filter; #endif -std::atomic blitDummied { false }; - extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); @@ -369,14 +367,9 @@ MainWindow::MainWindow(QWidget *parent) ui->actionVulkan->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false); } -#if !defined Q_OS_WINDOWS - ui->actionDirect3D_9->setVisible(false); - if (vid_api == 5) - vid_api = 0; -#endif #ifndef USE_VNC - if (vid_api == 6) + if (vid_api == 5) vid_api = 0; ui->actionVNC->setVisible(false); #endif @@ -410,14 +403,13 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); - actGroup->addAction(ui->actionDirect3D_9); actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC - if (vnc_enabled && vid_api != 6) { + if (vnc_enabled && vid_api != 5) { startblit(); vnc_enabled = 0; vnc_close(); @@ -442,11 +434,8 @@ MainWindow::MainWindow(QWidget *parent) case 4: newVidApi = RendererStack::Renderer::Vulkan; break; - case 5: - newVidApi = RendererStack::Renderer::Direct3D9; - break; #ifdef USE_VNC - case 6: + case 5: { newVidApi = RendererStack::Renderer::Software; startblit(); @@ -612,7 +601,7 @@ MainWindow::MainWindow(QWidget *parent) video_setblit(qt_blit); if (start_in_fullscreen) { - connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { + connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () { if (start_in_fullscreen) { QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); start_in_fullscreen = 0; @@ -1156,8 +1145,6 @@ MainWindow::on_actionFullscreen_triggered() { if (video_fullscreen > 0) { showNormal(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); ui->menubar->show(); if (!hide_status_bar) ui->statusbar->show(); @@ -1193,8 +1180,6 @@ MainWindow::on_actionFullscreen_triggered() ui->toolBar->hide(); ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); } ui->stackedWidget->onResize(width(), height()); } @@ -1316,7 +1301,7 @@ void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) + if (renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); else video_blit_complete_monitor(monitor_index); @@ -1976,8 +1961,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() { show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); - blitDummied = true; - if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { auto &secondaryRenderer = renderers[monitor_index]; @@ -2007,8 +1990,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() } } } - - blitDummied = false; } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 553f9602c..64a97f012 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -12,8 +12,6 @@ class MediaMenu; class RendererStack; -extern std::atomic blitDummied; - namespace Ui { class MainWindow; } diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index c14c33207..d77c8d171 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -117,7 +117,6 @@ - @@ -831,17 +830,6 @@ MCA devices... - - - true - - - Direct3D 9 - - - 5 - - true diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 897240d27..af72474c7 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -35,9 +35,6 @@ public: /* Reloads options of renderer */ virtual void reloadOptions() { } - virtual bool hasBlitFunc() { return false; } - virtual void blit(int x, int y, int w, int h) { } - int r_monitor_index = 0; protected: diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index e5ed77ba7..0f86e8ee6 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -25,9 +25,6 @@ #include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" -#ifdef Q_OS_WIN -# include "qt_d3d9renderer.hpp" -#endif #include "qt_mainwindow.hpp" #include "qt_util.hpp" @@ -279,40 +276,14 @@ RendererStack::switchRenderer(Renderer renderer) { startblit(); if (current) { - if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9) - || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { - rendererWindow->finalize(); - if (rendererWindow->hasBlitFunc()) { - while (directBlitting) { } - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon); - } + rendererWindow->finalize(); + removeWidget(current.get()); + disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); + /* Create new renderer only after previous is destroyed! */ + connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { - createRenderer(renderer); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); - blitDummied = false; - QTimer::singleShot(1000, this, []() { blitDummied = false; }); - }); - - rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); - } else { - rendererWindow->finalize(); - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); - - current.release()->deleteLater(); - } + current.release()->deleteLater(); } else { createRenderer(renderer); } @@ -321,7 +292,6 @@ RendererStack::switchRenderer(Renderer renderer) void RendererStack::createRenderer(Renderer renderer) { - current_vid_api = renderer; switch (renderer) { default: case Renderer::Software: @@ -374,27 +344,6 @@ RendererStack::createRenderer(Renderer renderer) current.reset(this->createWindowContainer(hw, this)); break; } -#ifdef Q_OS_WIN - case Renderer::Direct3D9: - { - this->createWinId(); - auto hw = new D3D9Renderer(this, m_monitor_index); - rendererWindow = hw; - connect(hw, &D3D9Renderer::error, this, [this](QString str) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - connect(hw, &D3D9Renderer::initialized, this, [this]() { - endblit(); - emit rendererChanged(); - }); - current.reset(hw); - break; - } -#endif #if QT_CONFIG(vulkan) case Renderer::Vulkan: { @@ -444,44 +393,18 @@ RendererStack::createRenderer(Renderer renderer) currentBuf = 0; - if (rendererWindow->hasBlitFunc()) { - connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection); - } - - if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) { + if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) { imagebufs = rendererWindow->getBuffers(); endblit(); emit rendererChanged(); } } -void -RendererStack::blitDummy(int x, int y, int w, int h) -{ - video_blit_complete_monitor(m_monitor_index); - blitDummied = true; -} - -void -RendererStack::blitRenderer(int x, int y, int w, int h) -{ - if (blitDummied) { - blitDummied = false; - video_blit_complete_monitor(m_monitor_index); - return; - } - directBlitting = true; - rendererWindow->blit(x, y, w, h); - directBlitting = false; -} - // called from blitter thread void -RendererStack::blitCommon(int x, int y, int w, int h) +RendererStack::blit(int x, int y, int w, int h) { - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index c9d90869b..5a08b351c 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -59,7 +59,6 @@ public: OpenGLES, OpenGL3, Vulkan, - Direct3D9, None = -1 }; void switchRenderer(Renderer renderer); @@ -81,13 +80,10 @@ public: signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); - void blit(int x, int y, int w, int h); void rendererChanged(); public slots: - void blitCommon(int x, int y, int w, int h); - void blitRenderer(int x, int y, int w, int h); - void blitDummy(int x, int y, int w, int h); + void blit(int x, int y, int w, int h); private: void createRenderer(Renderer renderer); @@ -107,13 +103,10 @@ private: int isMouseDown = 0; int m_monitor_index = 0; - Renderer current_vid_api = Renderer::None; - std::vector> imagebufs; RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting { false }; }; #endif // QT_RENDERERCONTAINER_HPP From 224daa92d0f32029cbc59bbd32eb9869bc3d7e79 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 21:13:25 +0500 Subject: [PATCH 082/690] qt: Remove fullscreen status icons --- src/config.c | 7 ----- src/include/86box/plat.h | 1 - src/qt/languages/ru-RU.po | 3 -- src/qt/qt_hardwarerenderer.cpp | 16 ----------- src/qt/qt_hardwarerenderer.hpp | 2 +- src/qt/qt_mainwindow.cpp | 9 ------ src/qt/qt_mainwindow.hpp | 1 - src/qt/qt_mainwindow.ui | 9 ------ src/qt/qt_renderercommon.cpp | 52 ---------------------------------- src/qt/qt_softwarerenderer.cpp | 2 -- src/unix/unix.c | 1 - src/win/win_ui.c | 2 -- 12 files changed, 1 insertion(+), 104 deletions(-) diff --git a/src/config.c b/src/config.c index f1807c316..3e4fd7222 100644 --- a/src/config.c +++ b/src/config.c @@ -139,8 +139,6 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); - status_icons_fullscreen = !!ini_section_get_int(cat, "status_icons_fullscreen", 0); - window_remember = ini_section_get_int(cat, "window_remember", 0); if (!window_remember && !(vid_resize & 2)) @@ -1859,11 +1857,6 @@ save_general(void) else ini_section_delete_var(cat, "open_dir_usr_path"); - if (status_icons_fullscreen) - ini_section_set_int(cat, "status_icons_fullscreen", status_icons_fullscreen); - else - ini_section_delete_var(cat, "status_icons_fullscreen"); - if (video_framerate != -1) ini_section_set_int(cat, "video_gl_framerate", video_framerate); else diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 1f5f2b695..84f0318c2 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -107,7 +107,6 @@ extern int infocus; extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; -extern int status_icons_fullscreen; extern int kbd_req_capture; extern int hide_status_bar; diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 04f3bc5b3..8683cc4d9 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -31,9 +31,6 @@ msgstr "&Скрыть строку состояния" msgid "Hide &toolbar" msgstr "С&крыть панель инструментов" -msgid "Show status icons in fullscreen" -msgstr "Показывать значки состояния в полноэкранном режиме" - msgid "Show non-primary monitors" msgstr "&Показывать неосновные мониторы" diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 47f0de718..ee2ec07df 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -136,22 +136,6 @@ HardwareRenderer::initializeGL() m_context->swapBuffers(this); } -void -HardwareRenderer::paintOverGL() -{ - /* Context switching is needed to make use of QPainter to draw status bar icons in fullscreen. - Especially since it seems to be impossible to use QPainter on externally-created OpenGL contexts. */ - if (video_fullscreen && status_icons_fullscreen) { - m_context->makeCurrent(nullptr); - makeCurrent(); - QPainter painter(this); - drawStatusBarIcons(&painter); - painter.end(); - doneCurrent(); - m_context->makeCurrent(this); - } -} - void HardwareRenderer::paintGL() { diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 1918cda18..f7861d2bd 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -53,7 +53,7 @@ public: { onResize(size().width(), size().height()); } - void paintOverGL() override; + std::vector> getBuffers() override; HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ace052a32..f24ab0788 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -340,7 +340,6 @@ MainWindow::MainWindow(QWidget *parent) ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionEnable_Discord_integration->setChecked(enable_discord); ui->actionApply_fullscreen_stretch_mode_when_maximized->setChecked(video_fullscreen_scale_maximized); - ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); #ifndef DISCORD ui->actionEnable_Discord_integration->setVisible(false); @@ -2032,11 +2031,3 @@ void MainWindow::on_actionACPI_Shutdown_triggered() { acpi_pwrbut_pressed = 1; } - -void MainWindow::on_actionShow_status_icons_in_fullscreen_triggered() -{ - status_icons_fullscreen = !status_icons_fullscreen; - ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); - config_save(); -} - diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 64a97f012..950d145c1 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -142,7 +142,6 @@ private slots: void on_actionCursor_Puck_triggered(); void on_actionACPI_Shutdown_triggered(); - void on_actionShow_status_icons_in_fullscreen_triggered(); private slots: void on_actionShow_non_primary_monitors_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index d77c8d171..ccdb5a9cf 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -179,7 +179,6 @@ - @@ -870,14 +869,6 @@ Cursor/Puck - - - true - - - Show status icons in fullscreen - - true diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 05c35e09b..178134c9d 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -17,15 +17,11 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" -#include "qt_machinestatus.hpp" #include #include #include #include -#include -#include -#include #include @@ -33,8 +29,6 @@ extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/video.h> - -int status_icons_fullscreen = 0; } RendererCommon::RendererCommon() = default; @@ -137,52 +131,6 @@ RendererCommon::onResize(int width, int height) monitors[r_monitor_index].mon_res_y = (double) destination.height(); } -void RendererCommon::drawStatusBarIcons(QPainter* painter) -{ - uint32_t x = 0; - auto prevcompositionMode = painter->compositionMode(); - painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver); - for (int i = 0; i < main_window->statusBar()->children().count(); i++) { - QLabel* label = qobject_cast(main_window->statusBar()->children()[i]); - if (label) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const QPixmap pixmap = label->pixmap(); -#elif QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - const QPixmap pixmap = label->pixmap(Qt::ReturnByValue); -#else - const QPixmap pixmap = (label->pixmap() ? *label->pixmap() : QPixmap()); -#endif - if (!pixmap.isNull()) { - painter->setBrush(QColor::fromRgbF(0, 0, 0, 1.)); - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, - pixmap.width(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5)); - painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2, - painter->device()->height() - pixmap.height() - 3, pixmap); - x += pixmap.width(); - if (i <= main_window->statusBar()->children().count() - 3) { - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, - main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, - QColor::fromRgbF(0, 0, 0, .5)); - x += main_window->statusBar()->layout()->spacing(); - } else - painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, - pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5)); - } - } - } - if (main_window->status->getMessage().isEmpty() == false) { - auto curStatusMsg = main_window->status->getMessage(); - auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); - painter->setPen(QColor(0, 0, 0, 127)); - painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), - textSize.width(), textSize.height(), QColor(0, 0, 0, 127)); - painter->setPen(QColor(255, 255, 255, 255)); - painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), - textSize.width(), textSize.height()), Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); - } - painter->setCompositionMode(prevcompositionMode); -} - bool RendererCommon::eventDelegate(QEvent *event, bool &result) { diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index ab9ed932d..a8c0229d3 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -24,7 +24,6 @@ extern "C" { #include <86box/86box.h> -#include <86box/plat.h> #include <86box/video.h> } @@ -114,7 +113,6 @@ SoftwareRenderer::onPaint(QPaintDevice *device) #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); - if (video_fullscreen && status_icons_fullscreen) drawStatusBarIcons(&painter); } std::vector> diff --git a/src/unix/unix.c b/src/unix/unix.c index 4f21ddd53..a5e4917f3 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -63,7 +63,6 @@ extern wchar_t sdl_win_title[512]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present; -int status_icons_fullscreen = 0; /* unused. */ SDL_mutex *blitmtx; SDL_threadID eventthread; static int exit_event = 0; diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 73119140c..207158b29 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -76,8 +76,6 @@ int hide_status_bar = 0; int hide_tool_bar = 0; int dpi = 96; -int status_icons_fullscreen = 0; /* unused. */ - extern char openfilestring[512]; extern WCHAR wopenfilestring[512]; From 307e15019ecda07b8b8f7403f7e23e3df90c11b3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 21:41:01 +0500 Subject: [PATCH 083/690] Remove a long-unused string --- src/include/86box/language.h | 1 - src/qt/languages/ca-ES.po | 3 --- src/qt/languages/cs-CZ.po | 3 --- src/qt/languages/de-DE.po | 3 --- src/qt/languages/en-GB.po | 3 --- src/qt/languages/en-US.po | 3 --- src/qt/languages/es-ES.po | 3 --- src/qt/languages/fi-FI.po | 3 --- src/qt/languages/fr-FR.po | 3 --- src/qt/languages/hr-HR.po | 3 --- src/qt/languages/hu-HU.po | 3 --- src/qt/languages/it-IT.po | 3 --- src/qt/languages/ja-JP.po | 3 --- src/qt/languages/ko-KR.po | 3 --- src/qt/languages/pl-PL.po | 3 --- src/qt/languages/pt-BR.po | 3 --- src/qt/languages/pt-PT.po | 3 --- src/qt/languages/ru-RU.po | 3 --- src/qt/languages/sk-SK.po | 3 --- src/qt/languages/sl-SI.po | 3 --- src/qt/languages/tr-TR.po | 3 --- src/qt/languages/uk-UA.po | 3 --- src/qt/languages/zh-CN.po | 3 --- src/qt/languages/zh-TW.po | 3 --- src/qt/qt_platform.cpp | 1 - src/unix/unix.c | 2 -- src/win/languages/cs-CZ.rc | 1 - src/win/languages/de-DE.rc | 1 - src/win/languages/en-GB.rc | 1 - src/win/languages/en-US.rc | 1 - src/win/languages/es-ES.rc | 1 - src/win/languages/fi-FI.rc | 1 - src/win/languages/fr-FR.rc | 1 - src/win/languages/hr-HR.rc | 1 - src/win/languages/hu-HU.rc | 1 - src/win/languages/it-IT.rc | 1 - src/win/languages/ja-JP.rc | 1 - src/win/languages/ko-KR.rc | 1 - src/win/languages/pl-PL.rc | 1 - src/win/languages/pt-BR.rc | 1 - src/win/languages/pt-PT.rc | 1 - src/win/languages/ru-RU.rc | 1 - src/win/languages/sl-SI.rc | 1 - src/win/languages/tr-TR.rc | 1 - src/win/languages/uk-UA.rc | 1 - src/win/languages/zh-CN.rc | 1 - src/win/languages/zh-TW.rc | 1 - 47 files changed, 94 deletions(-) diff --git a/src/include/86box/language.h b/src/include/86box/language.h index af459c0ff..3c96e711f 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -97,7 +97,6 @@ #define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" #define IDS_2109 2109 // "Floppy %i (%s): %ls" #define IDS_2110 2110 // "All floppy images (*.0??;*.." -#define IDS_2112 2112 // "Unable to initialize SDL..." #define IDS_2113 2113 // "Are you sure you want to..." #define IDS_2114 2114 // "Are you sure you want to..." #define IDS_2115 2115 // "Unable to initialize Ghostscript..." diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 71b643220..483e6ee53 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -814,9 +814,6 @@ 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?" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 0069f245b..84c795092 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -814,9 +814,6 @@ msgstr "Rozšířené sektorové obrazy" msgid "Flux images" msgstr "Obrazy magnetického toku" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Opravdu chcete resetovat emulovaný počítač?" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index ed8e57ffa..4a4fde3c2 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -814,9 +814,6 @@ msgstr "Fortgeschrittene Sektorimages" msgid "Flux images" msgstr "Fluximages" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index b56c274d3..031a365c0 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -814,9 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index e3cfa3f77..06a4b60f1 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -814,9 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index c0f38893d..60ac5fb5c 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -814,9 +814,6 @@ msgstr "Imágenes avanzadas de sector" msgid "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 "¿Está seguro de que quieres hacer una reinicialización completa de la máquina emulada?" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 4998d008b..50ebffccb 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -814,9 +814,6 @@ msgstr "Kehittyneet sektorilevykuvat" msgid "Flux images" msgstr "Flux-levykuvat" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 0c50b3e46..52bccebd2 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -814,9 +814,6 @@ msgstr "Images du secteur avancés" msgid "Flux images" msgstr "Images du flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossible d'initialiser SDL, SDL2.dll est nécessaire" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 436bae5c5..19b6a6e85 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -814,9 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Flux slike" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jeste li sigurni da želite hard resetirati emulirani sistem?" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 129df1e2b..338d2ff5e 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -814,9 +814,6 @@ msgstr "Továbbfejlesztett szektor képek" msgid "Flux images" msgstr "Flux képekfájlok" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Biztosan szeretné újraindítani az emulált gépet?" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 334ecadaa..20c15c656 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -814,9 +814,6 @@ msgstr "Immagini da settori avanzati" msgid "Flux images" msgstr "Immagini flusso" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossibile inizializzare SDL, SDL2.dll è necessario" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sei sicuro di voler riavviare la macchina emulata?" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 32236adaa..d0f206dc9 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -814,9 +814,6 @@ msgstr "アドバンスドセクターイメージ" msgid "Flux images" msgstr "Fluxイメージ" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDLが初期化できません。SDL2.dllが必要です" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "使用中のマシンをハード リセットしますか?" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index a8ff2723d..f5d1502b0 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -814,9 +814,6 @@ msgstr "어드밴스드 섹터 이미지" msgid "Flux images" msgstr "플럭스 이미지" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "실행중인 머신을 재시작하시겠습니까?" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index a449d8951..eb7a13e4e 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -814,9 +814,6 @@ msgstr "Zaawansowane obrazy sektorów" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nie można zainicjować SDL, wymagany SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index c06f24835..148ca716c 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -814,9 +814,6 @@ msgstr "Imagens de setor avançado" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não é possível inicializar o SDL, é necessário o SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem certeza de que deseja reiniciar completamente a máquina emulada?" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 9743bc83c..e309d91bf 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -814,9 +814,6 @@ msgstr "Imagens avançadas de sector" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem a certeza de que quer um reinício completo da máquina emulada?" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 8683cc4d9..4aa99eb87 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -904,9 +904,6 @@ msgstr "Расширенные образы секторов" msgid "Flux images" msgstr "Образы Flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Невозможно инициализировать SDL, требуется SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index c2f129a3d..376723efa 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -814,9 +814,6 @@ 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č?" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 8c1d62ded..cde1011d1 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -814,9 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Tokovne slike" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ste prepričani, da želite ponovno zagnati emulirani sistem?" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 65a039c42..0989218e5 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -814,9 +814,6 @@ msgstr "Gelişmiş sektör imajları" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL başlatılamadı, SDL2.dll gerekmektedir" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 0d8522f15..76796a57a 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -814,9 +814,6 @@ msgstr "Розширені образи секторів" msgid "Flux images" msgstr "Образи Flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Неможливо ініціалізувати SDL, потрібно SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 0ac54f4e7..94c468d80 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -814,9 +814,6 @@ msgstr "高级扇区映像" msgid "Flux images" msgstr "Flux 映像" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "无法初始化 SDL,需要 SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "确定要硬重置模拟器吗?" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index cf53b3488..7836f7ef8 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -814,9 +814,6 @@ msgstr "進階磁區映像" msgid "Flux images" msgstr "Flux 映像" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "無法初始化 SDL,需要 SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "確定要硬重設模擬器嗎?" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 6890bd407..356334bac 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -602,7 +602,6 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2112] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); diff --git a/src/unix/unix.c b/src/unix/unix.c index a5e4917f3..6c21bfa45 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -262,8 +262,6 @@ plat_get_string(int i) return L"No PCap devices found"; case IDS_2096: return L"Invalid PCap device"; - case IDS_2112: - return L"Unable to initialize SDL, libsdl2 is required"; case IDS_2133: return L"libgs 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."; case IDS_2130: diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 353ea55b6..cbda41e7e 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketová mechanika %i (%s): %ls" IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2112 "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" IDS_2114 "Opravdu chcete ukončit 86Box?" IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 0fe48b0ef..9859d3d26 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Diskette %i (%s): %ls" IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2112 "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" IDS_2115 "Ghostscript konnte nicht initialisiert werden" diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index bc0df4d05..a974b1862 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 05ef61790..c12fb4a45 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index e9fef50d4..4888c09f4 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Incapaz de inicializar SDL, se requiere SDL2.dll" IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" IDS_2114 "¿Seguro que quieres cerrar 86Box?" IDS_2115 "Incapaz de inicializar Ghostscript" diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 1b958cc82..029cce6c0 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u Mt (CHS: %i, %i, %i)" IDS_2109 "Levyke %i (%s): %ls" IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2112 "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" IDS_2114 "Haluatko varmasti sulkea 86Boxin?" IDS_2115 "Ghostscriptin alustus epäonnistui" diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 8c77979ef..425656c28 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u Mo (CTS: %i, %i, %i)" IDS_2109 "Disquette %i (%s): %ls" IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2112 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" IDS_2115 "Impossible d'initialiser Ghostscript" diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 2e6caea43..f01b2a881 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2112 "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" IDS_2115 "Nije moguće inicijalizirati GhostScript" diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index 34bf512c1..52189426a 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -469,7 +469,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2112 "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index 6f5b67201..e5868caa0 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -465,7 +465,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2112 "Impossibile inizializzare SDL, SDL2.dll è necessario" IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" IDS_2114 "Sei sicuro di voler uscire da 86Box?" IDS_2115 "Impossibile inizializzare Ghostscript" diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index a8e90d062..4090abf00 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS値: %i、%i、%i)" IDS_2109 "フロッピー %i (%s): %ls" IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスド セクター イメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0ベーシック セクター イメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0サーフェス イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2112 "SDLが初期化できません。SDL2.dllが必要です" IDS_2113 "使用中のマシンをハードリ セットしますか?" IDS_2114 "86Boxを終了しますか?" IDS_2115 "Ghostscriptが初期化できません" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 535ff1df4..7550e0779 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "플로피 %i (%s): %ls" IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2112 "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" IDS_2113 "실행중인 머신을 재시작하시겠습니까?" IDS_2114 "86Box를 끝내시겠습니까?" IDS_2115 "Ghostscript를 초기화할 수 없습니다" diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index bdd73f6cf..623415045 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Dyskietka %i (%s): %ls" IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Nie można zainicjować SDL, wymagany SDL2.dll" IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" IDS_2115 "Nie można zainicjować Ghostscript" diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 48cbba111..4f72a41a4 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -467,7 +467,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2112 "Não é possível inicializar o SDL, é necessário o SDL2.dll" IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" IDS_2114 "Tem certeza de que deseja sair do 86Box?" IDS_2115 "Não é possível inicializar o Ghostscript" diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index e4394b0cb..c17cfe362 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CCS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2112 "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" IDS_2114 "Tem a certeza de que quer sair do 86Box?" IDS_2115 "Não foi possível inicializar o Ghostscript" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 01562063a..719dd5a35 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2112 "Невозможно инициализировать SDL, требуется SDL2.dll" IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" IDS_2114 "Вы уверены, что хотите выйти из 86Box?" IDS_2115 "Невозможно инициализировать Ghostscript" diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index 80da82276..3a8b12dbb 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2112 "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" IDS_2114 "Ste prepričani, da želite zapreti 86Box?" IDS_2115 "Ne morem inicializirati Ghostscript" diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index d7285bdf7..80a436c5d 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disket %i (%s): %ls" IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "SDL başlatılamadı, SDL2.dll gerekmektedir" IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" IDS_2115 "Ghostscript başlatılamadı" diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index d9674260c..53f401e81 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" - IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" IDS_2115 "Неможливо ініціалізувати Ghostscript" diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 1be833eb3..1139de4ea 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "软盘 %i (%s): %ls" IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2112 "无法初始化 SDL,需要 SDL2.dll" IDS_2113 "确定要硬重置模拟器吗?" IDS_2114 "确定要退出 86Box 吗?" IDS_2115 "无法初始化 Ghostscript" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index dcc01836b..58324442d 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "軟碟 %i (%s): %ls" IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" - IDS_2112 "無法初始化 SDL,需要 SDL2.dll" IDS_2113 "確定要硬重設模擬器嗎?" IDS_2114 "確定要退出 86Box 嗎?" IDS_2115 "無法初始化 Ghostscript" From 0e53b86d25314d1548654762fe31161984ee26dc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 22:28:27 +0500 Subject: [PATCH 084/690] Move the Matrox Millennium II and G100 to the Dev branch --- CMakeLists.txt | 1 + src/include/86box/video.h | 2 ++ src/video/CMakeLists.txt | 4 ++++ src/video/vid_mga.c | 6 ++++++ src/video/vid_table.c | 4 ++++ src/win/Makefile.mingw | 10 ++++++++++ 6 files changed, 27 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6b50baf3..7767166af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e82807a12..612d1e503 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,8 +439,10 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; +# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t millennium_ii_device; extern const device_t productiva_g100_device; +# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 638837757..a11bb0a12 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,6 +28,10 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) +if(MGA2) + target_compile_definitions(vid PRIVATE USE_MGA2) +endif() + if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 088085355..c8836f129 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6541,6 +6541,7 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } +#if defined(DEV_BRANCH) && defined(USE_MGA2) static int millennium_ii_available(void) { @@ -6552,6 +6553,7 @@ matrox_g100_available(void) { return rom_present(ROM_G100); } +#endif static void mystique_speed_changed(void *priv) @@ -6601,6 +6603,7 @@ static const device_config_t mystique_config[] = { // clang-format on }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) static const device_config_t millennium_ii_config[] = { // clang-format off { @@ -6632,6 +6635,7 @@ static const device_config_t millennium_ii_config[] = { } // clang-format on }; +#endif const device_t millennium_device = { .name = "Matrox Millennium", @@ -6675,6 +6679,7 @@ const device_t mystique_220_device = { .config = mystique_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t millennium_ii_device = { .name = "Matrox Millennium II", .internal_name = "millennium_ii", @@ -6702,3 +6707,4 @@ const device_t productiva_g100_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; +#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d40f00e13..70e5a6359 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -208,7 +208,9 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, +#if defined(DEV_BRANCH) && defined(USE_MGA2) { &millennium_ii_device }, +#endif { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, @@ -259,7 +261,9 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, +#if defined(DEV_BRANCH) && defined(USE_MGA2) { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, +#endif { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0cf34d6c6..b889558ba 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,6 +64,9 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif + ifndef MGA2 + MGA2 := y + endif ifndef OLIVETTI OLIVETTI := y endif @@ -125,6 +128,9 @@ else ifndef LASERXT LASERXT := n endif + ifndef MGA2 + MGA2 := n + endif ifndef OLIVETTI OLIVETTI := n endif @@ -490,6 +496,10 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif + ifeq ($(MGA2), y) + OPTS += -DUSE_MGA2 + endif + ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From c7204f3c9fab2fc9943eb8e227655fee90a9fc3c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:51:19 +0600 Subject: [PATCH 085/690] Devbranch OPL4-ML daughterboard emulation (part 1) --- src/sound/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index d6672ac18..aeaa8c0be 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c midi_opl4.c midi_opl4_yrw801.c) + snd_optimc.c) if(OPENAL) if(VCPKG_TOOLCHAIN) @@ -125,5 +125,10 @@ if(GUSMAX) target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() +if(OPL4ML) + target_compile_definitions(snd PRIVATE USE_OPL4ML) + target_sources(snd PRIVATE target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) +endif() + add_subdirectory(resid-fp) target_link_libraries(86Box resid-fp) From c81c04a2a9b26d3de7dbf0997a6db7ede73e8ee6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:54:41 +0600 Subject: [PATCH 086/690] Devbranch OPL4-ML daughterboard emulation (part 2) --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7767166af..80b56d619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,7 @@ cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) From c7c05676061dd195baa5a9ae73c20adb8873196d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:58:31 +0600 Subject: [PATCH 087/690] Devbranch OPL4-ML daughterboard emulation (part 3) --- src/sound/midi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sound/midi.c b/src/sound/midi.c index c5dbd666f..bb107acbf 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -100,7 +100,9 @@ static const MIDI_OUT_DEVICE devices[] = { #ifdef USE_RTMIDI { &rtmidi_output_device }, #endif +#if defined(DEV_BRANCH) && defined(USE_OPL4ML) { &opl4_midi_device }, +#endif { NULL } // clang-format on }; From 63329bc922df9d98954f6a5a09cef8f400d37ca8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 03:02:14 +0600 Subject: [PATCH 088/690] Fix bad line --- src/sound/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index aeaa8c0be..72f05ff6d 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -127,7 +127,7 @@ endif() if(OPL4ML) target_compile_definitions(snd PRIVATE USE_OPL4ML) - target_sources(snd PRIVATE target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) + target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) endif() add_subdirectory(resid-fp) From f7c995738ca5aba8b380b7abcf5a7474851aae64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Wed, 14 Feb 2024 02:29:31 +0100 Subject: [PATCH 089/690] Fixed a bug in the 386 implementation of LOCK. --- src/cpu/x86_ops_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 419ee7dc2..8e9c9f785 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -743,7 +743,7 @@ opLOCK(uint32_t fetchdat) if (legal == 1) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ else if (legal == 2) { - legal = lock_legal[fetch_dat.b[1]]; + legal = lock_legal_0f[fetch_dat.b[1]]; if (legal == 1) legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ else if (legal == 3) { From e8406cdbc7b30e90511afe9beb3d2febf79c0758 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:17:42 +0500 Subject: [PATCH 090/690] Rename vid_c&t_69000.c to avoid & in the filename Apparently CMake chokes on it in a few cases --- src/video/CMakeLists.txt | 5 ++--- src/video/{vid_c&t_69000.c => vid_chips_69000.c} | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename src/video/{vid_c&t_69000.c => vid_chips_69000.c} (100%) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index d14120caf..dc0cac1ff 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -19,15 +19,14 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c - vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c - vid_c&t_69000.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) if(MGA2) target_compile_definitions(vid PRIVATE USE_MGA2) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_chips_69000.c similarity index 100% rename from src/video/vid_c&t_69000.c rename to src/video/vid_chips_69000.c From be27b6b6b22918adce315c8090be426339dce624 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:18:33 +0500 Subject: [PATCH 091/690] Fix a forgotten change from D3D9 renderer removal It only affected the VNC renderer --- src/qt/qt_mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index ccdb5a9cf..08d8bbf63 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -845,7 +845,7 @@ VNC - 6 + 5 From 0ecbc24763d021ee35408117e57a188eccc408ac Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:19:35 +0500 Subject: [PATCH 092/690] Improve the OPL4-ML devbranching --- CMakeLists.txt | 2 +- src/include/86box/midi.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80b56d619..f13e91791 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,11 +156,11 @@ cmake_dependent_option(LASERXT "VTech Laser XT" cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 4bc678817..7f7ad89ae 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -102,7 +102,9 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; +# if defined(DEV_BRANCH) && defined(USE_OPL4ML) extern const device_t opl4_midi_device; +# endif # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; # endif From 821f40deb1201cc9c82f6921da8a7bf057558998 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:19:48 +0500 Subject: [PATCH 093/690] Fix the legacy Makefile --- src/win/Makefile.mingw | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b889558ba..94b8af74a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -73,6 +73,9 @@ ifeq ($(DEV_BUILD), y) ifndef OPEN_AT OPEN_AT := y endif + ifndef OPL4ML + OPL4ML := y + endif ifndef PAS16 PAS16 := y endif @@ -137,6 +140,9 @@ else ifndef OPEN_AT OPEN_AT := n endif + ifndef OPL4ML + OPL4ML := n + endif ifndef PAS16 PAS16 := n endif @@ -504,6 +510,11 @@ ifeq ($(DEV_BRANCH), y) OPTS += -DUSE_OPEN_AT endif + ifeq ($(OPL4ML), y) + OPTS += -DUSE_OPL4ML + DEVBROBJ += midi_opl4.o midi_opl4_yrw801.o + endif + ifeq ($(PAS16), y) OPTS += -DUSE_PAS16 DEVBROBJ += snd_pas16.o @@ -708,8 +719,6 @@ SNDOBJ := sound.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ midi.o \ - midi_opl4.o \ - midi_opl4_yrw801.o \ snd_speaker.o \ snd_pssj.o \ snd_ps1.o \ @@ -744,10 +753,11 @@ VIDOBJ := agpgart.o video.o \ vid_vga.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ - vid_ati_mach8.o \ + vid_ati_mach8.o \ vid_ati68875_ramdac.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_bt48x_ramdac.o \ + vid_chips_69000.o \ vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ vid_cl54xx.o \ vid_et3000.o \ From 9b87dbe7bac0fedfeaec77e87b46595ce40c88ba Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:48:58 +0500 Subject: [PATCH 094/690] Fix warnings in vid_chips_69000.c --- src/video/vid_chips_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index b15546a69..deabc2b6a 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1988,7 +1988,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x600 ... 0x603: { chips->mem_regs_b[addr & 0xF] = val; - chips->mem_regs[addr >> 2] &= 0x80004040; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; if (addr == 0x605 || addr == 0x607) chips_69000_interrupt(chips); break; @@ -1997,7 +1997,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x604 ... 0x607: { chips->mem_regs_b[addr & 0xF] &= ~val; - chips->mem_regs[addr >> 2] &= 0x80004040; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; if (addr == 0x605 || addr == 0x607) chips_69000_interrupt(chips); break; From 0240f11bbee31327eb9b48346da55f891ee03777 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 14 Feb 2024 17:05:28 +0100 Subject: [PATCH 095/690] Matrox MGA fixes: 1. When the 128K banking is activated, use a mask of 0xffff instead of 0x1ffff. 2. Debian uses standard VGA mapping when in chain4 mode and its lfb is adapted accordingly. 3. Fixed the decode VRAM mask on the Millennium II so that the vram is detected correctly and no more glitches. 4. Undev the Millennium II as well. --- src/include/86box/video.h | 2 +- src/video/vid_mga.c | 50 +++++++++++++++++++++++---------------- src/video/vid_table.c | 2 -- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 26c9bd939..e1fa58b74 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,8 +439,8 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; -# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t millennium_ii_device; +# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t productiva_g100_device; # endif diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c8836f129..767ec57a0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1137,7 +1137,7 @@ mystique_recalc_mapping(mystique_t *mystique) switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0x1ffff; + svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); @@ -2812,13 +2812,21 @@ mystique_readb_linear(uint32_t addr, void *priv) const svga_t *svga = (svga_t *) priv; mystique_t *mystique = (mystique_t *) svga->priv; - if (mystique->type < MGA_1064SG) { - if (!svga->fast) - return svga_read_linear(addr, priv); - } - cycles -= svga->monitor->mon_video_timing_read_b; + if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4 && !svga->force_old_addr) { + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; @@ -2860,15 +2868,17 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; mystique_t *mystique = (mystique_t *) svga->priv; - if (mystique->type < MGA_1064SG) { - if (!svga->fast) { - svga_write_linear(addr, val, priv); - return; - } - } - cycles -= svga->monitor->mon_video_timing_write_b; + if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { + addr &= ~3; + } else if (svga->chain4 && (svga->writemode < 4)) { + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; @@ -6401,8 +6411,8 @@ mystique_init(const device_t *info) mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; mystique->svga.conv_16to32 = tvp3026_conv_16to32; - if (mystique->vram_size >= 16) - mystique->svga.decode_mask = mystique->svga.vram_mask; + if (mystique->type == MGA_2164W) + mystique->svga.decode_mask = 0xffffff; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); @@ -6413,8 +6423,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; - if (mystique->vram_size >= 16) - mystique->svga.decode_mask = mystique->svga.vram_mask; + if (mystique->type == MGA_G100) + mystique->svga.decode_mask = 0xffffff; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); @@ -6541,13 +6551,13 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } -#if defined(DEV_BRANCH) && defined(USE_MGA2) static int millennium_ii_available(void) { return rom_present(ROM_MILLENNIUM_II); } +#if defined(DEV_BRANCH) && defined(USE_MGA2) static int matrox_g100_available(void) { @@ -6603,7 +6613,6 @@ static const device_config_t mystique_config[] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) static const device_config_t millennium_ii_config[] = { // clang-format off { @@ -6635,7 +6644,6 @@ static const device_config_t millennium_ii_config[] = { } // clang-format on }; -#endif const device_t millennium_device = { .name = "Matrox Millennium", @@ -6679,7 +6687,6 @@ const device_t mystique_220_device = { .config = mystique_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t millennium_ii_device = { .name = "Matrox Millennium II", .internal_name = "millennium_ii", @@ -6694,6 +6701,7 @@ const device_t millennium_ii_device = { .config = millennium_ii_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t productiva_g100_device = { .name = "Matrox Productiva G100", .internal_name = "productiva_g100", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a44ba071f..889bfa5fc 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -209,9 +209,7 @@ video_cards[] = { { &s3_trio3d2x_pci_device }, { &chips_69000_device }, { &millennium_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA2) { &millennium_ii_device }, -#endif { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, From f5995a4719668a4fa71cebe315fc0d56ef37008f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 15 Feb 2024 00:31:51 +0600 Subject: [PATCH 096/690] vid_svga.c: Hardware cursors with negative Y values work properly now * Fixes cursor disappearing completely in Matrox cards in some cases. * Allows emulated video adapters allowing negative Y values for hardware cursor to render those properly --- src/video/vid_chips_69000.c | 8 +++----- src/video/vid_mga.c | 4 ++-- src/video/vid_svga.c | 12 ++++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index deabc2b6a..3852070b8 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1529,16 +1529,14 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; if (chips->ext_regs[0xA7] & 0x80) { - chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; - chips->svga.hwcursor.y = 0; + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; } break; case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80){ - chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; - chips->svga.hwcursor.y = 0; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; } break; case 0xC8: diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 767ec57a0..f9564366b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5924,9 +5924,9 @@ mystique_hwcursor_draw(svga_t *svga, int displine) case XCURCTRL_CURMODE_XGA: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; dat[0] <<= 1; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 81cc50bc4..0293ebeda 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -981,7 +981,7 @@ svga_do_render(svga_t *svga) if (svga->dac_hwcursor_on) { if (!svga->override && svga->dac_hwcursor_draw) - svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); + svga->dac_hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->dac_hwcursor_latch.y >= 0) ? 0 : svga->dac_hwcursor_latch.y)) & 2047); svga->dac_hwcursor_on--; if (svga->dac_hwcursor_on && svga->interlace) svga->dac_hwcursor_on--; @@ -989,7 +989,7 @@ svga_do_render(svga_t *svga) if (svga->hwcursor_on) { if (!svga->override && svga->hwcursor_draw) - svga->hwcursor_draw(svga, svga->displine + svga->y_add); + svga->hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->hwcursor_latch.y >= 0) ? 0 : svga->hwcursor_latch.y)) & 2047); svga->hwcursor_on--; if (svga->hwcursor_on && svga->interlace) svga->hwcursor_on--; @@ -1018,22 +1018,22 @@ svga_poll(void *priv) } if (!svga->linepos) { - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { + if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) { svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff; svga->hwcursor_oddeven = 0; } - if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { + if (svga->displine == (((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) + 1) && svga->hwcursor_latch.ena && svga->interlace) { svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1); svga->hwcursor_oddeven = 1; } - if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { + if (svga->displine == ((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) && svga->dac_hwcursor_latch.ena) { svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff; svga->dac_hwcursor_oddeven = 0; } - if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { + if (svga->displine == (((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); svga->dac_hwcursor_oddeven = 1; } From 536f10c60ec470535ae5807aebdc0fcb4360d108 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 14 Feb 2024 20:36:43 +0100 Subject: [PATCH 097/690] S3 Pre-ViRGE 32bpp fixes: 32-bit toggleable regs are now written properly, fixes OS/2 32-bit color using S3 Pre-ViRGE drivers while keeping existing compatibility fine. --- src/video/vid_s3.c | 243 +++++++++++++++++++++++++++------------------ 1 file changed, 146 insertions(+), 97 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ca737e7fe..41e21faa9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -981,16 +981,16 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa148: case 0xa2e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; break; case 0xa149: case 0xa2e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1001,34 +1001,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa14a: case 0xa2ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } break; case 0xa14b: case 0xa2eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xa548: case 0xa6e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; break; case 0xa549: case 0xa6e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1039,34 +1046,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa54a: case 0xa6ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; - else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } break; case 0xa54b: case 0xa6eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); - else - s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xa948: case 0xaae8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; break; case 0xa949: case 0xaae9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1077,85 +1091,106 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa94a: case 0xaaea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } break; case 0xa94b: case 0xaaeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xad48: case 0xaee8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; break; case 0xad49: case 0xaee9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xad4a: case 0xaeea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; - else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } break; case 0xad4b: case 0xaeeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); - else - s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb148: case 0xb2e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; break; case 0xb149: case 0xb2e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb14a: case 0xb2ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; - else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } break; case 0xb14b: case 0xb2eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); - else - s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb548: @@ -1189,34 +1224,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xe548: case 0xe6e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; break; case 0xe549: case 0xe6e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xe54a: case 0xe6ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + } break; case 0xe54b: case 0xe6eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xe948: case 0xeae8: @@ -1237,34 +1279,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xed48: case 0xeee8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; break; case 0xed49: case 0xeee9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xed4a: case 0xeeea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + } break; case 0xed4b: case 0xeeeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xe148: @@ -8009,8 +8058,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } break; @@ -8103,8 +8152,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } else { /*Bresenham*/ if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; @@ -8198,8 +8247,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } break; From 8166af1b77db5f74107113b75b4337cf07f2e24e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 00:59:25 +0600 Subject: [PATCH 098/690] C&T 69000: Fix VBIOS size --- src/video/vid_chips_69000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 3852070b8..eb67e16de 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1835,7 +1835,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->pci_rom_enable = val & 0x1; mem_mapping_disable(&chips->bios_rom.mapping); if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x32: @@ -1843,7 +1843,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->rom_addr &= ~0xFF; chips->rom_addr |= val & 0xFC; if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x33: @@ -1851,7 +1851,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->rom_addr &= ~0xFF00; chips->rom_addr |= (val << 8); if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x6C: @@ -2333,7 +2333,7 @@ chips_69000_init(const device_t *info) /* Appears to have an odd VBIOS size. */ if (!info->local) { - rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x40000, 0x3ffff, 0x0000, MEM_MAPPING_EXTERNAL); + rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x10000, 0xffff, 0x0000, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&chips->bios_rom.mapping); } From d37b72e251a00c006fe60307ff2ae2d699a9562e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 01:24:35 +0600 Subject: [PATCH 099/690] vid_tvp3026_ramdac: Implement warp-around for hardware cursor buffer32 drawing Fixes crashes on Windows 2000 --- src/video/vid_tvp3026_ramdac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 4b63892de..625adfe41 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -649,7 +649,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) comb = (b0 | (b1 << 1)); y_pos = displine; - x_pos = offset + svga->x_add; + x_pos = (offset + svga->x_add) & 2047; p = svga->monitor->target_buffer->line[y_pos]; if (offset >= svga->dac_hwcursor_latch.x) { From e9f0af21a05b659597e779fc52eb770db1e207a7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 15 Feb 2024 23:10:05 +0100 Subject: [PATCH 100/690] MGA updates for the vram detection and stuff. 1. The Debian issue mystery lies around chain2_read/write being required when the LFB mapping is enabled too when MGA modes are set without blitting, however, when it is blitting, immediately tell chain2 to not interfere with the mapping. Fixes Debian once and for all as well as VRAM detection correctly while keeping existing compatibility fine. 2. Undev branch the G100 per above. (Revert if more bugs are revealed). 3. An AND with 0 is not tolerable as it nulls the LFB, fixes hang ups with Win2000 using the Millennium II and possibly the G100. 4. the Extended CRTCs now have a call for timing recalculation, fixes mode changes when blitting is going on. --- src/include/86box/video.h | 2 - src/video/vid_mga.c | 161 +++++++++++++++++++++++--------------- src/video/vid_table.c | 2 - 3 files changed, 96 insertions(+), 69 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e1fa58b74..47d237b10 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -440,9 +440,7 @@ extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; extern const device_t millennium_ii_device; -# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t productiva_g100_device; -# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f9564366b..89b036ede 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -794,7 +794,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } - if (mystique->crtcext_idx == 4) { + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ if (mystique->type >= MGA_2164W) { @@ -815,6 +815,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } } + svga_recalctimings(svga); break; default: @@ -2814,17 +2815,11 @@ mystique_readb_linear(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; - if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4 && !svga->force_old_addr) { - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read) { - addr &= ~1; - addr <<= 2; + if (!svga->fast) { + if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } } addr &= svga->decode_mask; @@ -2870,13 +2865,11 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; - if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { - addr &= ~3; - } else if (svga->chain4 && (svga->writemode < 4)) { - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_write) { - addr &= ~1; - addr <<= 2; + if (!svga->fast) { + if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } } addr &= svga->decode_mask; @@ -5835,9 +5828,14 @@ blit_iload_highv(mystique_t *mystique) static void mystique_start_blit(mystique_t *mystique) { + svga_t *svga = &mystique->svga; uint64_t start_time = plat_timer_read(); uint64_t end_time; + /*Make sure we don't get any artifacts.*/ + svga->chain2_write = 0; + svga->chain2_read = 0; + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; mystique->maccess_running = mystique->maccess; @@ -5969,15 +5967,6 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; - if (mystique->type >= MGA_1164SG) - { - /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ - if (addr >= 0x10 && addr <= 0x13) - addr += 0x4; - else if (addr >= 0x14 && addr <= 0x17) - addr -= 0x4; - } - if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) ret = 0x00; else @@ -6032,25 +6021,46 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x10: ret = 0x00; - break; /*Control aperture*/ + break; /*Control aperture for Millennium and Mystique, LFB for Mystique 220 and later*/ case 0x11: - ret = (mystique->ctrl_base >> 8) & 0xc0; + if (mystique->type >= MGA_1164SG) + ret = 0x00; + else + ret = (mystique->ctrl_base >> 8) & 0xc0; break; case 0x12: - ret = mystique->ctrl_base >> 16; + if (mystique->type >= MGA_1164SG) + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); + else + ret = mystique->ctrl_base >> 16; break; case 0x13: - ret = mystique->ctrl_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->lfb_base >> 24; + else + ret = mystique->ctrl_base >> 24; break; case 0x14: ret = 0x00; - break; /*Linear frame buffer*/ + break; /*LFB for Millennium and Mystique, Control aperture for Mystique 220 and later*/ + case 0x15: + if (mystique->type >= MGA_1164SG) + ret = (mystique->ctrl_base >> 8) & 0xc0; + else + ret = 0x00; + break; case 0x16: - ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 16; + else + ret = (mystique->lfb_base >> 16) & 0x80; break; case 0x17: - ret = mystique->lfb_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 24; + else + ret = mystique->lfb_base >> 24; break; case 0x18: @@ -6090,7 +6100,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x34: - ret = mystique->type == MGA_G100 ? 0xdc : 0x00; + ret = (mystique->type == MGA_G100) ? 0xdc : 0x00; break; case 0x3c: @@ -6193,15 +6203,6 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; - if (mystique->type >= MGA_1164SG) - { - /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ - if (addr >= 0x10 && addr <= 0x13) - addr += 0x4; - else if (addr >= 0x14 && addr <= 0x17) - addr -= 0x4; - } - switch (addr) { case PCI_REG_COMMAND: mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; @@ -6217,27 +6218,61 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x11: - mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) + break; + else { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } break; case 0x12: - mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + break; + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } break; case 0x13: - mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + mystique->lfb_base = val << 24; + else + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; + case 0x15: + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } + break; case 0x16: - if (mystique->type >= MGA_2164W) - break; - mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } break; case 0x17: - mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; case 0x1a: @@ -6258,8 +6293,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x30) mystique->pci_regs[addr] &= 1; if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -6282,8 +6317,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x43) { if (val & 0x40) { if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); } else @@ -6557,13 +6592,11 @@ millennium_ii_available(void) return rom_present(ROM_MILLENNIUM_II); } -#if defined(DEV_BRANCH) && defined(USE_MGA2) static int matrox_g100_available(void) { return rom_present(ROM_G100); } -#endif static void mystique_speed_changed(void *priv) @@ -6701,7 +6734,6 @@ const device_t millennium_ii_device = { .config = millennium_ii_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t productiva_g100_device = { .name = "Matrox Productiva G100", .internal_name = "productiva_g100", @@ -6715,4 +6747,3 @@ const device_t productiva_g100_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; -#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 889bfa5fc..1faa04783 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -260,9 +260,7 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA2) { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, -#endif { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, From 19b8dbb1d2e1afaef4c3d9a1e5fcce7f826eba87 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 12:32:58 +0600 Subject: [PATCH 101/690] C&T: Clear bit 7 of CRTC register 0x40 on vertical blank start, fixes DirectDraw hangs --- src/video/vid_chips_69000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index eb67e16de..88ff698c7 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2202,6 +2202,7 @@ chips_69000_vblank_start(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; chips->mem_regs[1] |= 1 << 14; + chips->svga.crtc[0x40] &= ~0x80; chips_69000_interrupt(chips); } From f9aa97e1d3250dd46b624de3ceccd9066cbb9841 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 14:05:50 +0600 Subject: [PATCH 102/690] Fix text drawing on defined quadword aligned modes with CPU source --- src/video/vid_chips_69000.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 88ff698c7..a37510190 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1081,7 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } -#if 0 +#if 1 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " @@ -1107,6 +1107,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } else { chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5) + chips->bitblt_running.bitblt.monochrome_source_alignment = 0; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; } @@ -1238,7 +1241,14 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { + uint8_t val = chips->bitblt_running.bytes_port[0]; + int i = 0; + chips->bitblt_running.bytes_written = 0; + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; int i = 0, j = 0; chips->bitblt_running.bytes_written = 0; @@ -1254,8 +1264,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } } else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) - || chips->bitblt_running.bitblt.monochrome_source_alignment == 2 - || chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { + || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; From 9b070310a029513eec54ec49a8df9d09acba237e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 14:40:29 +0600 Subject: [PATCH 103/690] Disable logging --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index a37510190..e7486a684 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1081,7 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } -#if 1 +#if 0 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " From 996e365a8ce1498cd940a66120a1c9dcaa42ecf0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 15:02:05 +0600 Subject: [PATCH 104/690] Implement missing ROPs --- src/video/vid_chips_69000.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index e7486a684..57871e33f 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -475,6 +475,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -484,6 +487,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui case 0xCA: *dst ^= (pattern & (src ^ *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xDA: *dst ^= pattern & (~(src & *dst)); break; @@ -502,6 +508,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui case 0xFF: *dst = 0xFF; break; + default: + pclog("Unknown ROP 0x%X\n", rop); + break; } } @@ -513,6 +522,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src } switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; case 0x00: *dst = 0; break; @@ -572,6 +584,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -581,6 +596,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src case 0xCA: *dst ^= (pattern & (src ^ *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xDA: *dst ^= pattern & (~(src & *dst)); break; @@ -612,6 +630,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src } switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; case 0x00: *dst = 0; break; @@ -671,6 +692,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -683,6 +707,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src case 0xDA: *dst ^= pattern & (~(src & *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xEA: *dst |= pattern & src; break; @@ -853,7 +880,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.y) & 7), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips); is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); From edee5fd83950e352ac569fcd990a14c74f289407 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Fri, 16 Feb 2024 20:45:37 +0300 Subject: [PATCH 105/690] More 486 machine changes that I missed --- src/machine/m_at_386dx_486.c | 14 +++++++++----- src/machine/machine_table.c | 22 +++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5a47af620..415b7b442 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1961,19 +1961,22 @@ machine_at_actionpc2600_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 3); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_ps2_tg_ami_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&tgui9440_onboard_pci_device); + return ret; } @@ -1992,14 +1995,15 @@ machine_at_actiontower8400_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - if (gfxcard[0] == VID_INTERNAL) - pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x16, PCI_CARD_IDE, 0, 0, 0, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); device_add(&umc_8886af_device); device_add(&fdc37c665_device); + device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. device_add(&keyboard_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5b54dd506..00c776209 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5941,7 +5941,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 4096, .max = 36864, @@ -6668,7 +6668,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, /* Has internal video: Western Digital WD90C33-ZZ */ .ram = { .min = 1024, .max = 65536, @@ -6802,7 +6802,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &tgui9440_onboard_pci_device, + .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, @@ -7160,7 +7160,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, /* Has onboard video: C&T F65545 */ .ram = { .min = 1024, .max = 32768, @@ -7843,7 +7843,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 2048, .max = 261120, @@ -8003,7 +8003,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, .ram = { .min = 1024, .max = 262144, @@ -8204,7 +8204,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCIV, + .bus_flags = MACHINE_PS2_PCIV, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -8245,7 +8245,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 1024, .max = 131072, @@ -8330,7 +8330,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -8371,7 +8371,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -8412,7 +8412,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ .ram = { .min = 32768, .max = 131072, From cfa1e0d793fa30050b60d53c3ffdb7acacdcbd6e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 17 Feb 2024 15:43:52 +0600 Subject: [PATCH 106/690] C&T: Implement clock select and LCD panning properly --- src/video/vid_chips_69000.c | 55 +++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 57871e33f..f81029f57 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -205,11 +205,6 @@ chips_69000_read_flat_panel(chips_69000_t* chips) { switch (chips->flat_panel_index) { case 0: - /* Report no presence of flat panel module. */ - return 0; - case 1: - return 1; - case 0x10: return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; @@ -224,6 +219,13 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) switch (chips->flat_panel_index) { case 0: return; + case 1: + case 0x20 ... 0x33: + case 0x35: + case 0x36: + chips->flat_panel_regs[chips->flat_panel_index] = val; + svga_recalctimings(&chips->svga); + return; default: chips->flat_panel_regs[chips->flat_panel_index] = val; break; @@ -735,6 +737,8 @@ chips_69000_recalctimings(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->priv); + if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; } @@ -769,7 +773,7 @@ chips_69000_recalctimings(svga_t *svga) svga->htotal += 5; svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); - svga->hblank_end_len = 0x100; + svga->hblank_end_mask = 0xff; svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; @@ -806,8 +810,32 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } +#if 1 + if (chips->flat_panel_regs[0x01] & 0x2) { + /* TODO: Fix horizontal parameter calculations. */ + if (svga->hdisp > (((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3)) { + svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + } + if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { + svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + } + //svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + //svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + //svga->vsyncstart = ((chips->flat_panel_regs[0x31] | ((chips->flat_panel_regs[0x35] & 0xF0) << 4)) + 1); + //svga->vtotal = ((chips->flat_panel_regs[0x33] | ((chips->flat_panel_regs[0x36] & 0xF) << 8)) + 2); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((chips->flat_panel_regs[0x03] >> 2) & 3, svga->priv); + svga->hoverride = 1; + } else { + svga->hoverride = 0; + } +#endif } else { svga->bpp = 8; + svga->hoverride = 0; } } @@ -1790,7 +1818,9 @@ chips_69000_pci_read(int func, int addr, void *p) case 0x03: return 0x00; case 0x04: - return chips->pci_conf_status; + return (chips->pci_conf_status & 0b11100011) | 0x80; + case 0x06: + return 0x80; case 0x07: return 0x02; case 0x08: @@ -1840,14 +1870,12 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) { chips->pci_conf_status = val; io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - mem_mapping_disable(&chips->bios_rom.mapping); mem_mapping_disable(&chips->linear_mapping); mem_mapping_disable(&chips->svga.mapping); if (chips->pci_conf_status & PCI_COMMAND_IO) { io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); } if (chips->pci_conf_status & PCI_COMMAND_MEM) { - if (!chips->on_board) mem_mapping_enable(&chips->bios_rom.mapping); mem_mapping_enable(&chips->svga.mapping); if (chips->linear_mapping.base) mem_mapping_enable(&chips->linear_mapping); @@ -2320,13 +2348,15 @@ chips_69000_getclock(int clock, void *priv) int m = chips->ext_regs[0xc8]; int n = chips->ext_regs[0xc9]; - int pl = (chips->ext_regs[0xcb] >> 4) & 7; + int pl = ((chips->ext_regs[0xcb] >> 4) & 7); float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2)); if (chips->ext_regs[0xcb] & 4) fvco *= 4.0; float fo = fvco / (float)(1 << pl); + pclog("freq = %f\n", fo); + return fo; } @@ -2356,9 +2386,10 @@ chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) static int chips_69000_line_compare(svga_t* svga) { - /* Line compare glitches out at 1600x1200 and above. Disable it. */ - if (svga->dispend >= 1200) + const chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (chips->ext_regs[0x81] & 0xF) { return 0; + } return 1; } From fac527158c80c24cc98a77ca837904a29a426d21 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sat, 17 Feb 2024 15:22:56 +0300 Subject: [PATCH 107/690] The onboard Cirrus in the Epson ActionTower 8400 now gets loaded in the correct PCI slot --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 415b7b442..b6f2ec6d9 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -2007,7 +2007,7 @@ machine_at_actiontower8400_init(const machine_t *model) device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. device_add(&keyboard_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5430_pci_device); // VBIOS not included in BIOS ROM + device_add(&gd5430_onboard_pci_device); return ret; } From 451bc3d425ad9a568be6270d7b44baabd9051691 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:39:14 +0600 Subject: [PATCH 108/690] C&T 69000: Patterns are no longer horizontally reversed Fixes mouse dragging glitches under Windows 2000 on 16+ bpp --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index f81029f57..9ab6ba414 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -910,7 +910,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) else pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips); - is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); + is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { return; From 29c7b80fcfcb923ffbea2cf405295cddeba253da Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:43:56 +0600 Subject: [PATCH 109/690] Only skip hblank calculations when actually needed --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9ab6ba414..6a15e3a62 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -817,6 +817,7 @@ chips_69000_recalctimings(svga_t *svga) svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; //svga->hblank_end_val = svga->htotal - 1; + svga->hoverride = 1; } if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); @@ -828,7 +829,6 @@ chips_69000_recalctimings(svga_t *svga) //svga->vsyncstart = ((chips->flat_panel_regs[0x31] | ((chips->flat_panel_regs[0x35] & 0xF0) << 4)) + 1); //svga->vtotal = ((chips->flat_panel_regs[0x33] | ((chips->flat_panel_regs[0x36] & 0xF) << 8)) + 2); svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((chips->flat_panel_regs[0x03] >> 2) & 3, svga->priv); - svga->hoverride = 1; } else { svga->hoverride = 0; } From 575317fa085acdd0a86d5a6f7f9c5d517a4607ed Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:52:29 +0600 Subject: [PATCH 110/690] ...and don't otherwise --- src/video/vid_chips_69000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 6a15e3a62..0490523c9 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -818,7 +818,9 @@ chips_69000_recalctimings(svga_t *svga) //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; //svga->hblank_end_val = svga->htotal - 1; svga->hoverride = 1; - } + } else + svga->hoverride = 0; + if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); } From 4adb484184b813868b52c27c242444aad68e381b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 12:23:21 +0600 Subject: [PATCH 111/690] C&T 69000: Fix ROP 0xFF `WHITENESS` on 16+ bpp modes Fixes blue background on Write in Windows 3.11 drivers --- src/video/vid_chips_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0490523c9..9e5e74370 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -351,7 +351,7 @@ chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) *dst |= src; break; case 0xFF: - *dst = 0xFF; + *dst = 0xFFFF; break; } } @@ -405,7 +405,7 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) *dst |= src; break; case 0xFF: - *dst = 0xFF; + *dst = 0xFFFFFF; break; } } From 2928e2cf7928e364debbccbaf15b07fb8f110f12 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 16:35:32 +0600 Subject: [PATCH 112/690] C&T 69000: Make sure horizontal blank period does not exceed horizontal total Fixes machine freezes in certain circumstances --- src/video/vid_chips_69000.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9e5e74370..d35e66361 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -775,6 +775,9 @@ chips_69000_recalctimings(svga_t *svga) svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); svga->hblank_end_mask = 0xff; + if (svga->hblank_end_val >= svga->htotal) + svga->hblank_end_val = svga->htotal - 1; + svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; From 26dcf9cb7336744025a3dfaf3e9aea890e93f5a6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 11:54:11 +0100 Subject: [PATCH 113/690] Make the horizontal blanking loops no longer loop eternally. --- src/video/vid_svga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0293ebeda..b298fc4e1 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -797,7 +797,7 @@ svga_recalctimings(svga_t *svga) svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val, svga->htotal, eff_mask); - while (1) { + while (adj_dot < (svga->htotal << 1)) { if (dot == svga->htotal) dot = 0; @@ -820,7 +820,7 @@ svga_recalctimings(svga_t *svga) uint32_t eff_mask8514 = 0x0000003f; dev->hblank_sub = 0; - while (1) { + while (adj_dot8514 < (dev->h_total << 1)) { if (dot8514 == dev->h_total) dot = 0; From a0b984f79cc8a6054ca7e15be0254abfda352562 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 16:57:30 +0600 Subject: [PATCH 114/690] Revert no-longer-needed horizontal blanking changes --- src/video/vid_chips_69000.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index d35e66361..9e5e74370 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -775,9 +775,6 @@ chips_69000_recalctimings(svga_t *svga) svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); svga->hblank_end_mask = 0xff; - if (svga->hblank_end_val >= svga->htotal) - svga->hblank_end_val = svga->htotal - 1; - svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; From d789292f6566a5168e4fd5e22c0d14a3a1a50fcc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 16:37:46 +0500 Subject: [PATCH 115/690] Joystick: Remove the leftover separate slider handling --- src/include/86box/gameport.h | 8 -------- src/qt/qt_joystickconfiguration.cpp | 7 ------- src/qt/qt_settingsinput.cpp | 14 ++++---------- src/win/win_joystick.cpp | 19 ++++++++----------- src/win/win_jsconf.c | 19 ++++--------------- 5 files changed, 16 insertions(+), 51 deletions(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index ba3568464..d6e6f980a 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -36,7 +36,6 @@ #define POV_X 0x80000000 #define POV_Y 0x40000000 -#define SLIDER 0x20000000 #define AXIS_NOT_PRESENT -99999 @@ -50,7 +49,6 @@ typedef struct plat_joystick_t { int a[8]; int b[32]; int p[4]; - int s[2]; struct { char name[260]; @@ -67,15 +65,9 @@ typedef struct plat_joystick_t { int id; } pov[4]; - struct { - char name[260]; - int id; - } slider[2]; - int nr_axes; int nr_buttons; int nr_povs; - int nr_sliders; } plat_joystick_t; typedef struct joystick_t { diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index c363cd544..e03d57e09 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -118,19 +118,12 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); } - for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) { - Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0); - } - int nr_axes = plat_joystick_state[joystick].nr_axes; - int nr_povs = plat_joystick_state[joystick].nr_povs; int mapping = joystick_state[joystick_nr].axis_mapping[c]; if (mapping & POV_X) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); else if (mapping & POV_Y) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1); - else if (mapping & SLIDER) - cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3)); else cbox->setCurrentIndex(mapping); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 34d111e10..05e44c2c0 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -137,22 +137,16 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) { int axis_sel = jc.selectedAxis(axis); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) { return axis_sel; } axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index df8a99a05..17756ea94 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -36,6 +36,7 @@ plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present = 0; +int has_slider = 0; static LPDIRECTINPUT8 lpdi; static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL }; @@ -98,6 +99,10 @@ DIEnumDeviceObjectsCallback( state->axis[state->nr_axes].id = 4; else if (lpddoi->guidType == GUID_RzAxis) state->axis[state->nr_axes].id = 5; + else if (lpddoi->guidType == GUID_Slider) { + state->axis[state->nr_axes].id = 6 + has_slider; + has_slider++; + } state->nr_axes++; } } else if (lpddoi->guidType == GUID_Button) { @@ -112,13 +117,6 @@ DIEnumDeviceObjectsCallback( joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; } - } else if (lpddoi->guidType == GUID_Slider) { - if (state->nr_sliders < 2) { - memcpy(state->slider[state->nr_sliders].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - state->slider[state->nr_sliders].id = state->nr_sliders | SLIDER; - joystick_log("Slider %i : %s %x %x\n", state->nr_sliders, state->slider[state->nr_sliders].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_sliders++; - } } return DIENUM_CONTINUE; @@ -170,6 +168,7 @@ joystick_init() joystick_log(" Buttons = %i\n", devcaps.dwButtons); joystick_log(" POVs = %i\n", devcaps.dwPOVs); + has_slider = 0; lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) @@ -234,8 +233,6 @@ joystick_get_axis(int joystick_nr, int mapping) return 0; else return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & SLIDER) { - return plat_joystick_state[joystick_nr].s[mapping & 3]; } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } @@ -269,8 +266,8 @@ joystick_process(void) plat_joystick_state[c].a[3] = joystate.lRx; plat_joystick_state[c].a[4] = joystate.lRy; plat_joystick_state[c].a[5] = joystate.lRz; - plat_joystick_state[c].s[0] = joystate.rglSlider[0]; - plat_joystick_state[c].s[1] = joystate.rglSlider[1]; + plat_joystick_state[c].a[6] = joystate.rglSlider[0]; + plat_joystick_state[c].a[7] = joystate.rglSlider[1]; for (b = 0; b < 16; b++) plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 66ad60c73..416e7858d 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -54,9 +54,6 @@ rebuild_axis_button_selections(HWND hdlg) sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].slider[d].name); - } SendMessage(h, CB_SETCURSEL, sel, 0); EnableWindow(h, TRUE); } else @@ -111,21 +108,15 @@ get_axis(HWND hdlg, int id) HWND h = GetDlgItem(hdlg, id); int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) return axis_sel; axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int @@ -188,8 +179,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lPa SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); else if (mapping & POV_Y) SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else if (mapping & SLIDER) - SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0); else SendMessage(h, CB_SETCURSEL, mapping, 0); id += 2; From 394e07899105b4d8bd78769dc6b02c42c21e254f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 16:38:49 +0500 Subject: [PATCH 116/690] Joystick: Add support for more axis types to the Windows raw input backend --- src/qt/win_joystick_rawinput.c | 85 +++++++++++++++++++++++++++++---- src/win/win_joystick_rawinput.c | 63 +++++++++++++++++++++++- 2 files changed, 137 insertions(+), 11 deletions(-) diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 7ee0e8227..1a419c3ba 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -35,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -367,10 +426,10 @@ win_joystick_handle(PRAWINPUT raw) /* Read axes */ for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; + const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -395,14 +454,16 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; + const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -415,9 +476,13 @@ win_joystick_handle(PRAWINPUT raw) plat_joystick_state[j].p[p] = value; - // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#if 0 + joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#endif } - // joystick_log("\n"); +#if 0 + joystick_log("\n"); +#endif } static int diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index c5c2a3d6e..1a419c3ba 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -35,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -395,7 +454,9 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ From e51f99c800dd8c3fe844d32b6421036bc78f858d Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:08:26 +0500 Subject: [PATCH 117/690] Joystick: Replace magic numbers for maximum axes/buttons/POVs with macros --- src/include/86box/gameport.h | 34 ++++++++++++++++++--------------- src/qt/win_joystick_rawinput.c | 10 +++++----- src/win/win_joystick.cpp | 10 +++++----- src/win/win_joystick_rawinput.c | 10 +++++----- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index d6e6f980a..0fb4a0f36 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,6 +24,10 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 +#define MAX_JOY_AXES 8 +#define MAX_JOY_BUTTONS 32 +#define MAX_JOY_POVS 4 + #define JS_TYPE_NONE 0 #define JS_TYPE_2AXIS_4BUTTON 1 #define JS_TYPE_2AXIS_6BUTTON 2 @@ -46,24 +50,24 @@ typedef struct plat_joystick_t { char name[260]; - int a[8]; - int b[32]; - int p[4]; + int a[MAX_JOY_AXES]; + int b[MAX_JOY_BUTTONS]; + int p[MAX_JOY_POVS]; struct { char name[260]; int id; - } axis[8]; + } axis[MAX_JOY_AXES]; struct { char name[260]; int id; - } button[32]; + } button[MAX_JOY_BUTTONS]; struct { char name[260]; int id; - } pov[4]; + } pov[MAX_JOY_POVS]; int nr_axes; int nr_buttons; @@ -71,14 +75,14 @@ typedef struct plat_joystick_t { } plat_joystick_t; typedef struct joystick_t { - int axis[8]; - int button[32]; - int pov[4]; + int axis[MAX_JOY_AXES]; + int button[MAX_JOY_BUTTONS]; + int pov[MAX_JOY_POVS]; int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; + int axis_mapping[MAX_JOY_AXES]; + int button_mapping[MAX_JOY_BUTTONS]; + int pov_mapping[MAX_JOY_POVS][2]; } joystick_t; typedef struct joystick_if_t { @@ -96,9 +100,9 @@ typedef struct joystick_if_t { int button_count; int pov_count; int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; + const char *axis_names[MAX_JOY_AXES]; + const char *button_names[MAX_JOY_BUTTONS]; + const char *pov_names[MAX_JOY_POVS]; } joystick_if_t; #ifdef __cplusplus diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 1a419c3ba..bb05c3f5c 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -88,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -108,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -121,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -206,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 17756ea94..9b264a700 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -84,7 +84,7 @@ DIEnumDeviceObjectsCallback( plat_joystick_t *state = (plat_joystick_t *) pvRef; if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis) { - if (state->nr_axes < 8) { + if (state->nr_axes < MAX_JOY_AXES) { memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); if (lpddoi->guidType == GUID_XAxis) @@ -106,13 +106,13 @@ DIEnumDeviceObjectsCallback( state->nr_axes++; } } else if (lpddoi->guidType == GUID_Button) { - if (state->nr_buttons < 32) { + if (state->nr_buttons < MAX_JOY_BUTTONS) { memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_buttons++; } } else if (lpddoi->guidType == GUID_POV) { - if (state->nr_povs < 4) { + if (state->nr_povs < MAX_JOY_POVS) { memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; @@ -269,10 +269,10 @@ joystick_process(void) plat_joystick_state[c].a[6] = joystate.rglSlider[0]; plat_joystick_state[c].a[7] = joystate.rglSlider[1]; - for (b = 0; b < 16; b++) + for (b = 0; b < MAX_JOY_BUTTONS; b++) plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - for (b = 0; b < 4; b++) + for (b = 0; b < MAX_JOY_POVS; b++) plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; // joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index 1a419c3ba..bb05c3f5c 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -88,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -108,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -121,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -206,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); From 0fa364dec34dbbf9223fd8aeab66993f62842fbc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 19:12:57 +0500 Subject: [PATCH 118/690] MGA cleanup --- CMakeLists.txt | 1 - src/video/CMakeLists.txt | 4 ---- src/video/vid_mga.c | 2 -- src/win/Makefile.mingw | 10 ---------- 4 files changed, 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f13e91791..196952cb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index dc0cac1ff..8fbd62e35 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA2) - target_compile_definitions(vid PRIVATE USE_MGA2) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 89b036ede..b85eb5ad9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2811,7 +2811,6 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; - mystique_t *mystique = (mystique_t *) svga->priv; cycles -= svga->monitor->mon_video_timing_read_b; @@ -2861,7 +2860,6 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - mystique_t *mystique = (mystique_t *) svga->priv; cycles -= svga->monitor->mon_video_timing_write_b; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 94b8af74a..a80458938 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,9 +64,6 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA2 - MGA2 := y - endif ifndef OLIVETTI OLIVETTI := y endif @@ -131,9 +128,6 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA2 - MGA2 := n - endif ifndef OLIVETTI OLIVETTI := n endif @@ -502,10 +496,6 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif - ifeq ($(MGA2), y) - OPTS += -DUSE_MGA2 - endif - ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From f13cf419950deadd1e8dfd8b7d5931ee0f84f630 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:26:28 +0500 Subject: [PATCH 119/690] Joystick: Properly limit maximum axes/buttons/POVs in the SDL backend Axes beyond 6 are now actually working --- src/qt/sdl_joystick.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index cdbf102b8..4437bb696 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -36,19 +36,19 @@ joystick_init() int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); - plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); + plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); + plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); - for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { + for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { + for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) { snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d); plat_joystick_state[c].button[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { + for (d = 0; d < plat_joystick_state[c].nr_povs; d++) { snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d); plat_joystick_state[c].pov[d].id = d; } @@ -116,17 +116,13 @@ joystick_process() for (c = 0; c < joysticks_present; c++) { int b; - plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); - plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); - plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); - plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); - plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); - plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + for (b = 0; b < plat_joystick_state[c].nr_axes; b++) + plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b); - for (b = 0; b < 16; b++) + for (b = 0; b < plat_joystick_state[c].nr_buttons; b++) plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); - for (b = 0; b < 4; b++) + for (b = 0; b < plat_joystick_state[c].nr_povs; b++) plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } From c74ad5b4da570e95762cd47e122d7da0449cfc31 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:34:40 +0500 Subject: [PATCH 120/690] Joystick: Increase the maximum number of supported axes to 16 --- src/include/86box/gameport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 0fb4a0f36..48d639cf0 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,7 +24,7 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 -#define MAX_JOY_AXES 8 +#define MAX_JOY_AXES 16 #define MAX_JOY_BUTTONS 32 #define MAX_JOY_POVS 4 From 643979c0b7f8133c2d5e89f68c69fb30148e9caf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:28:29 +0500 Subject: [PATCH 121/690] Merge joystick_*.h into gameport.h Just like it was done to all headers with only device declarations years ago --- src/game/gameport.c | 4 -- src/game/joystick_ch_flightstick_pro.c | 1 - src/game/joystick_standard.c | 1 - src/game/joystick_sw_pad.c | 1 - src/game/joystick_tm_fcs.c | 1 - src/include/86box/gameport.h | 13 +++++ .../86box/joystick_ch_flightstick_pro.h | 43 ---------------- src/include/86box/joystick_standard.h | 49 ------------------- src/include/86box/joystick_sw_pad.h | 43 ---------------- src/include/86box/joystick_tm_fcs.h | 43 ---------------- 10 files changed, 13 insertions(+), 186 deletions(-) delete mode 100644 src/include/86box/joystick_ch_flightstick_pro.h delete mode 100644 src/include/86box/joystick_standard.h delete mode 100644 src/include/86box/joystick_sw_pad.h delete mode 100644 src/include/86box/joystick_tm_fcs.h diff --git a/src/game/gameport.c b/src/game/gameport.c index 323555984..58d9a446f 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -31,10 +31,6 @@ #include <86box/timer.h> #include <86box/isapnp.h> #include <86box/gameport.h> -#include <86box/joystick_ch_flightstick_pro.h> -#include <86box/joystick_standard.h> -#include <86box/joystick_sw_pad.h> -#include <86box/joystick_tm_fcs.h> #include <86box/plat_unused.h> typedef struct g_axis_t { diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 49ce824bc..8ca51d531 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index b9c449f99..1d1568738 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 5c91ee1e9..7962c38e3 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -64,7 +64,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_sw_pad.h> #include <86box/plat_unused.h> typedef struct sw_data { diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index d54d0e37d..f5c1e64e6 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 48d639cf0..d9c702394 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -154,6 +154,19 @@ extern void gameport_update_joystick_type(void); extern void gameport_remap(void *priv, uint16_t address); extern void *gameport_add(const device_t *gameport_type); +extern const joystick_if_t joystick_2axis_2button; +extern const joystick_if_t joystick_2axis_4button; +extern const joystick_if_t joystick_3axis_2button; +extern const joystick_if_t joystick_3axis_4button; +extern const joystick_if_t joystick_4axis_4button; +extern const joystick_if_t joystick_2axis_6button; +extern const joystick_if_t joystick_2axis_8button; + +extern const joystick_if_t joystick_ch_flightstick_pro; + +extern const joystick_if_t joystick_sw_pad; + +extern const joystick_if_t joystick_tm_fcs; #ifdef __cplusplus } #endif diff --git a/src/include/86box/joystick_ch_flightstick_pro.h b/src/include/86box/joystick_ch_flightstick_pro.h deleted file mode 100644 index b49800ecb..000000000 --- a/src/include/86box/joystick_ch_flightstick_pro.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Flight Stick Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H -#define EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H - -extern const joystick_if_t joystick_ch_flightstick_pro; - -#endif /*EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H*/ diff --git a/src/include/86box/joystick_standard.h b/src/include/86box/joystick_standard.h deleted file mode 100644 index c874677ea..000000000 --- a/src/include/86box/joystick_standard.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Definitions for the joystick driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_STANDARD_H -#define EMU_JOYSTICK_STANDARD_H - -extern const joystick_if_t joystick_2axis_2button; -extern const joystick_if_t joystick_2axis_4button; -extern const joystick_if_t joystick_3axis_2button; -extern const joystick_if_t joystick_3axis_4button; -extern const joystick_if_t joystick_4axis_4button; -extern const joystick_if_t joystick_2axis_6button; -extern const joystick_if_t joystick_2axis_8button; - -#endif /*EMU_JOYSTICK_STANDARD_H*/ diff --git a/src/include/86box/joystick_sw_pad.h b/src/include/86box/joystick_sw_pad.h deleted file mode 100644 index a75d802de..000000000 --- a/src/include/86box/joystick_sw_pad.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Sidewinder Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_SW_PAD_H -#define EMU_JOYSTICK_SW_PAD_H - -extern const joystick_if_t joystick_sw_pad; - -#endif /*EMU_JOYSTICK_SW_PAD_H*/ diff --git a/src/include/86box/joystick_tm_fcs.h b/src/include/86box/joystick_tm_fcs.h deleted file mode 100644 index 65e734a40..000000000 --- a/src/include/86box/joystick_tm_fcs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Flight Control System driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_TM_FCS_H -#define EMU_JOYSTICK_TM_FCS_H - -extern const joystick_if_t joystick_tm_fcs; - -#endif /*EMU_JOYSTICK_TM_FCS_H*/ From 4c3cceec693ea1ac38e667e3d47530ee2522e05c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 17:54:14 +0100 Subject: [PATCH 122/690] Fixed off by one errors in (S)VGA horizontal blanking start calculation. --- src/video/vid_8514a.c | 2 +- src/video/vid_ati28800.c | 5 ++--- src/video/vid_ati_mach64.c | 2 +- src/video/vid_ati_mach8.c | 4 ++-- src/video/vid_chips_69000.c | 6 +++--- src/video/vid_cl54xx.c | 4 ++-- src/video/vid_et4000.c | 8 +++----- src/video/vid_et4000w32.c | 2 +- src/video/vid_ht216.c | 2 +- src/video/vid_mga.c | 2 +- src/video/vid_s3.c | 8 ++++---- src/video/vid_s3_virge.c | 4 ++-- src/video/vid_svga.c | 2 +- src/video/vid_voodoo_banshee.c | 11 ++++------- 14 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 3505d1e0b..a94b974b0 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -914,7 +914,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + dev->hblankstart = (dev->hsync_start & 0x07); } } ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index be9654aca..368312fcb 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -408,7 +408,7 @@ ati28800_recalctimings(svga_t *svga) int clock_sel; if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2]; clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); @@ -492,8 +492,7 @@ ati28800_recalctimings(svga_t *svga) else { svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; svga->rowoffset <<= 1; svga->ma_latch <<= 1; } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index cdd906067..9aa396383 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -516,7 +516,7 @@ mach64_recalctimings(svga_t *svga) svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->hblankstart = (mach64->crtc_h_sync_strt_wid & 255) + - ((mach64->crtc_h_sync_strt_wid >> 8) & 7) + 1; + ((mach64->crtc_h_sync_strt_wid >> 8) & 7); svga->hblank_end_val = (svga->hblankstart + ((mach64->crtc_h_sync_strt_wid >> 16) & 31) - 1) & 63; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 5628e149a..b49806177 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2547,7 +2547,7 @@ mach_recalctimings(svga_t *svga) int clock_sel; if (mach->regs[0xad] & 0x08) - svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2]; clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); @@ -3636,7 +3636,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + dev->hblankstart = (dev->hsync_start & 0x07); } } mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9e5e74370..04a543884 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1886,10 +1886,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { + // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { chips->linear_mapping.base = val << 24; - break; - } + // break; + // } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 5d376effe..e83d4593f 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1750,7 +1750,7 @@ gd54xx_recalctimings(svga_t *svga) uint8_t rdmask; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { /* Special blanking mode: the blank start and end become components of the window generator, @@ -1763,7 +1763,7 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_mask = 0x000000ff; if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 6d52fc91b..fa671e2f6 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -650,7 +650,7 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; @@ -690,14 +690,12 @@ et4000_recalctimings(svga_t *svga) case 15: case 16: svga->hdisp /= 2; - svga->hblankstart /= 2; - svga->hblank_end_val /= 2; + svga->dots_per_clock /= 2; break; case 24: svga->hdisp /= 3; - svga->hblankstart /= 3; - svga->hblank_end_val /= 3; + svga->dots_per_clock /= 3; break; default: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 259fefffb..7adb6bc89 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -432,7 +432,7 @@ et4000w32p_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 35d335ed2..b87d93665 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -714,7 +714,7 @@ ht216_recalctimings(svga_t *svga) svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; if (ht216->ht_regs[0xe0] & 0x20) - svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4]; } static void diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b85eb5ad9..f40385fef 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -945,7 +945,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; - svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2]; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 41e21faa9..27c364898 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3312,7 +3312,7 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -3324,7 +3324,7 @@ s3_recalctimings(svga_t *svga) if (s3->chip >= S3_VISION964) svga->hblank_end_mask = 0x7f; } else if (s3->chip >= S3_86C801) { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; if (s3->chip >= S3_VISION964) { /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? @@ -4160,7 +4160,7 @@ s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -4169,7 +4169,7 @@ s3_trio64v_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 1cb6424fb..be6382ec9 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -827,7 +827,7 @@ s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -836,7 +836,7 @@ s3_virge_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b298fc4e1..d0f02929d 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -750,7 +750,7 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); svga->hblank_end_mask = 0x0000003f; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index f03f6efd4..098e919d4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -558,10 +558,10 @@ banshee_recalctimings(svga_t *svga) that is, no overscan and relying on display end to blank. */ if (banshee->vgaInit0 & 0x40) { svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + - (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + (((svga->crtc[0x1a] & 0x04) >> 2) << 8); svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/; svga->hblank_end_mask = 0x0000003f; } svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; @@ -579,12 +579,12 @@ banshee_recalctimings(svga_t *svga) svga->linedbl = 0; } else { if (banshee->vgaInit0 & 0x40) { - svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x1a] & 0x20) >> 5) << 6); svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5); svga->hblank_end_mask = 0x0000003f; } @@ -652,9 +652,6 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; - // svga->htotal *= 2; - // svga->hblankstart *= 2; - // svga->hblank_end_val *= 2; svga->dots_per_clock *= 2; } From fc63c26e04447c0cff375bf9c01f47ac9a19765e Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 18 Feb 2024 20:02:01 +0300 Subject: [PATCH 123/690] Merge network device headers to network.h --- src/include/86box/net_3c501.h | 45 ----------------------------- src/include/86box/net_3c503.h | 49 ------------------------------- src/include/86box/net_ne2000.h | 9 ------ src/include/86box/net_pcnet.h | 8 ------ src/include/86box/net_plip.h | 26 ----------------- src/include/86box/net_rtl8139.h | 1 - src/include/86box/net_tulip.h | 4 --- src/include/86box/net_wd8003.h | 7 ----- src/include/86box/network.h | 51 +++++++++++++++++++++++++++++++++ src/lpt.c | 5 +++- src/machine/machine_table.c | 4 ++- src/network/net_3c501.c | 1 - src/network/net_3c503.c | 1 - src/network/net_plip.c | 1 - src/network/net_rtl8139.c | 1 - src/network/net_tulip.c | 1 - src/network/network.c | 5 ---- 17 files changed, 58 insertions(+), 161 deletions(-) delete mode 100644 src/include/86box/net_3c501.h delete mode 100644 src/include/86box/net_3c503.h delete mode 100644 src/include/86box/net_plip.h delete mode 100644 src/include/86box/net_rtl8139.h delete mode 100644 src/include/86box/net_tulip.h diff --git a/src/include/86box/net_3c501.h b/src/include/86box/net_3c501.h deleted file mode 100644 index c55151ab8..000000000 --- a/src/include/86box/net_3c501.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 Project. - * - * Implementation of the following network controller: - * - 3Com Etherlink 3c500/3c501 (ISA 8-bit). - * - * - * - * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) - * - * Authors: TheCollector1995, - * Oracle - * - * Copyright 2022 TheCollector1995. - * Portions Copyright (C) 2022 Oracle and/or its affilitates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C501_H -#define NET_3C501_H - -extern const device_t threec501_device; - -#endif /*NET_3C501_H*/ diff --git a/src/include/86box/net_3c503.h b/src/include/86box/net_3c503.h deleted file mode 100644 index 44024850f..000000000 --- a/src/include/86box/net_3c503.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the following network controllers: - * - 3Com Etherlink II 3c503 (ISA 8-bit). - * - * - * - * Based on @(#)3c503.cpp Carl (MAME) - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * Carl, - * - * Copyright 2018 TheCollector1995. - * Copyright 2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Portions Copyright (C) 2018 MAME Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C503_H -#define NET_3C503_H - -extern const device_t threec503_device; - -#endif /*NET_3C503_H*/ diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index 907f1e9c1..fe1a71934 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -48,13 +48,4 @@ enum { NE2K_RTL8029AS = 8 /* 32-bit PCI Realtek 8029AS */ }; -extern const device_t ne1000_device; -extern const device_t ne1000_compat_device; -extern const device_t ne2000_device; -extern const device_t ne2000_compat_device; -extern const device_t ethernext_mc_device; -extern const device_t rtl8019as_device; -extern const device_t de220p_device; -extern const device_t rtl8029as_device; - #endif /*NET_NE2000_H*/ diff --git a/src/include/86box/net_pcnet.h b/src/include/86box/net_pcnet.h index 23ee643ed..994d88c75 100644 --- a/src/include/86box/net_pcnet.h +++ b/src/include/86box/net_pcnet.h @@ -30,12 +30,4 @@ enum { DEV_AM79C973 = 6 /* PCnet-FAST III (PCI, 10/100 Mbps) */ }; -extern const device_t pcnet_am79c960_device; -extern const device_t pcnet_am79c960_eb_device; -extern const device_t pcnet_am79c960_vlb_device; -extern const device_t pcnet_am79c961_device; -extern const device_t pcnet_am79c970a_device; -extern const device_t pcnet_am79c973_device; -extern const device_t pcnet_am79c973_onboard_device; - #endif /*NET_PCNET_H*/ diff --git a/src/include/86box/net_plip.h b/src/include/86box/net_plip.h deleted file mode 100644 index 83c33e4c6..000000000 --- a/src/include/86box/net_plip.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - * - * Definitions for the PLIP parallel port network device. - * - * - * - * Authors: RichardG, - * - * Copyright 2020 RichardG. - */ - -#ifndef NET_PLIP_H -#define NET_PLIP_H -#include <86box/device.h> -#include <86box/lpt.h> - -extern const lpt_device_t lpt_plip_device; -extern const device_t plip_device; - -#endif /*NET_PLIP_H*/ diff --git a/src/include/86box/net_rtl8139.h b/src/include/86box/net_rtl8139.h deleted file mode 100644 index f44d0facb..000000000 --- a/src/include/86box/net_rtl8139.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t rtl8139c_plus_device; diff --git a/src/include/86box/net_tulip.h b/src/include/86box/net_tulip.h deleted file mode 100644 index 2ee7ec3c1..000000000 --- a/src/include/86box/net_tulip.h +++ /dev/null @@ -1,4 +0,0 @@ -extern const device_t dec_tulip_device; -extern const device_t dec_tulip_21140_device; -extern const device_t dec_tulip_21140_vpc_device; -extern const device_t dec_tulip_21040_device; diff --git a/src/include/86box/net_wd8003.h b/src/include/86box/net_wd8003.h index 726510cdb..6797c7d88 100644 --- a/src/include/86box/net_wd8003.h +++ b/src/include/86box/net_wd8003.h @@ -54,11 +54,4 @@ enum { WD8013EPA = 6 }; -extern const device_t wd8003e_device; -extern const device_t wd8003eb_device; -extern const device_t wd8013ebt_device; -extern const device_t wd8003eta_device; -extern const device_t wd8003ea_device; -extern const device_t wd8013epa_device; - #endif /*NET_WD8003_H*/ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index e9b703ee0..d0af3f09b 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -192,12 +192,63 @@ extern int network_card_available(int); extern int network_card_has_config(int); extern const char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); +#ifdef EMU_DEVICE_H extern const device_t *network_card_getdevice(int); +#endif extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt); extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size); extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len); extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt); + +#ifdef EMU_DEVICE_H +/* 3Com Etherlink */ +extern const device_t threec501_device; +extern const device_t threec503_device; + +/* Novell NE2000 and compatibles */ +extern const device_t ne1000_device; +extern const device_t ne1000_compat_device; +extern const device_t ne2000_device; +extern const device_t ne2000_compat_device; +extern const device_t ethernext_mc_device; +extern const device_t rtl8019as_device; +extern const device_t de220p_device; +extern const device_t rtl8029as_device; + +/* AMD PCnet*/ +extern const device_t pcnet_am79c960_device; +extern const device_t pcnet_am79c960_eb_device; +extern const device_t pcnet_am79c960_vlb_device; +extern const device_t pcnet_am79c961_device; +extern const device_t pcnet_am79c970a_device; +extern const device_t pcnet_am79c973_device; +extern const device_t pcnet_am79c973_onboard_device; + +/* PLIP */ +#ifdef EMU_LPT_H +extern const lpt_device_t lpt_plip_device; +#endif +extern const device_t plip_device; + +/* Realtek RTL8139C+ */ +extern const device_t rtl8139c_plus_device; + +/* DEC Tulip */ +extern const device_t dec_tulip_device; +extern const device_t dec_tulip_21140_device; +extern const device_t dec_tulip_21140_vpc_device; +extern const device_t dec_tulip_21040_device; + +/* WD 80x3 */ +extern const device_t wd8003e_device; +extern const device_t wd8003eb_device; +extern const device_t wd8013ebt_device; +extern const device_t wd8003eta_device; +extern const device_t wd8003ea_device; +extern const device_t wd8013epa_device; +#endif + #ifdef __cplusplus } #endif diff --git a/src/lpt.c b/src/lpt.c index dd77b3516..419e5ad3d 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -11,7 +11,10 @@ #include <86box/pic.h> #include <86box/sound.h> #include <86box/prt_devs.h> -#include <86box/net_plip.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/network.h> lpt_port_t lpt_ports[PARALLEL_MAX]; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 00c776209..d6849c7ac 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -33,7 +33,9 @@ #include <86box/sound.h> #include <86box/video.h> #include <86box/plat_unused.h> -#include <86box/net_pcnet.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> // Temporarily here till we move everything out into the right files extern const device_t pcjr_device; diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c index 5b9fc0cac..868ee036f 100644 --- a/src/network/net_3c501.c +++ b/src/network/net_3c501.c @@ -56,7 +56,6 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> #include <86box/bswap.h> #include <86box/plat_unused.h> diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index d01b423ae..11e823326 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -60,7 +60,6 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_dp8390.h> -#include <86box/net_3c503.h> #include <86box/bswap.h> #include <86box/plat_unused.h> diff --git a/src/network/net_plip.c b/src/network/net_plip.c index f622d455b..41e5502a6 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -34,7 +34,6 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_plip.h> #include <86box/plat_unused.h> enum { diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 8afb7b4b8..a7c007115 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,6 @@ #include <86box/bswap.h> #include <86box/nvr.h> #include "cpu.h" -#include <86box/net_rtl8139.h> #include <86box/plat_unused.h> #define PCI_PERIOD 30 /* 30 ns period = 33.333333 Mhz frequency */ diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 5fed7f1d1..ffc342e81 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -32,7 +32,6 @@ #include <86box/thread.h> #include <86box/network.h> #include <86box/net_eeprom_nmc93cxx.h> -#include <86box/net_tulip.h> #include <86box/bswap.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> diff --git a/src/network/network.c b/src/network/network.c index 6b3a9fd1c..9eb537e3a 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -67,14 +67,9 @@ #include <86box/ui.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> -#include <86box/net_3c503.h> #include <86box/net_ne2000.h> #include <86box/net_pcnet.h> -#include <86box/net_plip.h> #include <86box/net_wd8003.h> -#include <86box/net_tulip.h> -#include <86box/net_rtl8139.h> #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN From 173007edce45050f19d2d2b7b55a36f289db54ab Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 19:55:13 +0500 Subject: [PATCH 124/690] Remove libvncserver from dependencies on GHA It's useless since VNC renderer is disabled there anyway --- .github/workflows/c-cpp.yml | 1 - .github/workflows/cmake_linux.yml | 1 - .github/workflows/cmake_macos.yml | 1 - .github/workflows/cmake_windows_msys2.yml | 1 - .github/workflows/codeql_linux.yml | 1 - .github/workflows/codeql_macos.yml | 1 - .github/workflows/codeql_windows_msys2.yml | 1 - 7 files changed, 7 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 2a22a19cf..fd81701a7 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -94,7 +94,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index c09789bfc..12cb21303 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -80,7 +80,6 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev - libvncserver-dev ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 7a6edcde9..e51c652a4 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -82,7 +82,6 @@ jobs: rtmidi openal-soft fluidsynth - libvncserver ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 46fc25b67..c7d77307c 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -104,7 +104,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index a97951abf..d92d11767 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -83,7 +83,6 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev - libvncserver-dev ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 724bdc6f6..cef8c4828 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -76,7 +76,6 @@ jobs: rtmidi openal-soft fluidsynth - libvncserver ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 5b0c2485f..dc18544c7 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -110,7 +110,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p ${{ matrix.ui.packages }} - name: Checkout repository From 6cd80ade0138b655a0b45317a06872dbc147072e Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 18 Feb 2024 21:33:46 +0300 Subject: [PATCH 125/690] Fix ActionPC onboard PCI slots --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b6f2ec6d9..63f59cb07 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1963,9 +1963,9 @@ machine_at_actionpc2600_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 3); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); From 873d8791e21b805c8053c68e3406bac347fbc2b7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 21:34:13 +0100 Subject: [PATCH 126/690] Override the (S)VGA blanking calculation for the S3 Trio32, Trio64, Trio64V+, and Trio64 V2/DX. --- src/video/vid_s3.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 27c364898..e387245c9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -4093,6 +4093,11 @@ s3_recalctimings(svga_t *svga) } } } + + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64)) + svga->hoverride = 1; + else + svga->hoverride = 0; } static void @@ -4271,6 +4276,8 @@ s3_trio64v_recalctimings(svga_t *svga) break; } } + + svga->hoverride = 1; } static void From cfebf4439b777036826d7a0c8eec321d801b779e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 04:19:55 +0600 Subject: [PATCH 127/690] C&T 69000: avoid stale linear mappings --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 04a543884..b649e41e5 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1887,7 +1887,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) case 0x13: { // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { - chips->linear_mapping.base = val << 24; + // chips->linear_mapping.base = val << 24; // break; // } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); From 91aa53d8a6bfda4fb43ee33c953d7c4edb942e66 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 04:31:08 +0600 Subject: [PATCH 128/690] More correct linear mapping behaviour --- src/video/vid_chips_69000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index b649e41e5..606001056 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1886,10 +1886,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { - // chips->linear_mapping.base = val << 24; - // break; - // } + if (!chips->linear_mapping.enable) { + chips->linear_mapping.base = val << 24; + break; + } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } From 6f22d58a4f4cbc10e4f513e8a9d32735def7d17e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 16:01:49 +0600 Subject: [PATCH 129/690] C&T 69000: Fix pattern drawing in 16-bpp modes --- src/video/vid_chips_69000.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 606001056..0708c7bc5 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -881,6 +881,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint32_t dest_pixel = 0; uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; + uint8_t orig_dest_addr_bit = chips->bitblt_running.bitblt.destination_addr & 1; switch (chips->bitblt_running.bytes_per_pixel) { case 1: /* 8 bits-per-pixel. */ @@ -903,8 +904,9 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } - /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ - /* Also: is horizontal pattern alignment a requirement? */ + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr >>= 1; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { uint8_t is_true = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) @@ -915,6 +917,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } return; } @@ -928,9 +934,13 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); } if (chips->bitblt_running.bytes_per_pixel == 2) { - pattern_pixel = chips_69000_readw_linear(chips->bitblt_running.bitblt.pat_addr + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; } if (chips->bitblt_running.bytes_per_pixel == 3) { pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr @@ -946,6 +956,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; } } + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { From 10c744d66547f7967d7b2642cab8bd0a45e45e48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 16:07:14 +0600 Subject: [PATCH 130/690] Remove frequency logging --- src/video/vid_chips_69000.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0708c7bc5..0eee90486 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2371,8 +2371,6 @@ chips_69000_getclock(int clock, void *priv) fvco *= 4.0; float fo = fvco / (float)(1 << pl); - pclog("freq = %f\n", fo); - return fo; } From 19f6954410ea21bcb19d834ff0b2994499fd546b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 15:20:59 +0100 Subject: [PATCH 131/690] Reverted some CPU-related changes. --- src/cpu/386_common.c | 10 ++++++++-- src/cpu/x86seg.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 77d984048..beb6869e9 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1539,7 +1539,10 @@ x86_int_sw(int num) } } - trap &= ~1; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); } @@ -1582,7 +1585,10 @@ x86_int_sw_rm(int num) #endif cycles -= timing_int_rm; - trap &= ~1; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); return 0; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 245f3fa65..c50c97a39 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2286,10 +2286,14 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) op_loadseg(new_fs, &cpu_state.seg_fs); op_loadseg(new_gs, &cpu_state.seg_gs); - rf_flag_no_clear = 1; + if (!cpu_use_exec) + rf_flag_no_clear = 1; if (t_bit) { - trap |= 2; + if (cpu_use_exec) + trap = 2; + else + trap |= 2; #ifdef USE_DYNAREC cpu_block_end = 1; #endif @@ -2469,7 +2473,8 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.limit = limit; tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; - dr[7] &= 0xFFFFFFAA; + if (!cpu_use_exec) + dr[7] &= 0xFFFFFFAA; } void From e3e30e7536683fa2cbe64b025efc877da0d67dd7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 15:41:49 +0100 Subject: [PATCH 132/690] Fixed a very stupid typo in the 286/386 version of the LOCK instruction that was breaking OS/2 Warp 3.0. --- src/cpu/x86_ops_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 8e9c9f785..dd05fb9d9 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -763,7 +763,7 @@ opLOCK(uint32_t fetchdat) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ break; case 0xfe ... 0xff: - legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; if (legal == 1) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ break; From 733c26d04a4aa2c62a14f0ff066a70267b53f0b6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 19:09:35 +0100 Subject: [PATCH 133/690] Return no mask when the TSS type is 286, closes #4177. --- src/cpu/386_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index beb6869e9..847408ba8 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1605,6 +1605,9 @@ checkio(uint32_t port, int mask) { uint32_t t; + if (!(tr.access & 0x08)) + return 0; + cpl_override = 1; t = readmemw(tr.base, 0x66); From 78dd6039518eb3fdd03ebd39852c1270eb433818 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Feb 2024 07:26:44 +0100 Subject: [PATCH 134/690] Minor change to FDC37C6xx. --- src/sio/sio_fdc37c6xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 22b88615d..c1fb2c1a5 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -396,7 +396,7 @@ const device_t fdc37c661_ide_device = { const device_t fdc37c661_ide_sec_device = { .name = "SMC FDC37C661 Super I/O (With Secondary IDE)", - .internal_name = "fdc37c661_ide", + .internal_name = "fdc37c661_ide_sec", .flags = 0, .local = 0x261, .init = fdc37c6xx_init, From 963b7eec042a048327edf740e06e6b553ab0e4b6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 20 Feb 2024 18:41:51 +0100 Subject: [PATCH 135/690] Some temporary video changes regarding the horizontal display. S3 side: Temporary changes to match the release (due to tomorrow) of 86box. Said changes are about the horizontal display of the tvp3026-based S3 chips. IBM/ATI 8514-based: Temporarily commented out the hblank side of it due to htotal bugs. TVP3026 side: When the upper clock selection bits are 0 and when extended VGA modes are set, double the hdisp. --- src/video/vid_s3.c | 27 ++++++++++++--- src/video/vid_svga.c | 43 ++++++++++++----------- src/video/vid_tvp3026_ramdac.c | 63 ++++------------------------------ 3 files changed, 52 insertions(+), 81 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e387245c9..0ef48fa0e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3214,7 +3214,6 @@ s3_recalctimings(svga_t *svga) } svga->hdisp = svga->hdisp_old; - svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { @@ -3222,7 +3221,7 @@ s3_recalctimings(svga_t *svga) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * svga->dots_per_clock; + svga->hdisp |= (0x100 * svga->dots_per_clock); } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3442,8 +3441,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { - case S3_PHOENIX_VISION968: + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; if (svga->hdisp == 832) @@ -3619,8 +3623,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -3801,8 +3810,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -4003,8 +4017,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -4165,7 +4184,7 @@ s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3) + 1*/; + ((svga->crtc[3] >> 5) & 3)*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d0f02929d..d9c2ba892 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -794,8 +794,8 @@ svga_recalctimings(svga_t *svga) uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f; svga->hblank_sub = 0; - svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val, - svga->htotal, eff_mask); + svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, svga->hblankstart, svga->hblank_end_val, + svga->htotal, eff_mask, adj_dot); while (adj_dot < (svga->htotal << 1)) { if (dot == svga->htotal) @@ -804,6 +804,7 @@ svga_recalctimings(svga_t *svga) if (adj_dot >= svga->htotal) svga->hblank_sub++; + svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, svga->hblank_end_val); if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask)) break; @@ -812,32 +813,34 @@ svga_recalctimings(svga_t *svga) } svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } - if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000003f; - dev->hblank_sub = 0; +#ifdef TBD + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; - while (adj_dot8514 < (dev->h_total << 1)) { - if (dot8514 == dev->h_total) - dot = 0; + while (adj_dot8514 < (dev->h_total << 1)) { + if (dot8514 == dev->h_total) + dot8514 = 0; - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) - break; + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; - dot8514++; - adj_dot8514++; - } - - dev->h_disp -= dev->hblank_sub; + dot8514++; + adj_dot8514++; } + + dev->h_disp -= dev->hblank_sub; } } +#endif if (svga->hdisp >= 2048) svga->monitor->mon_overscan_x = 0; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 625adfe41..cd3ff7e8b 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -65,7 +65,7 @@ typedef struct tvp3026_ramdac_t { static void tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) { - if ((ramdac->true_color & 0x80) == 0x80) { + if (ramdac->true_color & 0x80) { if (ramdac->mcr & 0x08) svga->bpp = 8; else @@ -514,67 +514,16 @@ tvp3026_recalctimings(void *priv, svga_t *svga) { const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; - svga->interlace = (ramdac->ccr & 0x40); + svga->interlace = !!(ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); - switch (ramdac->mcr) { - case 0x41: - case 0x4a: - case 0x61: + pclog("MCR=0x%02x, truecolor=0x%02x, crtc1=0x%02x, MCLK=0x%02x, ClockSel=%x.\n", ramdac->mcr, ramdac->true_color, svga->crtc[1] + 1, ramdac->mclk & 0x7f, ramdac->clock_sel); + if (!(ramdac->clock_sel & 0x70)) { + if (ramdac->mcr != 0x98) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; - break; - case 0x42: - case 0x4b: - case 0x62: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 0x43: - case 0x4c: - case 0x63: - svga->hdisp <<= 3; - svga->dots_per_clock <<= 3; - break; - case 0x44: - case 0x64: - svga->hdisp <<= 4; - svga->dots_per_clock <<= 4; - break; - case 0x5b: - switch (ramdac->true_color) { - case 0x16: - case 0x17: - svga->hdisp = (svga->hdisp << 2) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 2) / 3; - break; - case 0x1e: - case 0x1f: - svga->hdisp = (svga->hdisp * 5) >> 2; - svga->dots_per_clock = (svga->dots_per_clock * 5) >> 2; - break; - } - break; - case 0x5c: - switch (ramdac->true_color) { - case 0x06: - case 0x07: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 0x16: - case 0x17: - svga->hdisp = (svga->hdisp << 3) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 3) / 3; - break; - case 0x1e: - case 0x1f: - svga->hdisp = (svga->hdisp * 5) >> 1; - svga->dots_per_clock = (svga->dots_per_clock * 5) >> 1; - break; - } - break; + } } } From 8b4fb1b2abb2b12603cef9ae3aac04e268914226 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 20 Feb 2024 19:11:47 +0100 Subject: [PATCH 136/690] TVP3026: remove excess logs. See above. --- src/video/vid_tvp3026_ramdac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index cd3ff7e8b..b50d0406b 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -518,7 +518,6 @@ tvp3026_recalctimings(void *priv, svga_t *svga) /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); - pclog("MCR=0x%02x, truecolor=0x%02x, crtc1=0x%02x, MCLK=0x%02x, ClockSel=%x.\n", ramdac->mcr, ramdac->true_color, svga->crtc[1] + 1, ramdac->mclk & 0x7f, ramdac->clock_sel); if (!(ramdac->clock_sel & 0x70)) { if (ramdac->mcr != 0x98) { svga->hdisp <<= 1; From 80adef5ee624a99fbc525e20674715efc9eef3e0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 Feb 2024 01:43:36 +0600 Subject: [PATCH 137/690] C&T 69000: Fix black cursor on Red Hat Linux 8 --- src/video/vid_chips_69000.c | 65 ++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0eee90486..f53f44754 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2287,6 +2287,35 @@ chips_69000_vblank_start(svga_t *svga) chips_69000_interrupt(chips); } +static void +chips_69000_hwcursor_draw_64x64(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + + for (uint8_t x = 0; x < 64; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + static void chips_69000_hwcursor_draw(svga_t *svga, int displine) { @@ -2294,7 +2323,10 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) uint64_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - if (svga->interlace && (chips->ext_regs[0xa0] & 7) == 0b1) { + if ((chips->ext_regs[0xa0] & 7) == 0b101) + return chips_69000_hwcursor_draw_64x64(svga, displine); + + if (svga->interlace) { dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; @@ -2315,10 +2347,7 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) return; } - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; - - if ((svga->hwcursor_on & 1) && (chips->ext_regs[0xa0] & 7) == 0b1) { + if ((svga->hwcursor_on & 1)) { dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr - 16])); dat[0] = bswap64(*(uint64_t *) (&svga->vram[(svga->hwcursor_latch.addr - 16) + 8])); dat[1] <<= 32ULL; @@ -2329,27 +2358,17 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; } - switch (chips->ext_regs[0xa0] & 7) { - case 0b1: - case 0b101: - for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { - if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); - else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - break; + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; - default: - break; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; } - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; } static float From 1b5d84f36607fa76acbdcf89ab53cc47e9700e92 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 Feb 2024 02:25:40 +0600 Subject: [PATCH 138/690] C&T 69000: DPMS Also draw black overscan when monitor is turned off via DPMS. --- src/video/vid_chips_69000.c | 7 +++++++ src/video/vid_svga.c | 13 +++++++++++-- src/video/video.c | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index f53f44754..d91ab1a8b 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -743,6 +743,12 @@ chips_69000_recalctimings(svga_t *svga) svga->htotal -= 5; } + if (((chips->ext_regs[0x61] & 0x8) && !(chips->ext_regs[0x61] & 0x4)) + || ((chips->ext_regs[0x61] & 0x2) && !(chips->ext_regs[0x61] & 0x1))) { + svga->dpms = 1; + } else + svga->dpms = 0; + if (chips->ext_regs[0x09] & 0x1) { svga->vtotal -= 2; svga->vtotal &= 0xFF; @@ -1543,6 +1549,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) break; case 0x61: chips->ext_regs[chips->ext_index] = val & 0x7f; + svga_recalctimings(&chips->svga); break; case 0x62: chips->ext_regs[chips->ext_index] = val & 0x9C; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d9c2ba892..d60a5de0e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -947,6 +947,15 @@ svga_recalctimings(svga_t *svga) /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { if (!svga->dpms_ui) { + /* Make sure to black out the entire screen to avoid lingering image. */ + int y_add = enable_overscan ? svga->monitor->mon_overscan_y : 0; + int x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; + int y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); + int x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); + video_wait_for_buffer_monitor(svga->monitor_index); + memset(svga->monitor->target_buffer->dat, 0, svga->monitor->target_buffer->w * svga->monitor->target_buffer->h * 4); + video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); + video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; ui_sb_set_text_w(plat_get_string(IDS_2143)); } @@ -1864,14 +1873,14 @@ svga_doblit(int wx, int wy, svga_t *svga) p = &svga->monitor->target_buffer->line[i & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } for (i = 0; i < bottom; i++) { p = &svga->monitor->target_buffer->line[(svga->monitor->mon_ysize + svga->y_add + i) & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } } diff --git a/src/video/video.c b/src/video/video.c index 710449746..01c398118 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -831,9 +831,9 @@ destroy_bitmap(bitmap_t *b) bitmap_t * create_bitmap(int x, int y) { - bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint32_t *))); + bitmap_t *b = calloc(sizeof(bitmap_t), (y * sizeof(uint32_t *))); - b->dat = malloc((size_t) x * y * 4); + b->dat = calloc((size_t) x * y, 4); for (int c = 0; c < y; c++) b->line[c] = &(b->dat[c * x]); b->w = x; From 58a0c840c1d18845e8a7b71439bcaca4408491f8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 00:52:20 +0100 Subject: [PATCH 139/690] Added SiS 550x, 558x, 559x, (5)600, UMC UM8890, UMC UM8663 Super I/O Chips, UMC UM8673F and Winbond W83769F IDE Contollers, and a number of machines, and fixes to the UM888x 486 chipset. --- src/acpi.c | 910 ++++++++++++++++- src/chipset/CMakeLists.txt | 8 +- src/chipset/sis_5511.c | 878 +---------------- src/chipset/sis_5511_h2p.c | 461 +++++++++ src/chipset/sis_5513_ide.c | 501 ++++++++++ src/chipset/sis_5513_p2i.c | 1354 ++++++++++++++++++++++++++ src/chipset/sis_5571.c | 1151 +--------------------- src/chipset/sis_5571_h2p.c | 458 +++++++++ src/chipset/sis_5571_old.c | 772 +++++++++++++++ src/chipset/sis_5572_usb.c | 323 ++++++ src/chipset/sis_5581.c | 185 ++++ src/chipset/sis_5581_h2p.c | 553 +++++++++++ src/chipset/sis_5591.c | 210 ++++ src/chipset/sis_5591_h2p.c | 493 ++++++++++ src/chipset/sis_5595_pmu.c | 455 +++++++++ src/chipset/sis_55xx.c | 96 ++ src/chipset/sis_5600.c | 210 ++++ src/chipset/sis_5600_h2p.c | 434 +++++++++ src/chipset/sis_85c50x.c | 424 ++++++-- src/chipset/umc_8886.c | 264 ++--- src/chipset/umc_8890.c | 241 +++++ src/chipset/umc_hb4.c | 123 +-- src/device.c | 17 + src/device/CMakeLists.txt | 2 +- src/device/pci_bridge.c | 25 +- src/device/smbus_sis5595.c | 386 ++++++++ src/disk/CMakeLists.txt | 2 +- src/disk/hdc_ide_sff8038i.c | 11 +- src/disk/hdc_ide_um8673f.c | 212 ++++ src/disk/hdc_ide_w83769f.c | 460 +++++++++ src/include/86box/acpi.h | 62 +- src/include/86box/chipset.h | 10 + src/include/86box/device.h | 2 + src/include/86box/hdc.h | 12 +- src/include/86box/hdc_ide_sff8038i.h | 4 +- src/include/86box/machine.h | 19 + src/include/86box/nvr.h | 2 + src/include/86box/pci.h | 1 + src/include/86box/sio.h | 6 + src/include/86box/sis_55xx.h | 78 ++ src/include/86box/smbus.h | 46 +- src/include/86box/video.h | 4 +- src/machine/m_at_386dx_486.c | 15 +- src/machine/m_at_slot1.c | 34 + src/machine/m_at_socket5.c | 96 ++ src/machine/m_at_socket7.c | 115 ++- src/machine/m_at_socket7_3v.c | 28 + src/machine/machine_table.c | 375 +++++++ src/nvr_at.c | 24 + src/sio/CMakeLists.txt | 3 +- src/sio/sio_it86x1f.c | 4 +- src/sio/sio_um8663f.c | 366 +++++++ src/video/vid_cl54xx.c | 20 +- src/video/vid_tgui9440.c | 16 +- 54 files changed, 10672 insertions(+), 2289 deletions(-) create mode 100644 src/chipset/sis_5511_h2p.c create mode 100644 src/chipset/sis_5513_ide.c create mode 100644 src/chipset/sis_5513_p2i.c create mode 100644 src/chipset/sis_5571_h2p.c create mode 100644 src/chipset/sis_5571_old.c create mode 100644 src/chipset/sis_5572_usb.c create mode 100644 src/chipset/sis_5581.c create mode 100644 src/chipset/sis_5581_h2p.c create mode 100644 src/chipset/sis_5591.c create mode 100644 src/chipset/sis_5591_h2p.c create mode 100644 src/chipset/sis_5595_pmu.c create mode 100644 src/chipset/sis_55xx.c create mode 100644 src/chipset/sis_5600.c create mode 100644 src/chipset/sis_5600_h2p.c create mode 100644 src/chipset/umc_8890.c create mode 100644 src/device/smbus_sis5595.c create mode 100644 src/disk/hdc_ide_um8673f.c create mode 100644 src/disk/hdc_ide_w83769f.c create mode 100644 src/include/86box/sis_55xx.h create mode 100644 src/sio/sio_um8663f.c diff --git a/src/acpi.c b/src/acpi.c index ddd2ffbe7..93cb71542 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -39,6 +39,10 @@ #include <86box/machine.h> #include <86box/i2c.h> #include <86box/video.h> +#include <86box/smbus.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/sis_55xx.h> int acpi_rtc_status = 0; atomic_int acpi_pwrbut_pressed = 0; @@ -46,7 +50,9 @@ int acpi_enabled = 0; static double cpu_to_acpi; -static int acpi_power_on = 0; +static int acpi_power_on = 0; +static uint64_t acpi_last_clock = 0ULL; +static int acpi_count = 0; #ifdef ENABLE_ACPI_LOG int acpi_do_log = ENABLE_ACPI_LOG; @@ -82,65 +88,152 @@ acpi_timer_get(acpi_t *dev) return clock & 0xffffff; } +static uint8_t +acpi_gp_timer_get(acpi_t *dev) +{ + uint64_t clock = acpi_clock_get(); + clock -= acpi_last_clock; + if (clock >= acpi_count) + clock = 0x00; + else + clock &= 0xff; + return clock; +} + static double acpi_get_overflow_period(acpi_t *dev) { uint64_t timer = acpi_clock_get(); uint64_t overflow_time; - if (dev->regs.timer32) { + if (dev->regs.timer32) overflow_time = (timer + 0x80000000LL) & ~0x7fffffffLL; - } else { + else overflow_time = (timer + 0x800000LL) & ~0x7fffffLL; - } uint64_t time_to_overflow = overflow_time - timer; return ((double) time_to_overflow / (double) ACPI_TIMER_FREQ) * 1000000.0; } +static void +acpi_timer_update(acpi_t *dev, bool enable) +{ + if (enable) + timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + else + timer_stop(&dev->timer); +} + static void acpi_timer_overflow(void *priv) { acpi_t *dev = (acpi_t *) priv; dev->regs.pmsts |= TMROF_STS; acpi_update_irq(dev); + acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); } static void -acpi_timer_update(acpi_t *dev, bool enable) +acpi_gp_timer_update(acpi_t *dev, bool enable, int count) { if (enable) { - timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); - } else { + acpi_last_clock = acpi_clock_get(); + acpi_count = count; + timer_on_auto(&dev->gp_timer, (1000000.0 / (double) ACPI_TIMER_FREQ) * ((double) count)); + } else timer_stop(&dev->timer); +} + +void +acpi_sis5595_smi_raise(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->regs.leg_en & 0x20) { + dev->regs.leg_sts |= 0x20; + smi_raise(); } } +static void +acpi_gp_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor == VEN_SIS_5595_1997) { + dev->regs.gpe_sts |= 0x20000000; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + acpi_sis5595_smi_raise(dev); + } else if (dev->vendor == VEN_SIS_5595) { + dev->regs.gpe_sts |= 0x00000400; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_14 |= 0x2000; + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + smi_raise(); + } +} + +static void +acpi_per_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor >= VEN_SIS_5595_1997) { + dev->regs.leg_sts |= 0x04; + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_25 |= 0x04; + smi_raise(); + } + timer_on_auto(&dev->per_timer, 16000000.0); +} + void acpi_update_irq(acpi_t *dev) { int sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); - if (dev->vendor == VEN_SMC) - sci_level |= (dev->regs.pmsts & BM_STS); + sis_55xx_common_t *sis = (sis_55xx_common_t *) dev->priv; - if ((dev->regs.pmcntrl & 0x01) && sci_level) { - if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); - else if (dev->irq_mode == 2) - pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); - else - picintlevel(1 << dev->irq_line, &dev->irq_state); - } else { - if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); - else if (dev->irq_mode == 2) - pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); - else - picintclevel(1 << dev->irq_line, &dev->irq_state); + switch (dev->vendor) { + case VEN_SMC: + sci_level |= (dev->regs.pmsts & BM_STS); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + if ((sis != NULL) && (sis->pmu_regs != NULL)) { + sci_level |= (sis->pmu_regs[0x80] | sis->pmu_regs[0x81] | + sis->pmu_regs[0x82] | sis->pmu_regs[0x83]); + } + break; } - acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); + if ((dev->regs.pmcntrl & 0x01) && sci_level) switch (dev->irq_mode) { + default: + picintlevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } else switch (dev->irq_mode) { + default: + picintclevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } } void @@ -652,6 +745,230 @@ acpi_aux_reg_read_smc(UNUSED(int size), uint16_t addr, void *priv) return ret; } +static uint32_t +acpi_reg_read_sis_5582(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x14: + case 0x15: + ret = (dev->regs.reg_14 >> shift16) & 0xff; + break; + case 0x16: + case 0x17: + ret = (dev->regs.reg_16 >> shift16) & 0xff; + break; + case 0x18: + case 0x19: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1a: + case 0x1b: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1c: + case 0x1d: + ret = (dev->regs.reg_1c >> shift16) & 0xff; + break; + case 0x20: + ret = dev->regs.smi_cmd; + break; + case 0x24: + ret = dev->regs.reg_24; + break; + case 0x25: + ret = dev->regs.reg_25; + break; + case 0x26: + ret = dev->regs.reg_26; + break; + case 0x28: + ret = dev->regs.smi_en_val; + break; + case 0x29: + ret = dev->regs.smi_dis_val; + break; + case 0x2a: + ret = dev->regs.mail_box; + break; + case 0x2b: + ret = dev->regs.reg_2b; + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + +static uint32_t +acpi_reg_read_sis_5595(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = dev->regs.reg_13; + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + ret = (dev->regs.gpe_sts >> shift32) & 0xff; + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + ret = (dev->regs.gpe_en >> shift32) & 0xff; + break; + case 0x1c: + case 0x1d: + case 0x1e: + ret = (dev->regs.gpe_pin >> shift32) & 0xff; + break; + case 0x1f: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + ret = (dev->regs.gpe_io >> shift32) & 0xff; + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + ret = (dev->regs.gpe_pol >> shift32) & 0xff; + break; + case 0x28: + case 0x29: + ret = (dev->regs.gpe_mul >> shift16) & 0xff; + break; + case 0x2a: + case 0x2b: + ret = (dev->regs.gpe_ctl >> shift16) & 0xff; + break; + case 0x2c: + case 0x2d: + ret = (dev->regs.gpe_smi >> shift16) & 0xff; + break; + case 0x2e: + case 0x2f: + ret = (dev->regs.gpe_rl >> shift16) & 0xff; + break; + case 0x30: + ret = dev->regs.leg_sts; + break; + case 0x31: + ret = dev->regs.leg_en; + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_cmd; + else + ret = 0x00; + break; + case 0x33: + ret = dev->regs.tst_ctl; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_en_val; + else + ret = dev->regs.reg_34; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_dis_val; + else + ret = dev->regs.smi_cmd; + break; + case 0x36: + ret = dev->regs.mail_box; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_index(dev->smbus); + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_data(dev->smbus); + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + static void acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) { @@ -1193,22 +1510,405 @@ acpi_aux_reg_write_smc(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) } } +void +acpi_sis5582_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + dev->regs.reg_25 |= 0x02; + if (dev->regs.reg_26 & 0x02) + smi_raise(); +} + +static void +acpi_reg_write_sis_5582(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x007e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.reg_16 & 0x2000), val); + break; + case 0x14: + case 0x15: + dev->regs.reg_14 &= ~((val << shift32) & 0xff9f); + break; + case 0x16: + case 0x17: + dev->regs.reg_16 = ((dev->regs.reg_16 & ~(0xff << shift16)) | (val << shift16)) & 0xff1f; + break; + case 0x18: + case 0x19: + dev->regs.reg_18 = ((dev->regs.reg_18 & ~(0xff << shift16)) | (val << shift16)) & 0x07ff; + break; + case 0x1a: + case 0x1b: + dev->regs.reg_1a = ((dev->regs.reg_1a & ~(0xff << shift16)) | (val << shift16)) & 0x0387; + break; + case 0x1c: + case 0x1d: + dev->regs.reg_1c = ((dev->regs.reg_1c & ~(0xff << shift16)) | (val << shift16)) & 0x3f7f; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_1c & 0x0400) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x20: + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.reg_25 |= 0x08; + if (dev->regs.reg_26 & 0x08) + smi_raise(); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.reg_25 |= 0x10; + if (dev->regs.reg_26 & 0x10) + smi_raise(); + } + break; + case 0x24: + dev->regs.reg_24 = val & 0x43; + break; + case 0x25: + dev->regs.reg_25 &= ~(val & 0x1f); + break; + case 0x26: + old = dev->regs.reg_26; + dev->regs.reg_26 = val & 0x3f; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x28: + dev->regs.smi_en_val = val; + break; + case 0x29: + dev->regs.smi_dis_val = val; + break; + case 0x2a: + dev->regs.mail_box = val; + break; + case 0x2b: + dev->regs.reg_2b = val & 0x01; + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_1c &= ~0x0400; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.reg_25 |= 0x01; + if (dev->regs.reg_26 & 0x01) + acpi_raise_smi(dev, 1); + } + break; + } +} + +void +acpi_sis5595_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_sis5595_smi_raise(dev); + else if (dev->regs.gpe_en & 0x00001000) { + dev->regs.gpe_sts |= 0x00001000; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_smbus_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.gpe_en & 0x00000800) { + dev->regs.gpe_sts |= 0x00000800; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_software_smi(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.leg_en & 0x01) { + dev->regs.leg_sts |= 0x01; + acpi_sis5595_smi_raise(dev); + } +} + +static void +acpi_reg_write_sis_5595(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + uint8_t do_smi = 0; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x001e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_13 & 0x02) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_sts &= ~((val << shift32) & 0xff03ffbf); + else + dev->regs.gpe_sts &= ~((val << shift32) & 0xff83ffff); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | (val << shift32)); + else + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | + (val << shift32)) & 0xff83ffff; + break; + case 0x1c: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0xff << shift32)) | ((val & 0xff) << shift32)); + break; + case 0x1d: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x1e: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x1f: + dev->regs.gp_tmr = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.gpe_en & 0x00000400), val); + break; + case 0x20: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x9f << shift32)) | ((val & 0x9f) << shift32)); + break; + case 0x21: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x22: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x24: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0xbf << shift32)) | ((val & 0xbf) << shift32)); + break; + case 0x25: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x26: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x27: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x10 << shift32)) | ((val & 0x10) << shift32)); + break; + case 0x28: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0xf9 << shift16)) | ((val & 0xf9) << shift16)); + break; + case 0x29: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0x13 << shift16)) | ((val & 0x13) << shift16)); + break; + case 0x2a: + case 0x2b: + dev->regs.gpe_ctl = ((dev->regs.gpe_ctl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2c: + case 0x2d: + dev->regs.gpe_smi = ((dev->regs.gpe_smi & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2e: + case 0x2f: + dev->regs.gpe_rl = ((dev->regs.gpe_rl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x30: + dev->regs.leg_sts &= ~val; + break; + case 0x31: + old = dev->regs.leg_en; + dev->regs.leg_en = val; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.leg_sts |= 0x08; + if (dev->regs.leg_en & 0x08) + acpi_sis5595_smi_raise(dev); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + } + break; + case 0x33: + dev->regs.tst_ctl = val & 0x01; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_en_val = val; + else + dev->regs.reg_34 = val; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_dis_val = val; + else { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + break; + case 0x36: + dev->regs.mail_box = val; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.index = val; + smbus_sis5595_write_index(dev->smbus, val); + } + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.reg_ff = val & 0x3f; + smbus_sis5595_write_data(dev->smbus, val); + if (val & 0x20) { /* Set GPIO5_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000008; + do_smi |= (dev->regs.gpe_en & 0x00000004); + } else if (val & 0x10) { /* Set GPIO10_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000004; + do_smi |= (dev->regs.gpe_en & 0x00000008); + } else if (val & 0x08) { /* Set RI_STS in GPE_STS */ + dev->regs.gpe_sts |= 0x00000002; + do_smi |= (dev->regs.gpe_en & 0x00000002); + } else if (val & 0x04) /* Set WAK_STS of PM1_STS */ + dev->regs.pmsts |= 0x8000; + else if (val & 0x02) { /* Set RTC_STS of PM1_STS */ + dev->regs.pmsts |= 0x0400; + do_smi |= (dev->regs.pmen & 0x0400); + } else if (val & 0x01) { /* Set PWRBTN_STS of PM1_STS */ + dev->regs.pmsts |= 0x0100; + do_smi |= (dev->regs.pmen & 0x0100); + } + + if (do_smi) + acpi_sis5595_smi_raise(dev); + } + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_13 &= ~0x02; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.leg_sts |= 0x01; + if (dev->regs.leg_en & 0x01) + acpi_sis5595_smi_raise(dev); + } + break; + } +} + static uint32_t acpi_reg_read_common(int size, uint16_t addr, void *priv) { const acpi_t *dev = (acpi_t *) priv; uint8_t ret = 0xff; - if (dev->vendor == VEN_ALI) - ret = acpi_reg_read_ali(size, addr, priv); - else if (dev->vendor == VEN_VIA) - ret = acpi_reg_read_via(size, addr, priv); - else if (dev->vendor == VEN_VIA_596B) - ret = acpi_reg_read_via_596b(size, addr, priv); - else if (dev->vendor == VEN_INTEL) - ret = acpi_reg_read_intel(size, addr, priv); - else if (dev->vendor == VEN_SMC) - ret = acpi_reg_read_smc(size, addr, priv); + switch (dev->vendor) { + case VEN_ALI: + ret = acpi_reg_read_ali(size, addr, priv); + break; + case VEN_VIA: + ret = acpi_reg_read_via(size, addr, priv); + break; + case VEN_VIA_596B: + ret = acpi_reg_read_via_596b(size, addr, priv); + break; + case VEN_INTEL: + ret = acpi_reg_read_intel(size, addr, priv); + break; + case VEN_SMC: + ret = acpi_reg_read_smc(size, addr, priv); + break; + case VEN_SIS_5582: + ret = acpi_reg_read_sis_5582(size, addr, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + ret = acpi_reg_read_sis_5595(size, addr, priv); + break; + } return ret; } @@ -1218,16 +1918,30 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv) { const acpi_t *dev = (acpi_t *) priv; - if (dev->vendor == VEN_ALI) - acpi_reg_write_ali(size, addr, val, priv); - else if (dev->vendor == VEN_VIA) - acpi_reg_write_via(size, addr, val, priv); - else if (dev->vendor == VEN_VIA_596B) - acpi_reg_write_via_596b(size, addr, val, priv); - else if (dev->vendor == VEN_INTEL) - acpi_reg_write_intel(size, addr, val, priv); - else if (dev->vendor == VEN_SMC) - acpi_reg_write_smc(size, addr, val, priv); + switch (dev->vendor) { + case VEN_ALI: + acpi_reg_write_ali(size, addr, val, priv); + break; + case VEN_VIA: + acpi_reg_write_via(size, addr, val, priv); + break; + case VEN_VIA_596B: + acpi_reg_write_via_596b(size, addr, val, priv); + break; + case VEN_INTEL: + acpi_reg_write_intel(size, addr, val, priv); + break; + case VEN_SMC: + acpi_reg_write_smc(size, addr, val, priv); + break; + case VEN_SIS_5582: + acpi_reg_write_sis_5582(size, addr, val, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + acpi_reg_write_sis_5595(size, addr, val, priv); + break; + } } static uint32_t @@ -1396,6 +2110,9 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) default: case VEN_ALI: case VEN_INTEL: + case VEN_SIS_5582: + case VEN_SIS_5595_1997: + case VEN_SIS_5595: size = 0x040; break; case VEN_SMC: @@ -1677,6 +2394,20 @@ acpi_reset(void *priv) acpi_update_irq(dev); dev->irq_state = 0; + + timer_disable(&dev->gp_timer); + + acpi_last_clock = 0ULL; + acpi_count = 0; + + timer_disable(&dev->per_timer); + + if ((dev->vendor == VEN_SIS_5595_1997) || (dev->vendor == VEN_SIS_5595)) { + dev->regs.reg_13 = 0x20; + dev->regs.gp_tmr = 0xff; + dev->regs.gpe_io = 0x00030b9f; + dev->regs.gpe_mul = 0x1001; + } } static void @@ -1689,6 +2420,33 @@ acpi_speed_changed(void *priv) if (timer_enabled) timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + + if ((dev->vendor & 0xffff) == 0x1039) { + if (timer_is_on(&dev->gp_timer)) { + timer_stop(&dev->gp_timer); + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + else if (dev->vendor == VEN_SIS_5595) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + else + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + } + + if (timer_is_on(&dev->per_timer)) { + timer_stop(&dev->per_timer); + + timer_on_auto(&dev->per_timer, 16000000.0); + } + } +} + +void * +acpi_get_smbus(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + return dev->smbus; } static void @@ -1767,6 +2525,28 @@ acpi_init(const device_t *info) dev->suspend_types[4] = SUS_SUSPEND; break; + case VEN_SIS_5582: + dev->suspend_types[0] = SUS_SUSPEND; /* S1 */ + dev->suspend_types[4] = SUS_POWER_OFF; /* S5 */ + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + break; + + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + dev->suspend_types[1] = SUS_SUSPEND; + dev->suspend_types[2] = SUS_SUSPEND; + dev->suspend_types[3] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[4] = SUS_POWER_OFF; + dev->suspend_types[5] = SUS_POWER_OFF; + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + + dev->smbus = device_add(&sis5595_smbus_device); + break; + default: break; } @@ -1854,3 +2634,45 @@ const device_t acpi_smc_device = { .force_redraw = NULL, .config = NULL }; + +const device_t acpi_sis_5582_device = { + .name = "SiS 5582 ACPI", + .internal_name = "acpi_sis_5582", + .flags = DEVICE_PCI, + .local = VEN_SIS_5582, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_1997_device = { + .name = "SiS 5595 (1997) ACPI", + .internal_name = "acpi_sis_5595_1997", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595_1997, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_device = { + .name = "SiS 5595 ACPI", + .internal_name = "acpi_sis_5595", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0f3c78c84..0406ea0b8 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -18,9 +18,11 @@ add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali14 compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c - sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c - umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c + sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c + sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c + via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c + umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index e58066c95..aa841ed9c 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -25,9 +25,10 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -41,7 +42,7 @@ #include <86box/port_92.h> #include <86box/smram.h> #include <86box/spd.h> - +#include <86box/sis_55xx.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_5511_LOG @@ -63,573 +64,53 @@ sis_5511_log(const char *fmt, ...) #endif typedef struct sis_5511_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t nb_slot; + uint8_t sb_slot; - uint8_t regs[16]; - uint8_t states[7]; + void *h2p; - uint8_t slic_regs[4096]; + void *p2i; + void *ide; - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[2][256]; - - mem_mapping_t slic_mapping; - - sff8038i_t *bm[2]; - smram_t *smram; - port_92_t *port_92; - void *pit; - nvr_t *nvr; - - uint8_t (*pit_read_reg)(void *priv, uint8_t reg); + sis_55xx_common_t *sis; } sis_5511_t; static void -sis_5511_shadow_recalc(sis_5511_t *dev) +sis_5511_write(int func, int addr, uint8_t val, void *priv) { - int state; - uint32_t base; - - for (uint8_t i = 0x80; i <= 0x86; i++) { - if (i == 0x86) { - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - sis_5511_log("000F0000-000FFFFF\n"); - } - } else { - base = ((i & 0x07) << 15) + 0xc0000; - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - sis_5511_log("%08X-%08X\n", base, base + 0x3fff); - } - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); - } - } - - dev->states[i & 0x0f] = dev->pci_conf[i]; - } - - flushmmucache_nopc(); -} - -static void -sis_5511_smram_recalc(sis_5511_t *dev) -{ - smram_disable_all(); - - switch (dev->pci_conf[0x65] >> 6) { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - - default: - break; - } - - flushmmucache(); -} - -static void -sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; + const sis_5511_t *dev = (sis_5511_t *) priv; sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - if (func == 0x00) switch (addr) { - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= 0xb0; - break; - - case 0x50: - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x51: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x52: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x53: - case 0x54: - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x56 ... 0x59: - dev->pci_conf[addr] = val; - break; - - case 0x5a: - /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. - The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. - The latter (bit 6) means the chipset intercepts all odd FXh to 64h. - Bit 5 sets fast reset latency. This should be fixed on the other SiS - chipsets as well. */ - dev->pci_conf[addr] = val; - break; - - case 0x5b: - dev->pci_conf[addr] = val & 0xf7; - break; - - case 0x5c: - dev->pci_conf[addr] = val & 0xcf; - break; - - case 0x5d: - dev->pci_conf[addr] = val; - break; - - case 0x5e: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x5f: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x60: - dev->pci_conf[addr] = val & 0x3e; - if ((dev->pci_conf[0x68] & 1) && (val & 2)) { - smi_raise(); - dev->pci_conf[0x69] |= 1; - } - break; - - case 0x61 ... 0x64: - dev->pci_conf[addr] = val; - break; - - case 0x65: - dev->pci_conf[addr] = val & 0xd0; - sis_5511_smram_recalc(dev); - break; - - case 0x66: - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x67: - case 0x68: - dev->pci_conf[addr] = val; - break; - - case 0x69: - dev->pci_conf[addr] &= val; - break; - - case 0x6a ... 0x6e: - dev->pci_conf[addr] = val; - break; - - case 0x6f: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x70: /* DRAM Bank Register 0-0 */ - case 0x72: /* DRAM Bank Register 0-1 */ - case 0x74: /* DRAM Bank Register 1-0 */ - case 0x76: /* DRAM Bank Register 1-1 */ - case 0x78: /* DRAM Bank Register 2-0 */ - case 0x7a: /* DRAM Bank Register 2-1 */ - case 0x7c: /* DRAM Bank Register 3-0 */ - case 0x7e: /* DRAM Bank Register 3-1 */ - spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); - break; - - case 0x71: /* DRAM Bank Register 0-0 */ - dev->pci_conf[addr] = val; - break; - - case 0x75: /* DRAM Bank Register 1-0 */ - case 0x79: /* DRAM Bank Register 2-0 */ - case 0x7d: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x73: /* DRAM Bank Register 0-1 */ - case 0x77: /* DRAM Bank Register 1-1 */ - case 0x7b: /* DRAM Bank Register 2-1 */ - case 0x7f: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x80 ... 0x85: - dev->pci_conf[addr] = val & 0xee; - sis_5511_shadow_recalc(dev); - break; - case 0x86: - dev->pci_conf[addr] = val & 0xe8; - sis_5511_shadow_recalc(dev); - break; - - case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ - dev->pci_conf[addr] = val; - break; - - default: - break; - } -} - -static void -sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - addr &= 0x00000fff; - - switch (addr) { - case 0x00000000: - case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ - dev->slic_regs[addr] = val; - break; - case 0x00000010: - case 0x00000018: - case 0x00000028: - case 0x00000038: - dev->slic_regs[addr] = val & 0x01; - break; - case 0x00000030: - dev->slic_regs[addr] = val & 0x0f; - mem_mapping_set_addr(&dev->slic_mapping, - (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); - break; - } + if (func == 0x00) + sis_5511_host_to_pci_write(addr, val, dev->h2p); } static uint8_t -sis_5511_read(UNUSED(int func), int addr, void *priv) +sis_5511_read(int func, int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; if (func == 0x00) - ret = dev->pci_conf[addr]; + ret = sis_5511_host_to_pci_read(addr, dev->h2p); sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } -static uint8_t -sis_5511_slic_read(uint32_t addr, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - uint8_t ret = 0xff; - - addr &= 0x00000fff; - - switch (addr) { - case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ - ret = dev->slic_regs[addr]; - break; - } - - return ret; -} - -void -sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) -{ - sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30); - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x60: /* MIRQ0 Remapping Control Register */ - case 0x61: /* MIRQ1 Remapping Control Register */ - sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); - break; - - case 0x64: /* GPIO0 Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x80; - break; - - case 0x66: /* GPIO0 Output Mode Control Register */ - case 0x67: /* GPIO0 Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: /* GPIO Status Register */ - dev->pci_conf_sb[0][addr] |= (val & 0x10); - dev->pci_conf_sb[0][addr] &= ~(val & 0x01); - break; - - default: - break; - } -} - -static void -sis_5513_ide_irq_handler(sis_5511_t *dev) -{ - if (dev->pci_conf_sb[1][0x09] & 0x01) { - /* Primary IDE is native. */ - sis_5511_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); - } else { - /* Primary IDE is legacy. */ - sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - } - - if (dev->pci_conf_sb[1][0x09] & 0x04) { - /* Secondary IDE is native. */ - sis_5511_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); - } else { - /* Secondary IDE is legacy. */ - sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); - } -} - -static void -sis_5513_ide_handler(sis_5511_t *dev) -{ - uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; - - uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; - uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; - uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; - uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; - - uint16_t current_pri_base; - uint16_t current_pri_side; - uint16_t current_sec_base; - uint16_t current_sec_side; - - /* Primary Channel Programming */ - current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; - current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; - - /* Secondary Channel Programming */ - current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; - current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; - - sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); - ide_pri_disable(); - sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); - ide_sec_disable(); - - if (ide_io_on) { - /* Primary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x02) { - sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); - ide_set_base(0, current_pri_base); - sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); - ide_set_side(0, current_pri_side); - - sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); - ide_pri_enable(); - - sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); - } - - /* Secondary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x04) { - sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); - ide_set_base(1, current_sec_base); - sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); - ide_set_side(1, current_sec_side); - - sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); - ide_sec_enable(); - - sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); - } - } - - sff_bus_master_handler(dev->bm[0], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); - sff_bus_master_handler(dev->bm[1], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); -} - -void -sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) -{ - sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5513_ide_handler(dev); - break; - case 0x06: /* Status low byte */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); - break; - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05); - sis_5513_ide_irq_handler(dev); - sis_5513_ide_handler(dev); - break; - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - /* Primary Base Address */ - case 0x10: - case 0x11: - case 0x14: - case 0x15: - fallthrough; - - /* Secondary Base Address */ - case 0x18: - case 0x19: - case 0x1c: - case 0x1d: - fallthrough; - - /* Bus Mastering Base Address */ - case 0x20: - case 0x21: - if (addr == 0x20) - dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; - else - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x07; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0x9e; - sis_5513_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control Register 1 */ - dev->pci_conf_sb[1][addr] = val & 0xef; - break; - - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - - default: - break; - } -} - static void sis_5513_write(int func, int addr, uint8_t val, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; + const sis_5511_t *dev = (sis_5511_t *) priv; - switch (func) { - default: - break; - case 0: - sis_5513_pci_to_isa_write(addr, val, dev); - break; - case 1: - sis_5513_ide_write(addr, val, dev); - break; - } + sis_5511_log("SiS 5513: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); } static uint8_t @@ -638,281 +119,21 @@ sis_5513_read(int func, int addr, void *priv) const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) { - switch (addr) { - default: - ret = dev->pci_conf_sb[func][addr]; - break; - case 0x4c ... 0x4f: - ret = pic_read_icw(0, addr & 0x03); - break; - case 0x50 ... 0x53: - ret = pic_read_icw(1, addr & 0x03); - break; - case 0x54 ... 0x55: - ret = pic_read_ocw(0, addr & 0x01); - break; - case 0x56 ... 0x57: - ret = pic_read_ocw(1, addr & 0x01); - break; - case 0x58 ... 0x5f: - ret = dev->pit_read_reg(dev->pit, addr & 0x07); - break; - } + if (func == 0x00) + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); - sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); - } else if (func == 0x01) { - if (addr == 0x3d) - ret = (((dev->pci_conf_sb[0x01][0x4b] & 0xc0) == 0xc0) || - (dev->pci_conf_sb[0x01][0x09] & 0x05)) ? PCI_INTA : 0x00; - else - ret = dev->pci_conf_sb[func][addr]; - - sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); - } + sis_5511_log("SiS 5513: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } -static void -sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - switch (addr) { - case 0x22: - dev->index = val - 0x50; - break; - case 0x23: - sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); - - switch (dev->index) { - case 0x00: - dev->regs[dev->index] = val & 0xed; - switch (val >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - - default: - break; - } - nvr_bank_set(0, !!(val & 0x08), dev->nvr); - break; - case 0x01: - dev->regs[dev->index] = val & 0xf4; - break; - case 0x03: - dev->regs[dev->index] = val & 3; - break; - case 0x04: /* BIOS Register */ - dev->regs[dev->index] = val; - break; - case 0x05: - dev->regs[dev->index] = val; - outb(0x70, val); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - dev->regs[dev->index] = val; - break; - - default: - break; - } - break; - - default: - break; - } -} - -static uint8_t -sis_5513_isa_read(uint16_t addr, void *priv) -{ - const sis_5511_t *dev = (sis_5511_t *) priv; - uint8_t ret = 0xff; - - if (addr == 0x23) { - if (dev->index == 0x05) - ret = inb(0x70); - else - ret = dev->regs[dev->index]; - - sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); - } - - return ret; -} - -static void -sis_5511_reset(void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - /* SiS 5511 */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x11; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0x07; - dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x02; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; - dev->pci_conf[0x52] = 0x20; - dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; - dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; - dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; - dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; - dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; - dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; - dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; - dev->pci_conf[0x63] = 0xff; - dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; - dev->pci_conf[0x66] = 0x00; - dev->pci_conf[0x67] = 0xff; - dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6a] = 0x00; - dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; - dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; - dev->pci_conf[0x6f] = 0x00; - dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; - dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; - dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; - dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; - dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; - dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; - dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; - dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; - dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; - - cpu_cache_ext_enabled = 0; - cpu_update_waitstates(); - - sis_5511_smram_recalc(dev); - sis_5511_shadow_recalc(dev); - - flushmmucache(); - - memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); - dev->slic_regs[0x18] = 0x0f; - - mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); - - /* SiS 5513 */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x03] = 0x00; - dev->pci_conf_sb[0][0x04] = 0x07; - dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00; - dev->pci_conf_sb[0][0x07] = 0x02; - dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; - dev->pci_conf_sb[0][0x0e] = 0x80; - dev->pci_conf_sb[0][0x40] = 0x00; - dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; - dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; - dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; - dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; - dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x61] = 0x80; - dev->pci_conf_sb[0][0x62] = 0x00; - dev->pci_conf_sb[0][0x63] = 0x80; - dev->pci_conf_sb[0][0x64] = 0x00; - dev->pci_conf_sb[0][0x65] = 0x00; - dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; - dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00; - dev->pci_conf_sb[0][0x6a] = 0x04; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - - dev->regs[0x00] = dev->regs[0x01] = 0x00; - dev->regs[0x03] = dev->regs[0x04] = 0x00; - dev->regs[0x05] = 0x00; - dev->regs[0x08] = dev->regs[0x09] = 0x00; - dev->regs[0x0a] = dev->regs[0x0b] = 0x00; - - cpu_set_isa_speed(7159091); - nvr_bank_set(0, 0, dev->nvr); - - /* SiS 5513 IDE Controller */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; - dev->pci_conf_sb[1][0x08] = 0x00; - dev->pci_conf_sb[1][0x09] = 0x8a; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x0f] = 0x00; - dev->pci_conf_sb[1][0x10] = 0xf1; - dev->pci_conf_sb[1][0x11] = 0x01; - dev->pci_conf_sb[1][0x14] = 0xf5; - dev->pci_conf_sb[1][0x15] = 0x03; - dev->pci_conf_sb[1][0x18] = 0x71; - dev->pci_conf_sb[1][0x19] = 0x01; - dev->pci_conf_sb[1][0x1c] = 0x75; - dev->pci_conf_sb[1][0x1d] = 0x03; - dev->pci_conf_sb[1][0x20] = 0x01; - dev->pci_conf_sb[1][0x21] = 0xf0; - dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; - dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; - dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; - dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; - dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; - dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; - dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; - dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; - dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; - dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; - dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; - dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; - dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; - dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; - dev->pci_conf_sb[1][0x4a] = 0x06; - dev->pci_conf_sb[1][0x4b] = 0x00; - dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; - dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; - - sis_5513_ide_irq_handler(dev); - sis_5513_ide_handler(dev); - - sff_bus_master_reset(dev->bm[0]); - sff_bus_master_reset(dev->bm[1]); -} - static void sis_5511_close(void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; - smram_del(dev->smram); free(dev); } @@ -920,53 +141,18 @@ static void * sis_5511_init(UNUSED(const device_t *info)) { sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); - uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); /* Device 0: SiS 5511 */ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 1: SiS 5513 */ pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); - /* SLiC Memory Mapped Registers */ - mem_mapping_add(&dev->slic_mapping, - 0xffc00000, 0x00001000, - sis_5511_slic_read, - NULL, - NULL, - sis_5511_slic_write, - NULL, - NULL, - NULL, MEM_MAPPING_EXTERNAL, - dev); + dev->sis = device_add(&sis_55xx_common_device); - /* Ports 22h-23h: SiS 5513 ISA */ - io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); + dev->h2p = device_add_linked(&sis_5511_h2p_device, dev->sis); - /* MIRQ */ - pci_enable_mirq(0); - pci_enable_mirq(1); - - /* IDEIRQ */ - pci_enable_mirq(2); - - /* Port 92h */ - dev->port_92 = device_add(&port_92_device); - - /* SFF IDE */ - dev->bm[0] = device_add_inst(&sff8038i_device, 1); - dev->bm[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* PIT */ - dev->pit = device_find_first_priv(DEVICE_PIT); - dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; - - /* NVR */ - dev->nvr = device_add(&at_mb_nvr_device); - - sis_5511_reset(dev); + dev->p2i = device_add_linked(&sis_5513_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5513_ide_device, dev->sis); return dev; } @@ -978,7 +164,7 @@ const device_t sis_5511_device = { .local = 0, .init = sis_5511_init, .close = sis_5511_close, - .reset = sis_5511_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c new file mode 100644 index 000000000..7916d6ae2 --- /dev/null +++ b/src/chipset/sis_5511_h2p.c @@ -0,0 +1,461 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5511 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5511_HOST_TO_PCI_LOG +int sis_5511_host_to_pci_do_log = ENABLE_SIS_5511_HOST_TO_PCI_LOG; + +static void +sis_5511_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5511_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5511_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5511_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + uint8_t slic_regs[4096]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + mem_mapping_t slic_mapping; +} sis_5511_host_to_pci_t; + +static void +sis_5511_shadow_recalc(sis_5511_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x80; i <= 0x86; i++) { + if (i == 0x86) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5511_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5511_smram_recalc(sis_5511_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x65] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= 0xb0; + break; + + case 0x50: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x51: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x52: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x53: + case 0x54: + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x56 ... 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x5a: + /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. + The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. + The latter (bit 6) means the chipset intercepts all odd FXh to 64h. + Bit 5 sets fast reset latency. This should be fixed on the other SiS + chipsets as well. */ + dev->pci_conf[addr] = val; + break; + + case 0x5b: + dev->pci_conf[addr] = val & 0xf7; + break; + + case 0x5c: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0x5d: + dev->pci_conf[addr] = val; + break; + + case 0x5e: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x5f: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x60: + dev->pci_conf[addr] = val & 0x3e; + if ((dev->pci_conf[0x68] & 1) && (val & 2)) { + smi_raise(); + dev->pci_conf[0x69] |= 1; + } + break; + + case 0x61 ... 0x64: + dev->pci_conf[addr] = val; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0xd0; + sis_5511_smram_recalc(dev); + break; + + case 0x66: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x67: + case 0x68: + dev->pci_conf[addr] = val; + break; + + case 0x69: + dev->pci_conf[addr] &= val; + break; + + case 0x6a ... 0x6e: + dev->pci_conf[addr] = val; + break; + + case 0x6f: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x70: /* DRAM Bank Register 0-0 */ + case 0x72: /* DRAM Bank Register 0-1 */ + case 0x74: /* DRAM Bank Register 1-0 */ + case 0x76: /* DRAM Bank Register 1-1 */ + case 0x78: /* DRAM Bank Register 2-0 */ + case 0x7a: /* DRAM Bank Register 2-1 */ + case 0x7c: /* DRAM Bank Register 3-0 */ + case 0x7e: /* DRAM Bank Register 3-1 */ + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); + break; + + case 0x71: /* DRAM Bank Register 0-0 */ + dev->pci_conf[addr] = val; + break; + + case 0x75: /* DRAM Bank Register 1-0 */ + case 0x79: /* DRAM Bank Register 2-0 */ + case 0x7d: /* DRAM Bank Register 3-0 */ + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x73: /* DRAM Bank Register 0-1 */ + case 0x77: /* DRAM Bank Register 1-1 */ + case 0x7b: /* DRAM Bank Register 2-1 */ + case 0x7f: /* DRAM Bank Register 3-1 */ + dev->pci_conf[addr] = val & 0x83; + break; + + case 0x80 ... 0x85: + dev->pci_conf[addr] = val & 0xee; + sis_5511_shadow_recalc(dev); + break; + case 0x86: + dev->pci_conf[addr] = val & 0xe8; + sis_5511_shadow_recalc(dev); + break; + + case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5511_host_to_pci_read(int addr, void *priv) +{ + const sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + dev->slic_regs[addr] = val; + break; + case 0x00000010: + case 0x00000018: + case 0x00000028: + case 0x00000038: + dev->slic_regs[addr] = val & 0x01; + break; + case 0x00000030: + dev->slic_regs[addr] = val & 0x0f; + mem_mapping_set_addr(&dev->slic_mapping, + (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); + break; + } +} + +static uint8_t +sis_5511_slic_read(uint32_t addr, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + ret = dev->slic_regs[addr]; + break; + } + + return ret; +} + +static void +sis_5511_host_to_pci_reset(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x11; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x20; + dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = 0xff; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; + dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; + dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; + dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; + dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; + dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5511_smram_recalc(dev); + sis_5511_shadow_recalc(dev); + + flushmmucache(); + + memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); + dev->slic_regs[0x18] = 0x0f; + + mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); +} + +static void +sis_5511_host_to_pci_close(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5511_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) calloc(1, sizeof(sis_5511_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SLiC Memory Mapped Registers */ + mem_mapping_add(&dev->slic_mapping, + 0xffc00000, 0x00001000, + sis_5511_slic_read, + NULL, + NULL, + sis_5511_slic_write, + NULL, + NULL, + NULL, MEM_MAPPING_EXTERNAL, + dev); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5511_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5511_h2p_device = { + .name = "SiS 5511 Host to PCI bridge", + .internal_name = "sis_5511_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5511_host_to_pci_init, + .close = sis_5511_host_to_pci_close, + .reset = sis_5511_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c new file mode 100644 index 000000000..130f2abd5 --- /dev/null +++ b/src/chipset/sis_5513_ide.c @@ -0,0 +1,501 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5513 IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_IDE_LOG +int sis_5513_ide_do_log = ENABLE_SIS_5513_IDE_LOG; + +static void +sis_5513_ide_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_ide_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_ide_log(fmt, ...) +#endif + +typedef struct sis_5513_ide_t { + uint8_t rev; + + uint8_t pci_conf[256]; + + sis_55xx_common_t *sis; +} sis_5513_ide_t; + +static void +sis_5513_ide_irq_handler(sis_5513_ide_t *dev) +{ + if (dev->pci_conf[0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5513_ide_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5513_ide_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf[0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5513_ide_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5513_ide_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5513_ide_handler(sis_5513_ide_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf[0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf[0x11] | dev->pci_conf[0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf[0x15] | dev->pci_conf[0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf[0x19] | dev->pci_conf[0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf[0x1c] | dev->pci_conf[0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf[0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf[0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf[0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf[0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5513_ide_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5513_ide_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x02) { + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5513_ide_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x04) { + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5513_ide_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->sis->bm[0], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 0); + sff_bus_master_handler(dev->sis->bm[1], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 8); +} + +void +sis_5513_ide_write(int addr, uint8_t val, void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + sis_5513_ide_log("SiS 5513 IDE: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf[addr] = val & 0x05; + sis_5513_ide_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf[addr] = val & 0x20; + break; + case 0x07: /* Status high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x38); + break; + case 0x09: /* Programming Interface Byte */ + switch (dev->rev) { + case 0xd0: + if (dev->sis->ide_bits_1_3_writable) + val |= 0x0a; + fallthrough; + case 0x00: + case 0xd1: + val &= 0xbf; + fallthrough; + case 0xc0: + switch (val & 0x0a) { + case 0x00: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x85) | (val & 0x4a); + break; + case 0x02: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x84) | (val & 0x4b); + break; + case 0x08: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x81) | (val & 0x4e); + break; + case 0x0a: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x80) | (val & 0x4f); + break; + } + break; + } + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + break; + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + /* Primary Base Address */ + case 0x10 ... 0x11: + case 0x14 ... 0x15: + fallthrough; + + /* Secondary Base Address */ + case 0x18 ... 0x19: + case 0x1c ... 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20 ... 0x21: + if (addr == 0x20) + dev->pci_conf[addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf[addr] = val; + sis_5513_ide_handler(dev); + break; + + case 0x2c ... 0x2f: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x30 ... 0x33: /* Expansion ROM Base Address */ +#ifdef DATASHEET + dev->pci_conf[addr] = val; +#else + if (dev->rev == 0x00) + dev->pci_conf[addr] = val; +#endif + break; + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xcf; + else + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xe7; + else + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x4a: /* IDE General Control Register 0 */ + switch (dev->rev) { + case 0x00: + dev->pci_conf[addr] = val & 0x9e; + break; + case 0xc0: + dev->pci_conf[addr] = val & 0xaf; + break; + case 0xd0: + dev->pci_conf[addr] = val; + break; + } + sis_5513_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control Register 1 */ + if (dev->rev >= 0xc0) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf[addr] = val; + break; + + case 0x50: + case 0x51: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x52: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0x0f; + break; + + default: + break; + } +} + +uint8_t +sis_5513_ide_read(int addr, void *priv) +{ + const sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x09: + ret = dev->pci_conf[addr]; + if (dev->rev >= 0xc0) { + if (dev->pci_conf[0x09] & 0x40) + ret |= ((dev->pci_conf[0x4a] & 0x06) << 3); + if ((dev->rev == 0xd0) && dev->sis->ide_bits_1_3_writable) + ret |= 0x0a; + } + break; + case 0x3d: + if (dev->rev >= 0xc0) + ret = (dev->pci_conf[0x09] & 0x05) ? PCI_INTA : 0x00; + else + ret = (((dev->pci_conf[0x4b] & 0xc0) == 0xc0) || + (dev->pci_conf[0x09] & 0x05)) ? PCI_INTA : 0x00; + break; + } + + sis_5513_ide_log("SiS 5513 IDE: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_ide_reset(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x13; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = dev->pci_conf[0x07] = 0x00; + dev->pci_conf[0x08] = (dev->rev == 0xd1) ? 0xd0 : dev->rev; + dev->pci_conf[0x09] = 0x8a; + dev->pci_conf[0x0a] = dev->pci_conf[0x0b] = 0x01; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0xf1; + dev->pci_conf[0x11] = 0x01; + dev->pci_conf[0x14] = 0xf5; + dev->pci_conf[0x15] = 0x03; + dev->pci_conf[0x18] = 0x71; + dev->pci_conf[0x19] = 0x01; + dev->pci_conf[0x1c] = 0x75; + dev->pci_conf[0x1d] = 0x03; + dev->pci_conf[0x20] = 0x01; + dev->pci_conf[0x21] = 0xf0; + dev->pci_conf[0x22] = dev->pci_conf[0x23] = 0x00; + dev->pci_conf[0x24] = dev->pci_conf[0x25] = 0x00; + dev->pci_conf[0x26] = dev->pci_conf[0x27] = 0x00; + dev->pci_conf[0x28] = dev->pci_conf[0x29] = 0x00; + dev->pci_conf[0x2a] = dev->pci_conf[0x2b] = 0x00; + switch (dev->rev) { + case 0x00: + case 0xd0: + case 0xd1: + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; + break; + case 0xc0: +#ifdef DATASHEET + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; +#else + /* The only Linux lspci listing I could find of this chipset, + shows a subsystem of 0058:0000. */ + dev->pci_conf[0x2c] = 0x58; + dev->pci_conf[0x2d] = 0x00; +#endif + break; + } + dev->pci_conf[0x2e] = dev->pci_conf[0x2f] = 0x00; + dev->pci_conf[0x30] = dev->pci_conf[0x31] = 0x00; + dev->pci_conf[0x32] = dev->pci_conf[0x33] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = 0x06; + dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + + sff_bus_master_reset(dev->sis->bm[0]); + sff_bus_master_reset(dev->sis->bm[1]); +} + +static void +sis_5513_ide_close(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + free(dev); +} + +static void * +sis_5513_ide_init(UNUSED(const device_t *info)) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) calloc(1, sizeof(sis_5513_ide_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* SFF IDE */ + dev->sis->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->sis->bm[1] = device_add_inst(&sff8038i_device, 2); + + sis_5513_ide_reset(dev); + + return dev; +} + +const device_t sis_5513_ide_device = { + .name = "SiS 5513 IDE controller", + .internal_name = "sis_5513_ide", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_ide_device = { + .name = "SiS 5572 IDE controller", + .internal_name = "sis_5572_ide", + .flags = DEVICE_PCI, + .local = 0xc0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_ide_device = { + .name = "SiS 5582 IDE controller", + .internal_name = "sis_5582_ide", + .flags = DEVICE_PCI, + .local = 0xd0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_5600_ide_device = { + .name = "SiS 5591/(5)600 IDE controller", + .internal_name = "sis_5591_5600_ide", + .flags = DEVICE_PCI, + .local = 0xd1, /* D0, but we need to distinguish them. */ + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c new file mode 100644 index 000000000..df18cc4b3 --- /dev/null +++ b/src/chipset/sis_5513_p2i.c @@ -0,0 +1,1354 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5513 PCI to ISA bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_PCI_TO_ISA_LOG +int sis_5513_pci_to_isa_do_log = ENABLE_SIS_5513_PCI_TO_ISA_LOG; + +static void +sis_5513_pci_to_isa_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_pci_to_isa_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_pci_to_isa_log(fmt, ...) +#endif + +typedef struct sis_5513_pci_to_isa_t { + uint8_t rev; + uint8_t index; + uint8_t dam_index; + uint8_t irq_state; + uint8_t dam_enable; + uint8_t dam_irq_enable; + uint8_t ddma_enable; + uint8_t pci_conf[256]; + uint8_t regs[16]; + uint8_t dam_regs[256]; + uint8_t apc_regs[256]; + + uint16_t dam_base; + uint16_t ddma_base; + uint16_t acpi_io_base; + + sis_55xx_common_t *sis; + port_92_t *port_92; + void *pit; + nvr_t *nvr; + ddma_t *ddma; + acpi_t *acpi; + void *smbus; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); +} sis_5513_pci_to_isa_t; + +static void +sis_5595_acpi_recalc(sis_5513_pci_to_isa_t *dev) +{ + dev->acpi_io_base = (dev->pci_conf[0x91] << 8) | (dev->pci_conf[0x90] & 0xc0); + acpi_update_io_mapping(dev->sis->acpi, dev->acpi_io_base, (dev->pci_conf[0x40] & 0x80)); +} + +static void +sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) +{ + memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); + + if (dev->rev == 0b0) { + dev->apc_regs[0x03] = 0x80; + dev->apc_regs[0x04] = 0x38; + dev->apc_regs[0x07] = 0x01; + } else + dev->apc_regs[0x04] = 0x08; +} + +static void +sis_5513_apc_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + + sis_5513_pci_to_isa_log("SiS 5595 APC: [W] %04X = %02X\n", addr, val); + + switch (nvr_index) { + case 0x02 ... 0x04: + dev->apc_regs[nvr_index] = val; + break; + case 0x05: + case 0x07 ... 0x08: + if (dev->rev == 0xb0) + dev->apc_regs[nvr_index] = val; + break; + } +} + +static uint8_t +sis_5513_apc_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + uint8_t ret = 0xff; + + ret = dev->apc_regs[nvr_index]; + + if (nvr_index == 0x06) + dev->apc_regs[nvr_index] = 0x00; + + sis_5513_pci_to_isa_log("SiS 5595 APC: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +void +sis_5513_apc_recalc(sis_5513_pci_to_isa_t *dev, uint8_t apc_on) +{ + nvr_at_data_port(!apc_on, dev->nvr); + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); + + if (apc_on) + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); +} + +static void +sis_5595_do_nmi(sis_5513_pci_to_isa_t *dev, int set) +{ + if (set) + nmi_raise(); + + dev->irq_state = set; +} + +static void +sis_5595_dam_reset(sis_5513_pci_to_isa_t *dev) +{ + if (dev->irq_state) { + if (dev->dam_regs[0x40] & 0x20) + sis_5595_do_nmi(dev, 0); + else if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + } + + memset(dev->dam_regs, 0x00, sizeof(dev->dam_regs)); + + dev->dam_regs[0x40] = 0x08; + dev->dam_regs[0x47] = 0x50; +} + +static void +sis_5595_dam_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t old; + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [W] %04X = %02X\n", addr, val); + + switch (reg) { + case 0x05: + dev->dam_index = (dev->index & 0x80) | (val & 0x7f); + break; + case 0x06: + switch (dev->dam_index) { + case 0x40: + old = dev->dam_regs[0x40]; + dev->dam_regs[0x40] = val & 0xef; + if (val & 0x80) { + sis_5595_dam_reset(dev); + return; + } + if (dev->irq_state) { + if (!(old & 0x20) && (val & 0x20)) { + if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + sis_5595_do_nmi(dev, 1); + } else if ((old & 0x20) && !(val & 0x20)) { + sis_5595_do_nmi(dev, 0); + if (dev->dam_irq_enable) + pci_set_mirq(6, 1, &dev->irq_state); + } + } + if ((val & 0x08) && dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + break; + case 0x43 ... 0x47: + dev->dam_regs[dev->dam_index] = val; + break; + case 0x2b ... 0x34: + case 0x6b ... 0x74: + case 0x3b ... 0x3c: + case 0x7b ... 0x7c: + dev->dam_regs[dev->dam_index & 0x3f] = val; + break; + } + break; + } +} + +static uint8_t +sis_5595_dam_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t ret = 0xff; + + switch (reg) { + case 0x05: + ret = dev->dam_index; + break; + case 0x06: + switch (dev->dam_index) { + default: + ret = dev->dam_regs[dev->dam_index]; + break; + case 0x20 ... 0x29: + case 0x2b ... 0x3f: + ret = dev->dam_regs[dev->dam_index & 0x3f]; + break; + case 0x2a: + case 0x6a: + ret = dev->pci_conf[0x78]; + break; + } + break; + } + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_dam_recalc(sis_5513_pci_to_isa_t *dev) +{ + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_removehandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); + + dev->dam_base = dev->pci_conf[0x68] | (dev->pci_conf[0x69] << 16); + dev->dam_enable = !!(dev->pci_conf[0x7b] & 0x80); + + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_sethandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); +} + +static void +sis_5595_ddma_recalc(sis_5513_pci_to_isa_t *dev) +{ + uint16_t ch_base; + + dev->ddma_base = (dev->pci_conf[0x80] & 0xf0) | (dev->pci_conf[0x81] << 16); + dev->ddma_enable = !!(dev->pci_conf[0x80] & 0x01); + + for (uint8_t i = 0; i < 8; i++) { + ch_base = dev->ddma_base + (i << 4); + ddma_update_io_mapping(dev->ddma, i, ch_base & 0xff, (ch_base >> 8), + dev->ddma_enable && (dev->pci_conf[0x84] & (1 << i)) && + (dev->ddma_base != 0x0000)); + } +} + +static void +sis_5513_00_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + switch (addr) { + case 0x60: /* MIRQ0 Remapping Control Register */ + case 0x61: /* MIRQ1 Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO0 Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x80; + break; + + case 0x66: /* GPIO0 Output Mode Control Register */ + case 0x67: /* GPIO0 Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x6a: /* GPIO Status Register */ + dev->pci_conf[addr] |= (val & 0x10); + dev->pci_conf[addr] &= ~(val & 0x01); + break; + + default: + break; + } +} + +static void +sis_5513_01_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ + case 0x61: /* MIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x69: + dev->pci_conf[addr] = val; + break; + + case 0x6a: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x6c: + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x02) | (val & 0xdc); + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf[addr] = val; + break; + + default: + break; + } +} + +static void +sis_5513_11_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + dev->sis->ide_bits_1_3_writable = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* GPCS0 Control Register */ + case 0x64: /* GPCS1 Control Register */ + case 0x65: /* GPCS0 Output Mode Control Register */ + case 0x66: /* GPCS0 Output Mode Control Register */ + case 0x67: /* GPCS1 Output Mode Control Register */ + case 0x68: /* GPCS1 Output Mode Control Register */ + case 0x6b: + case 0x6c: + dev->pci_conf[addr] = val; + break; + + case 0x69: /* GPCS0/1 De-Bounce Control Register */ + dev->pci_conf[addr] = val & 0xdf; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x10)) { + plat_power_off(); + return; + } + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x71: /* Type F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ Control */ + dev->pci_conf[addr] = val & 0xfa; + break; + case 0x73: /* SMI Triggered By IRQ Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x77: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x76: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val & 0xfb; + break; + dev->pci_conf[addr] = val; + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + dev->pci_conf[addr] = val; + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +static void +sis_5513_b0_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xdf; + sff_set_mirq(dev->sis->bm[0], (val & 0x10) ? 7 : 2); + sff_set_mirq(dev->sis->bm[1], (val & 0x10) ? 2 : 7); + pci_set_mirq_routing(PCI_MIRQ7, 14 + (!!(val & 0x10))); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* PCI OutputBuffer Current Strength Register */ + dev->pci_conf[addr] = val; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x04)) { + plat_power_off(); + return; + } + if ((val & 0x18) == 0x18) { + dma_reset(); + dma_set_at(1); + + device_reset_all(DEVICE_ALL); + + cpu_alt_reset = 0; + + pci_reset(); + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); + } + break; + + case 0x64: /* INIT Enable Register */ + dev->pci_conf[addr] = val; + cpu_cpurst_on_sr = !(val & 0x20); + break; + + case 0x65: /* PHOLD# Timer */ + case 0x66: /* Priority Timer */ + case 0x67: /* Respond to C/D Segments Register */ + case 0x6b: /* Test Mode Register I */ + case 0x6c: /* Test Mode Register II */ + case 0x71: /* Reserved */ + case 0x72: /* Individual PC/PCI DMA Channel Enable */ + case 0x7c: /* Data Acquisition Module ADC Calibration */ + case 0x7d: /* Data Acquisition Module ADC Calibration */ + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + case 0x8c: /* Serial Interrupt Enable Register 3 */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* Data Acquistion Module Base Address */ + dev->pci_conf[addr] = val & 0xf8; + sis_5595_dam_recalc(dev); + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x73: + case 0x75 ... 0x79: + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + break; + + case 0x7a: /* Data Acquisition Module Function Selection Register */ + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0x90; + break; + + case 0x7b: /* Data Acquisition Module Control Register */ + dev->pci_conf[addr] = val; + sis_5595_dam_recalc(dev); + break; + + case 0x7e: /* Data Acquisition Module and SMBUS IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: DAM/SMBUS IRQ -> %02X\n", val); + if (dev->rev == 0x81) + dev->pci_conf[addr] = val & 0x8f; + else { + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x10) | (val & 0xef); + + dev->dam_irq_enable = ((val & 0xc0) == 0x40); + smbus_sis5595_irq_enable(dev->smbus, (val & 0xa0) == 0x20); + } + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ6, val & 0xf); + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +void +sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x07: /* Status */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x30); + break; + + case 0x0d: /* Master Latency Timer */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x40: /* BIOS Control Register */ + if (dev->rev >= 0x11) { + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + } else + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + case 0x44: /* INTD# Remapping Control Register */ + if (dev->rev == 0x11) { + dev->pci_conf[addr] = val & 0xcf; + sis_5513_apc_recalc(dev, val & 0x10); + } else + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + + case 0x45: /* ISA Bus Control Register I */ + if (dev->rev >= 0x01) { + if (dev->rev == 0x01) + dev->pci_conf[addr] = val & 0xec; + else + dev->pci_conf[addr] = val; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + if (dev->rev == 0xb0) + sis_5513_apc_recalc(dev, val & 0x02); + } + break; + case 0x46: /* ISA Bus Control Register II */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + else if (dev->rev == 0x00) + dev->pci_conf[addr] = val & 0xec; + break; + case 0x47: /* DMA Clock and Wait State Control Register */ + switch (dev->rev) { + case 0x01: + dev->pci_conf[addr] = val & 0x3e; + break; + case 0x11: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xb0: + dev->pci_conf[addr] = val & 0xfd; + break; + } + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf[addr] = val; + break; + + default: + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_write(addr, val, priv); + break; + case 0x01: + sis_5513_01_pci_to_isa_write(addr, val, priv); + break; + case 0x11: + sis_5513_11_pci_to_isa_write(addr, val, priv); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_write(addr, val, priv); + break; + } + break; + } +} + +uint8_t +sis_5513_pci_to_isa_read(int addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + case 0x60: + if (dev->rev >= 0x01) + ret = inb(0x0070); + else + ret = dev->pci_conf[addr]; + break; + } + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + switch (addr) { + case 0x22: + dev->index = val - 0x50; + break; + case 0x23: + sis_5513_pci_to_isa_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); + + switch (dev->index) { + case 0x00: + dev->regs[dev->index] = val & 0xed; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + break; + case 0x01: + dev->regs[dev->index] = val & 0xf4; + break; + case 0x03: + dev->regs[dev->index] = val & 3; + break; + case 0x04: /* BIOS Register */ + dev->regs[dev->index] = val; + break; + case 0x05: + dev->regs[dev->index] = val; + outb(0x70, val); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +sis_5513_isa_read(uint16_t addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + if (addr == 0x23) { + if (dev->index == 0x05) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + + sis_5513_pci_to_isa_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); + } + + return ret; +} + +static void +sis_5513_00_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x04; + + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + + dev->regs[0x00] = dev->regs[0x01] = 0x00; + dev->regs[0x03] = dev->regs[0x04] = 0x00; + dev->regs[0x05] = 0x00; + dev->regs[0x08] = dev->regs[0x09] = 0x00; + dev->regs[0x0a] = dev->regs[0x0b] = 0x00; +} + +static void +sis_5513_01_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x80; + dev->pci_conf[0x69] = dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x02; + dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); +} + +static void +sis_5513_11_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = dev->pci_conf[0x68] = 0x00; + dev->pci_conf[0x69] = 0x01; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = dev->pci_conf[0x76] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + dev->sis->ide_bits_1_3_writable = 0; + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); +} + +static void +sis_5513_b0_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x01; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x90; + dev->pci_conf[0x69] = 0x02; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x8b] = dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ7, 15); + + sff_set_mirq(dev->sis->bm[0], 2); + sff_set_mirq(dev->sis->bm[1], 7); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + /* SiS 5595 Data Acquisition Module */ + sis_5595_dam_recalc(dev); + sis_5595_dam_reset(dev); + + dev->dam_irq_enable = 0; + + cpu_cpurst_on_sr = 1; + + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); + + if (dev->rev == 0x81) + dev->dam_irq_enable = 1; +} + +static void +sis_5513_pci_to_isa_reset(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x08; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + if ((dev->rev == 0x11) || (dev->rev == 0x81)) + dev->pci_conf[0x08] = 0x01; + else + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x01; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x40] = 0x00; + dev->pci_conf[0x41] = dev->pci_conf[0x42] = 0x80; + dev->pci_conf[0x43] = dev->pci_conf[0x44] = 0x80; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_reset(dev); + break; + case 0x01: + sis_5513_01_pci_to_isa_reset(dev); + break; + case 0x11: + sis_5513_11_pci_to_isa_reset(dev); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_reset(dev); + break; + } + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); +} + +static void +sis_5513_pci_to_isa_close(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + free(dev); +} + +static void * +sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) calloc(1, sizeof(sis_5513_pci_to_isa_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* IDEIRQ */ + pci_enable_mirq(2); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_device); + + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + switch (dev->rev) { + case 0x00: + /* MIRQ */ + pci_enable_mirq(0); + pci_enable_mirq(1); + + /* Ports 22h-23h: SiS 5513 ISA */ + io_sethandler(0x0022, 0x0002, + sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); + break; + case 0x01: + /* MIRQ */ + pci_enable_mirq(1); + break; + case 0x11: + case 0x81: + case 0xb0: + /* USBIRQ */ + pci_enable_mirq(3); + + /* ACPI/SCI IRQ */ + pci_enable_mirq(5); + + if (dev->rev == 0xb0) { + /* Data Acquisition Module and SMBUS IRQ */ + pci_enable_mirq(6); + + /* Non-remapped native IDE IRQ */ + pci_enable_mirq(7); + } + + dev->ddma = device_add(&ddma_device); + + switch (dev->rev) { + case 0x11: + dev->sis->acpi = device_add(&acpi_sis_5582_device); + break; + case 0x81: + dev->sis->acpi = device_add(&acpi_sis_5595_1997_device); + break; + case 0xb0: + dev->sis->acpi = device_add(&acpi_sis_5595_device); + dev->smbus = acpi_get_smbus(dev->sis->acpi); + break; + } + + dev->sis->acpi->priv = dev->sis; + acpi_set_slot(dev->sis->acpi, dev->sis->sb_pci_slot); + acpi_set_nvr(dev->sis->acpi, dev->nvr); + acpi_set_irq_mode(dev->sis->acpi, 2); + break; + } + + sis_5513_pci_to_isa_reset(dev); + + return dev; +} + +const device_t sis_5513_p2i_device = { + .name = "SiS 5513 PCI to ISA bridge", + .internal_name = "sis_5513_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_p2i_device = { + .name = "SiS 5572 PCI to ISA bridge", + .internal_name = "sis_5572_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_p2i_device = { + .name = "SiS 5582 PCI to ISA bridge", + .internal_name = "sis_5582_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x11, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5595 1997, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_1997_p2i_device = { + .name = "SiS 5595 (1997) PCI to ISA bridge", + .internal_name = "sis_5595_1997_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x81, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5582, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_p2i_device = { + .name = "SiS 5595 PCI to ISA bridge", + .internal_name = "sis_5595_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 007a96178..3fb111978 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -6,11 +6,11 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 5571 Pentium PCI/ISA Chipset. + * Implementation of the SiS 5571/5572 Pentium PCI/ISA Chipset. * * Authors: Miran Grca, * - * Copyright 2023-2024 Miran Grca. + * Copyright 2021-2023 Miran Grca. */ #include #include @@ -23,10 +23,10 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - -// #include <86box/dma.h> #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -40,8 +40,7 @@ #include <86box/port_92.h> #include <86box/smram.h> #include <86box/spd.h> -#include <86box/usb.h> - +#include <86box/sis_55xx.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_5571_LOG @@ -63,1128 +62,90 @@ sis_5571_log(const char *fmt, ...) #endif typedef struct sis_5571_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t nb_slot; + uint8_t sb_slot; - uint8_t regs[16]; - uint8_t states[7]; - uint8_t pad0; + void *h2p; + void *p2i; + void *ide; + void *usb; - uint8_t usb_unk_regs[8]; - - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[3][256]; - - uint16_t usb_unk_base; - - sff8038i_t *bm[2]; - smram_t *smram; - port_92_t *port_92; - void *pit; - nvr_t *nvr; - usb_t *usb; - - uint8_t (*pit_read_reg)(void *priv, uint8_t reg); + sis_55xx_common_t *sis; } sis_5571_t; static void -sis_5571_shadow_recalc(sis_5571_t *dev) +sis_5571_write(int func, int addr, uint8_t val, void *priv) { - int state; - uint32_t base; + const sis_5571_t *dev = (sis_5571_t *) priv; - for (uint8_t i = 0x70; i <= 0x76; i++) { - if (i == 0x76) { - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - sis_5571_log("000F0000-000FFFFF\n"); - } - } else { - base = ((i & 0x07) << 15) + 0xc0000; + sis_5571_log("SiS 5571: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - sis_5571_log("%08X-%08X\n", base, base + 0x3fff); - } - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - sis_5571_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); - } - } - - dev->states[i & 0x0f] = dev->pci_conf[i]; - } - - flushmmucache_nopc(); -} - -static void -sis_5571_smram_recalc(sis_5571_t *dev) -{ - smram_disable_all(); - - switch (dev->pci_conf[0xa3] >> 6) { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - - default: - break; - } - - flushmmucache(); -} - -static void -sis_5571_mem_to_pci_reset(sis_5571_t *dev) -{ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x71; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0x05; - dev->pci_conf[0x05] = 0x00; - dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x02; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = 0x00; - dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x0c] = 0x00; - dev->pci_conf[0x0d] = 0x00; - dev->pci_conf[0x0e] = 0x00; - dev->pci_conf[0x0f] = 0x00; - - dev->pci_conf[0x50] = 0x00; - dev->pci_conf[0x51] = 0x00; - dev->pci_conf[0x52] = 0x00; - dev->pci_conf[0x53] = 0x00; - dev->pci_conf[0x54] = 0x54; - dev->pci_conf[0x55] = 0x54; - dev->pci_conf[0x56] = 0x03; - dev->pci_conf[0x57] = 0x00; - dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = 0x00; - dev->pci_conf[0x5a] = 0x00; - - /* Undocumented DRAM bank registers. */ - dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; - dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; - dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; - dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; - dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; - dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6b] = 0x80; - - dev->pci_conf[0x70] = 0x00; - dev->pci_conf[0x71] = 0x00; - dev->pci_conf[0x72] = 0x00; - dev->pci_conf[0x73] = 0x00; - dev->pci_conf[0x74] = 0x00; - dev->pci_conf[0x75] = 0x00; - dev->pci_conf[0x76] = 0x00; - - dev->pci_conf[0x77] = 0x00; - dev->pci_conf[0x78] = 0x00; - dev->pci_conf[0x79] = 0x00; - dev->pci_conf[0x7a] = 0x00; - dev->pci_conf[0x7b] = 0x00; - - dev->pci_conf[0x80] = 0x00; - dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = 0x00; - dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = 0x00; - dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; - dev->pci_conf[0x87] = 0x00; - - dev->pci_conf[0x8c] = 0x00; - dev->pci_conf[0x8d] = 0x00; - dev->pci_conf[0x8e] = 0x00; - dev->pci_conf[0x8f] = 0x00; - - dev->pci_conf[0x90] = 0x00; - dev->pci_conf[0x91] = 0x00; - dev->pci_conf[0x92] = 0x00; - dev->pci_conf[0x93] = 0x00; - dev->pci_conf[0x93] = 0x00; - dev->pci_conf[0x94] = 0x00; - dev->pci_conf[0x95] = 0x00; - dev->pci_conf[0x96] = 0x00; - dev->pci_conf[0x97] = 0x00; - dev->pci_conf[0x98] = 0x00; - dev->pci_conf[0x99] = 0x00; - dev->pci_conf[0x9a] = 0x00; - dev->pci_conf[0x9b] = 0x00; - dev->pci_conf[0x9c] = 0x00; - dev->pci_conf[0x9d] = 0x00; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - - dev->pci_conf[0xa0] = 0xff; - dev->pci_conf[0xa1] = 0x00; - dev->pci_conf[0xa2] = 0xff; - dev->pci_conf[0xa3] = 0x00; - - cpu_cache_ext_enabled = 0; - cpu_update_waitstates(); - - sis_5571_smram_recalc(dev); - sis_5571_shadow_recalc(dev); - - flushmmucache(); -} - -static void -sis_5571_mem_to_pci_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - if (func == 0) { - sis_5571_log("SiS 5571 M2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command - low byte */ - case 0x05: /* Command - high byte */ - dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= ~(val & 0xb8); - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; - break; - - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xec; - break; - - case 0x51: /* CACHE */ - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x52: - dev->pci_conf[addr] = val & 0xd0; - break; - - case 0x53: /* DRAM */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x54: /* FP/EDO */ - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xe0; - break; - - case 0x56: /* MDLE delay */ - dev->pci_conf[addr] = val & 0x07; - break; - - case 0x57: /* SDRAM */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x59: /* Buffer strength and current rating */ - dev->pci_conf[addr] = val; - break; - - case 0x5a: - dev->pci_conf[addr] = val & 0x03; - break; - - /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ - case 0x60 ... 0x6b: - dev->pci_conf[addr] = val; - break; - - case 0x70 ... 0x75: - dev->pci_conf[addr] = val & 0xee; - sis_5571_shadow_recalc(dev); - break; - case 0x76: - dev->pci_conf[addr] = val & 0xe8; - sis_5571_shadow_recalc(dev); - break; - - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x78: /* Allocation of Non-Cacheable area #1 */ - case 0x79: /* NCA1REG2 */ - case 0x7a: /* Allocation of Non-Cacheable area #2 */ - case 0x7b: /* NCA2REG2 */ - dev->pci_conf[addr] = val; - break; - - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xcc; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ - break; - - case 0x84 ... 0x86: - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellanea */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x90: /* PMU control register */ - case 0x91: /* Address trap for green function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - - if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { - smi_raise(); - dev->pci_conf[0x9d] |= 0x01; - } - break; - - case 0x94: /* 6x86 and Green function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: /* Test mode control */ - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x97: /* programmable 10-bit I/O port address */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99 ... 0x9c: - dev->pci_conf[addr] = val; - break; - - case 0x9d: - dev->pci_conf[addr] &= val; - break; - - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0 ... 0xa2: - dev->pci_conf[addr] = val; - break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5571_smram_recalc(dev); - break; - - default: - break; - } - } + if (func == 0x00) + sis_5571_host_to_pci_write(addr, val, dev->h2p); } static uint8_t -sis_5571_mem_to_pci_read(int func, int addr, void *priv) +sis_5571_read(int func, int addr, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) { - ret = dev->pci_conf[addr]; + if (func == 0x00) + ret = sis_5571_host_to_pci_read(addr, dev->h2p); - sis_5571_log("SiS 5571 M2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); - } + sis_5571_log("SiS 5571: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } static void -sis_5571_pci_to_isa_reset(sis_5571_t *dev) -{ - /* PCI to ISA Bridge */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x03] = 0x00; - dev->pci_conf_sb[0][0x04] = 0x07; - dev->pci_conf_sb[0][0x05] = 0x00; - dev->pci_conf_sb[0][0x06] = 0x00; - dev->pci_conf_sb[0][0x07] = 0x02; - dev->pci_conf_sb[0][0x08] = 0x01; - dev->pci_conf_sb[0][0x09] = 0x00; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; - dev->pci_conf_sb[0][0x0e] = 0x80; - - dev->pci_conf_sb[0][0x40] = 0x00; - dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; - dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; - dev->pci_conf_sb[0][0x45] = 0x00; - dev->pci_conf_sb[0][0x46] = 0x00; - dev->pci_conf_sb[0][0x47] = 0x00; - dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; - dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; - dev->pci_conf_sb[0][0x61] = 0x80; - dev->pci_conf_sb[0][0x62] = 0x00; - dev->pci_conf_sb[0][0x63] = 0x80; - dev->pci_conf_sb[0][0x64] = 0x00; - dev->pci_conf_sb[0][0x65] = 0x00; - dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; - dev->pci_conf_sb[0][0x68] = 0x80; - dev->pci_conf_sb[0][0x69] = dev->pci_conf_sb[0][0x6a] = 0x00; - dev->pci_conf_sb[0][0x6b] = 0x00; - dev->pci_conf_sb[0][0x6c] = 0x02; - dev->pci_conf_sb[0][0x6d] = 0x00; - dev->pci_conf_sb[0][0x6e] = dev->pci_conf_sb[0][0x6f] = 0x00; - dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; - dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; - dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x75] = 0x00; - dev->pci_conf_sb[0][0x76] = dev->pci_conf_sb[0][0x77] = 0x00; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); - - cpu_set_isa_speed(7159091); - nvr_bank_set(0, 0, dev->nvr); -} - -static void -sis_5571_pci_to_isa_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t old; - - sis_5571_log("SiS 5571 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); - - switch (addr) { - default: - break; - - case 0x04: /* Command */ - // dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= ~(val & 0x30); - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xec; - switch (val >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - - default: - break; - } - nvr_bank_set(0, !!(val & 0x08), dev->nvr); - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val & 0xec; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3e; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x60: - outb(0x0070, val); - break; - - /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ - case 0x61: /* MIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); - break; - - case 0x64: /* GPIO Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x66: /* GPIO Output Mode Control Register */ - case 0x67: /* GPIO Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x68: /* USBIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: USBIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); - break; - - case 0x69: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: - dev->pci_conf_sb[0][addr] = val & 0xfc; - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0x02; - break; - - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - old = dev->pci_conf_sb[0][addr]; - picint((val ^ old) & val); - picintc((val ^ old) & ~val); - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - old = dev->pci_conf_sb[0][addr]; - picint(((val ^ old) & val) << 8); - picintc(((val ^ old) & ~val) << 8); - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x70: - dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x02) | (val & 0xdc); - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x72: /* SMI Triggered By IRQ/GPIO Control */ - case 0x73: /* SMI Triggered By IRQ/GPIO Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x74: /* System Standby Timer Reload, - System Standby State Exit And Throttling State Exit Control */ - case 0x75: /* System Standby Timer Reload, - System Standby State Exit And Throttling State Exit Control */ - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - dev->pci_conf_sb[0][addr] = val; - break; - } -} - -static uint8_t -sis_5571_pci_to_isa_read(int addr, void *priv) +sis_5572_write(int func, int addr, uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - switch (addr) { - default: - ret = dev->pci_conf_sb[0][addr]; - break; - case 0x4c ... 0x4f: - ret = pic_read_icw(0, addr & 0x03); - break; - case 0x50 ... 0x53: - ret = pic_read_icw(1, addr & 0x03); - break; - case 0x54 ... 0x55: - ret = pic_read_ocw(0, addr & 0x01); - break; - case 0x56 ... 0x57: - ret = pic_read_ocw(1, addr & 0x01); - break; - case 0x58 ... 0x5f: - ret = dev->pit_read_reg(dev->pit, addr & 0x07); - break; - case 0x60: - ret = inb(0x0070); - break; - } + sis_5571_log("SiS 5572: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - sis_5571_log("SiS 5571 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); - - return ret; -} - -static void -sis_5571_ide_irq_handler(sis_5571_t *dev) -{ - if (dev->pci_conf_sb[1][0x09] & 0x01) { - /* Primary IDE is native. */ - sis_5571_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); - } else { - /* Primary IDE is legacy. */ - sis_5571_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - } - - if (dev->pci_conf_sb[1][0x09] & 0x04) { - /* Secondary IDE is native. */ - sis_5571_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); - } else { - /* Secondary IDE is legacy. */ - sis_5571_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); - } -} - -static void -sis_5571_ide_handler(sis_5571_t *dev) -{ - uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; - - uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; - uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; - uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; - uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; - - uint16_t current_pri_base; - uint16_t current_pri_side; - uint16_t current_sec_base; - uint16_t current_sec_side; - - /* Primary Channel Programming */ - current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; - current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; - - /* Secondary Channel Programming */ - current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; - current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; - - sis_5571_log("sis_5571_ide_handler(): Disabling primary IDE...\n"); - ide_pri_disable(); - sis_5571_log("sis_5571_ide_handler(): Disabling secondary IDE...\n"); - ide_sec_disable(); - - if (ide_io_on) { - /* Primary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x02) { - sis_5571_log("sis_5571_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); - ide_set_base(0, current_pri_base); - sis_5571_log("sis_5571_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); - ide_set_side(0, current_pri_side); - - sis_5571_log("sis_5571_ide_handler(): Enabling primary IDE...\n"); - ide_pri_enable(); - - sis_5571_log("SiS 5571 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); - } - - /* Secondary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x04) { - sis_5571_log("sis_5571_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); - ide_set_base(1, current_sec_base); - sis_5571_log("sis_5571_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); - ide_set_side(1, current_sec_side); - - sis_5571_log("sis_5571_ide_handler(): Enabling secondary IDE...\n"); - ide_sec_enable(); - - sis_5571_log("SiS 5571: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); - } - } - - sff_bus_master_handler(dev->bm[0], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); - sff_bus_master_handler(dev->bm[1], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); -} - -static void -sis_5571_ide_reset(sis_5571_t *dev) -{ - /* PCI IDE */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; - dev->pci_conf_sb[1][0x08] = 0xc0; - dev->pci_conf_sb[1][0x09] = 0x8a; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x0f] = 0x00; - dev->pci_conf_sb[1][0x10] = 0xf1; - dev->pci_conf_sb[1][0x11] = 0x01; - dev->pci_conf_sb[1][0x14] = 0xf5; - dev->pci_conf_sb[1][0x15] = 0x03; - dev->pci_conf_sb[1][0x18] = 0x71; - dev->pci_conf_sb[1][0x19] = 0x01; - dev->pci_conf_sb[1][0x1c] = 0x75; - dev->pci_conf_sb[1][0x1d] = 0x03; - dev->pci_conf_sb[1][0x20] = 0x01; - dev->pci_conf_sb[1][0x21] = 0xf0; - dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; - dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; - dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; - dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; - dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; -#ifdef DATASHEET - dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; -#else - /* The only Linux lspci listing I could find of this chipset, - shows a subsystem of 0058:0000. */ - dev->pci_conf_sb[1][0x2c] = 0x58; - dev->pci_conf_sb[1][0x2d] = 0x00; -#endif - dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; - dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; - dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; - dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; - dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; - dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; - dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; - dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; - dev->pci_conf_sb[1][0x4a] = 0x06; - dev->pci_conf_sb[1][0x4b] = 0x00; - dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; - dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; - - sis_5571_ide_irq_handler(dev); - sis_5571_ide_handler(dev); - - sff_bus_master_reset(dev->bm[0]); - sff_bus_master_reset(dev->bm[1]); -} - -static void -sis_5571_ide_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - sis_5571_log("SiS 5571 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); - - switch (addr) { - default: - break; - - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5571_ide_handler(dev); - break; - case 0x06: /* Status low byte */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); - break; - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x45); - sis_5571_ide_irq_handler(dev); - sis_5571_ide_handler(dev); - break; - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - /* Primary Base Address */ - case 0x10: - case 0x11: - case 0x14: - case 0x15: - fallthrough; - - /* Secondary Base Address */ - case 0x18: - case 0x19: - case 0x1c: - case 0x1d: - fallthrough; - - /* Bus Mastering Base Address */ - case 0x20: - case 0x21: - if (addr == 0x20) - dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; - else - dev->pci_conf_sb[1][addr] = val; - sis_5571_ide_handler(dev); - break; - - /* The only Linux lspci listing I could find of this chipset, - does not show any BIOS bar, therefore writes to that are disabled. */ -#ifdef DATASHEET - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; -#endif - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x07; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0xaf; - sis_5571_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - } -} - -static uint8_t -sis_5571_ide_read(int addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - default: - ret = dev->pci_conf_sb[1][addr]; - break; - - case 0x09: - ret = dev->pci_conf_sb[1][addr]; - if (dev->pci_conf_sb[1][0x09] & 0x40) - ret |= ((dev->pci_conf_sb[1][0x4a] & 0x06) << 3); - break; - - case 0x3d: - ret = (dev->pci_conf_sb[1][0x09] & 0x05) ? PCI_INTA : 0x00; - break; - } - - sis_5571_log("SiS 5571 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); - - return ret; -} - -/* SiS 5571 unknown I/O port (second USB PCI BAR). */ -static void -sis_5571_usb_unk_write(uint16_t addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - addr = (addr - dev->usb_unk_base) & 0x07; - - sis_5571_log("SiS 5571 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); - - dev->usb_unk_regs[addr] = val; -} - -static uint8_t -sis_5571_usb_unk_read(uint16_t addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - addr = (addr - dev->usb_unk_base) & 0x07; - - ret = dev->usb_unk_regs[addr & 0x07]; - - sis_5571_log("SiS 5571 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); - - return ret; -} - -static void -sis_5571_usb_reset(sis_5571_t *dev) -{ - /* USB */ - dev->pci_conf_sb[2][0x00] = 0x39; - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 0x01; - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[2][0x06] = 0x00; - dev->pci_conf_sb[2][0x07] = 0x02; - dev->pci_conf_sb[2][0x08] = 0xb0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 0x03; - dev->pci_conf_sb[2][0x0b] = 0x0c; - dev->pci_conf_sb[2][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[2][0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; - dev->pci_conf_sb[2][0x0f] = 0x00; - dev->pci_conf_sb[2][0x10] = 0x00; - dev->pci_conf_sb[2][0x11] = 0x00; - dev->pci_conf_sb[2][0x12] = 0x00; - dev->pci_conf_sb[2][0x13] = 0x00; - dev->pci_conf_sb[2][0x14] = 0x01; - dev->pci_conf_sb[2][0x15] = 0x00; - dev->pci_conf_sb[2][0x16] = 0x00; - dev->pci_conf_sb[2][0x17] = 0x00; - dev->pci_conf_sb[2][0x3c] = 0x00; - dev->pci_conf_sb[2][0x3d] = PCI_INTA; - dev->pci_conf_sb[2][0x3e] = 0x00; - dev->pci_conf_sb[2][0x3f] = 0x00; - - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); - - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - - dev->usb_unk_base = 0x0000; - - memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); -} - -static void -sis_5571_usb_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - sis_5571_log("SiS 5571 USB: [W] dev->pci_conf_sb[2][%02X] = %02X\n", addr, val); - - if (dev->pci_conf_sb[0][0x68] & 0x40) switch (addr) { - default: - break; - - case 0x04: /* Command - Low Byte */ - dev->pci_conf_sb[2][addr] = val & 0x47; - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - if (dev->pci_conf_sb[2][0x04] & 0x01) - io_sethandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); - break; - - case 0x05: /* Command - High Byte */ - dev->pci_conf_sb[2][addr] = val & 0x01; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf_sb[2][addr] &= ~(val & 0xf9); - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[2][addr] = val; - break; - - case 0x11: /* Memory Space Base Address Register */ - case 0x12: /* Memory Space Base Address Register */ - case 0x13: /* Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 0x02); - break; - - case 0x14: /* IO Space Base Address Register */ - case 0x15: /* IO Space Base Address Register */ - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - dev->pci_conf_sb[2][addr] = val; - dev->usb_unk_base = (dev->pci_conf_sb[2][0x14] & 0xf8) | - (dev->pci_conf_sb[2][0x15] << 8); - if (dev->usb_unk_base != 0x0000) { - io_sethandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - break; - - case 0x3c: /* Interrupt Line */ - dev->pci_conf_sb[2][addr] = val; - break; - } -} - -static uint8_t -sis_5571_usb_read(int addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - if (dev->pci_conf_sb[0][0x68] & 0x40) { - ret = dev->pci_conf_sb[2][addr]; - - sis_5571_log("SiS 5571 USB: [R] dev->pci_conf_sb[2][%02X] = %02X\n", addr, ret); - } - - return ret; -} - -static void -sis_5571_sb_write(int func, int addr, uint8_t val, void *priv) -{ switch (func) { case 0x00: - sis_5571_pci_to_isa_write(addr, val, priv); + sis_5513_pci_to_isa_write(addr, val, dev->p2i); break; case 0x01: - sis_5571_ide_write(addr, val, priv); + sis_5513_ide_write(addr, val, dev->ide); break; case 0x02: - sis_5571_usb_write(addr, val, priv); + sis_5572_usb_write(addr, val, dev->usb); break; } } static uint8_t -sis_5571_sb_read(int func, int addr, void *priv) +sis_5572_read(int func, int addr, void *priv) { + const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; switch (func) { case 0x00: - ret = sis_5571_pci_to_isa_read(addr, priv); + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); break; case 0x01: - ret = sis_5571_ide_read(addr, priv); + ret = sis_5513_ide_read(addr, dev->ide); break; case 0x02: - ret = sis_5571_usb_read(addr, priv); + ret = sis_5572_usb_read(addr, dev->usb); break; } + sis_5571_log("SiS 5572: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + return ret; } -static void -sis_5571_reset(void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - /* Memory/PCI Bridge */ - sis_5571_mem_to_pci_reset(dev); - - /* PCI to ISA bridge */ - sis_5571_pci_to_isa_reset(dev); - - /* IDE Controller */ - sis_5571_ide_reset(dev); - - /* USB Controller */ - sis_5571_usb_reset(dev); -} - static void sis_5571_close(void *priv) { sis_5571_t *dev = (sis_5571_t *) priv; - smram_del(dev->smram); free(dev); } @@ -1192,44 +153,18 @@ static void * sis_5571_init(UNUSED(const device_t *info)) { sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); - uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - /* Device 0: Memory/PCI Bridge */ - pci_add_card(PCI_ADD_NORTHBRIDGE, - sis_5571_mem_to_pci_read, sis_5571_mem_to_pci_write, dev, &dev->nb_slot); - /* Device 1: Southbridge */ - pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5571_sb_read, sis_5571_sb_write, dev, &dev->sb_slot); + /* Device 0: SiS 5571 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5571_read, sis_5571_write, dev, &dev->nb_slot); + /* Device 1: SiS 5572 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5572_read, sis_5572_write, dev, &dev->sb_slot); - /* MIRQ */ - pci_enable_mirq(1); + dev->sis = device_add(&sis_55xx_common_device); - /* IDEIRQ */ - pci_enable_mirq(2); - - /* USBIRQ */ - pci_enable_mirq(3); - - /* Port 92h */ - dev->port_92 = device_add(&port_92_device); - - /* SFF IDE */ - dev->bm[0] = device_add_inst(&sff8038i_device, 1); - dev->bm[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* PIT */ - dev->pit = device_find_first_priv(DEVICE_PIT); - dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; - - /* NVR */ - dev->nvr = device_add(&at_mb_nvr_device); - - /* USB */ - dev->usb = device_add(&usb_device); - - sis_5571_reset(dev); + dev->h2p = device_add_linked(&sis_5571_h2p_device, dev->sis); + dev->p2i = device_add_linked(&sis_5572_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5572_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5572_usb_device, dev->sis); return dev; } @@ -1241,7 +176,7 @@ const device_t sis_5571_device = { .local = 0, .init = sis_5571_init, .close = sis_5571_close, - .reset = sis_5571_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c new file mode 100644 index 000000000..26c74a3c0 --- /dev/null +++ b/src/chipset/sis_5571_h2p.c @@ -0,0 +1,458 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5571 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5571_HOST_TO_PCI_LOG +int sis_5571_host_to_pci_do_log = ENABLE_SIS_5571_HOST_TO_PCI_LOG; + +static void +sis_5571_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5571_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5571_host_to_pci_t; + +static void +sis_5571_shadow_recalc(sis_5571_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5571_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ + case 0x60 ... 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5571_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5571_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { + smi_raise(); + dev->pci_conf[0x9d] |= 0x01; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99 ... 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0 ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5571_host_to_pci_read(int addr, void *priv) +{ + const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_host_to_pci_reset(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x54; + dev->pci_conf[0x56] = 0x03; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + + /* Undocumented DRAM bank registers. */ + dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; + dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; + dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; + dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; + dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6b] = 0x80; + + dev->pci_conf[0x70] = 0x00; + dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = 0x00; + + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = 0x00; + dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = 0x00; + dev->pci_conf[0x7b] = 0x00; + + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = 0x00; + dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = 0x00; + dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + dev->pci_conf[0x87] = 0x00; + + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x8e] = 0x00; + dev->pci_conf[0x8f] = 0x00; + + dev->pci_conf[0x90] = 0x00; + dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = 0x00; + dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = 0x00; + dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = 0x00; + dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = 0x00; + dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = 0x00; + dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5571_smram_recalc(dev); + sis_5571_shadow_recalc(dev); + + flushmmucache(); +} + +static void +sis_5571_host_to_pci_close(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) calloc(1, sizeof(sis_5571_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5571_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5571_h2p_device = { + .name = "SiS 5571 Host to PCI bridge", + .internal_name = "sis_5571_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5571_host_to_pci_init, + .close = sis_5571_host_to_pci_close, + .reset = sis_5571_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571_old.c b/src/chipset/sis_5571_old.c new file mode 100644 index 000000000..f130ecd8a --- /dev/null +++ b/src/chipset/sis_5571_old.c @@ -0,0 +1,772 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5571 Chipset. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/smram.h> +#include <86box/usb.h> + +#include <86box/chipset.h> + +/* Shadow RAM */ +#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) + +/* IDE Flags (1 Native / 0 Compatibility)*/ +#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) +#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) +#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) +#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) +#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) +#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) +#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + +#ifdef ENABLE_SIS_5571_LOG +int sis_5571_do_log = ENABLE_SIS_5571_LOG; + +static void +sis_5571_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_log(fmt, ...) +#endif + +typedef struct sis_5571_t { + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; + uint8_t usb_irq_state; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[3][256]; + + port_92_t *port_92; + sff8038i_t *ide_drive[2]; + smram_t *smram; + usb_t *usb; +} sis_5571_t; + +static void +sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +{ + if (cur_reg != 0x76) { + mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE); + mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE); + } else + mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); + + flushmmucache_nopc(); +} + +static void +sis_5571_smm_recalc(sis_5571_t *dev) +{ + smram_disable_all(); + + switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) { + case 0x00: + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x01: + smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x02: + smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x03: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_ide_handler(sis_5571_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->pci_conf_sb[1][4] & 1) { + if (dev->pci_conf_sb[1][0x4a] & 4) { + ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); + ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); + ide_pri_enable(); + } + if (dev->pci_conf_sb[1][0x4a] & 2) { + ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); + ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); + ide_sec_enable(); + } + } +} + +void +sis_5571_bm_handler(sis_5571_t *dev) +{ + sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); + sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); +} + +static void +memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + switch (addr) { + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] |= val; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf[addr] &= val; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= val & 0xbe; + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60: /* Undocumented */ + case 0x61: /* Undocumented */ + case 0x62: /* Undocumented */ + case 0x63: /* Undocumented */ + case 0x64: /* Undocumented */ + case 0x65: /* Undocumented */ + case 0x66: /* Undocumented */ + case 0x67: /* Undocumented */ + case 0x68: /* Undocumented */ + case 0x69: /* Undocumented */ + case 0x6a: /* Undocumented */ + case 0x6b: /* Undocumented */ + dev->pci_conf[addr] = val; + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: /* Attribute of shadow RAM for BIOS area */ + dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); + sis_5571_shadow_recalc(addr, dev); + sis_5571_smm_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); + break; + + case 0x84: + case 0x85: + case 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) { + smi_raise(); + dev->pci_conf[0x9d] |= 1; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0: + case 0xa1: + case 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smm_recalc(dev); + break; + + default: + break; + } + sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val); +} + +static uint8_t +memory_pci_bridge_read(UNUSED(int func), int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); + return dev->pci_conf[addr]; +} + +static void +pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + switch (func) { + case 0: /* Bridge */ + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[0][addr] |= val & 0x0f; + break; + + case 0x06: /* Status */ + dev->pci_conf_sb[0][addr] &= val; + break; + + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + case 0x44: /* INTD# Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xec; + switch ((val & 0xc0) >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + break; + + case 0x46: + dev->pci_conf_sb[0][addr] = val & 0xec; + break; + + case 0x47: /* DMA Clock and Wait State Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3e; + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x5f: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x60: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x61: /* MIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val; + pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x0f; + dma_set_drq((val & 0x07), 1); + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + if (val & 0x80) { + sff_set_irq_line(dev->ide_drive[0], val & 0x0f); + sff_set_irq_line(dev->ide_drive[1], val & 0x0f); + } + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x69: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6a: + dev->pci_conf_sb[0][addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0x03; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x70: + dev->pci_conf_sb[0][addr] = val & 0xde; + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xfe; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf_sb[0][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 1: /* IDE Controller */ + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf_sb[1][addr] = val & 0x05; + sis_5571_ide_handler(dev); + sis_5571_bm_handler(dev); + break; + + case 0x07: /* Status high byte */ + dev->pci_conf_sb[1][addr] &= val; + break; + + case 0x09: /* Programming Interface Byte */ + dev->pci_conf_sb[1][addr] = val & 0xcf; + sis_5571_ide_handler(dev); + break; + + case 0x0d: /* Latency Time */ + case 0x10: /* Primary Channel Base Address Register */ + case 0x11: /* Primary Channel Base Address Register */ + case 0x12: /* Primary Channel Base Address Register */ + case 0x13: /* Primary Channel Base Address Register */ + case 0x14: /* Primary Channel Base Address Register */ + case 0x15: /* Primary Channel Base Address Register */ + case 0x16: /* Primary Channel Base Address Register */ + case 0x17: /* Primary Channel Base Address Register */ + case 0x18: /* Secondary Channel Base Address Register */ + case 0x19: /* Secondary Channel Base Address Register */ + case 0x1a: /* Secondary Channel Base Address Register */ + case 0x1b: /* Secondary Channel Base Address Register */ + case 0x1c: /* Secondary Channel Base Address Register */ + case 0x1d: /* Secondary Channel Base Address Register */ + case 0x1e: /* Secondary Channel Base Address Register */ + case 0x1f: /* Secondary Channel Base Address Register */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_ide_handler(dev); + break; + + case 0x20: /* Bus Master IDE Control Register Base Address */ + case 0x21: /* Bus Master IDE Control Register Base Address */ + case 0x22: /* Bus Master IDE Control Register Base Address */ + case 0x23: /* Bus Master IDE Control Register Base Address */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_bm_handler(dev); + break; + + case 0x30: /* Expansion ROM Base Address */ + case 0x31: /* Expansion ROM Base Address */ + case 0x32: /* Expansion ROM Base Address */ + case 0x33: /* Expansion ROM Base Address */ + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x4a: /* IDE General Control Register 0 */ + dev->pci_conf_sb[1][addr] = val & 0xaf; + sis_5571_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control register 1 */ + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf_sb[1][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 2: /* USB Controller */ + switch (addr) { + case 0x04: /* Command - Low Byte */ + dev->pci_conf_sb[2][addr] = val; + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf_sb[2][addr] = val & 0x03; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf_sb[2][addr] &= val & 0xc0; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf_sb[2][addr] &= val; + break; + + case 0x10: /* Memory Space Base Address Register */ + case 0x11: /* Memory Space Base Address Register */ + case 0x12: /* Memory Space Base Address Register */ + case 0x13: /* Memory Space Base Address Register */ + dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x14: /* IO Space Base Address Register */ + case 0x15: /* IO Space Base Address Register */ + case 0x16: /* IO Space Base Address Register */ + case 0x17: /* IO Space Base Address Register */ + case 0x3c: /* Interrupt Line */ + dev->pci_conf_sb[2][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + default: + break; + } +} + +static uint8_t +pci_isa_bridge_read(int func, int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + switch (func) { + case 0: + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); + return dev->pci_conf_sb[0][addr]; + case 1: + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); + return dev->pci_conf_sb[1][addr]; + case 2: + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); + return dev->pci_conf_sb[2][addr]; + + default: + return 0xff; + } +} + +static void +sis_5571_reset(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + /* Memory/PCI Bridge */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0xfd; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa2] = 0xff; + + /* PCI to ISA bridge */ + dev->pci_conf_sb[0][0x00] = 0x39; + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x04] = 0xfd; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + + /* IDE Controller */ + dev->pci_conf_sb[1][0x00] = 0x39; + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x0a] = 0x01; + dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x4a] = 0x06; + sff_set_slot(dev->ide_drive[0], dev->sb_slot); + sff_set_slot(dev->ide_drive[1], dev->sb_slot); + sff_bus_master_reset(dev->ide_drive[0]); + sff_bus_master_reset(dev->ide_drive[1]); + + /* USB Controller */ + dev->pci_conf_sb[2][0x00] = 0x39; + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 0x01; + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x08] = 0xb0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 0x03; + dev->pci_conf_sb[2][0x0b] = 0xc0; + dev->pci_conf_sb[2][0x0e] = 0x80; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x3d] = 0x01; +} + +static void +sis_5571_close(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_init(UNUSED(const device_t *info)) +{ + sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); + memset(dev, 0x00, sizeof(sis_5571_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot); + pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot); + + /* MIRQ */ + pci_enable_mirq(0); + + /* Port 92 & SMRAM */ + dev->port_92 = device_add(&port_92_pci_device); + dev->smram = smram_add(); + + /* SFF IDE */ + dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); + dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5571_reset(dev); + + return dev; +} + +const device_t sis_5571_device = { + .name = "SiS 5571", + .internal_name = "sis_5571", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5571_init, + .close = sis_5571_close, + .reset = sis_5571_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5572_usb.c b/src/chipset/sis_5572_usb.c new file mode 100644 index 000000000..250c32587 --- /dev/null +++ b/src/chipset/sis_5572_usb.c @@ -0,0 +1,323 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5572_USB_LOG +int sis_5572_usb_do_log = ENABLE_SIS_5572_USB_LOG; + +static void +sis_5572_usb_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5572_usb_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5572_usb_log(fmt, ...) +#endif + +typedef struct sis_5572_usb_t { + uint8_t rev; + + uint8_t usb_unk_regs[256]; + uint8_t pci_conf[256]; + + uint16_t usb_unk_base; + + usb_t *usb; + + sis_55xx_common_t *sis; +} sis_5572_usb_t; + +/* SiS 5572 unknown I/O port (second USB PCI BAR). */ +static void +sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + addr = (addr - dev->usb_unk_base) & 0x07; + + sis_5572_usb_log("SiS 5572 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); + + dev->usb_unk_regs[addr] = val; +} + +static uint8_t +sis_5572_usb_unk_read(uint16_t addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->usb_unk_base) & 0x07; + + ret = dev->usb_unk_regs[addr & 0x07]; + + sis_5572_usb_log("SiS 5572 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); + + return ret; +} + +void +sis_5572_usb_write(int addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + sis_5572_usb_log("SiS 5572 USB: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + if (dev->rev == 0xb0) + dev->pci_conf[addr] = val & 0x47; + else + dev->pci_conf[addr] = val & 0x57; + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + if (dev->pci_conf[0x04] & 0x01) + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + case 0x11 ... 0x13: /* Memory Space Base Address Register */ + dev->pci_conf[addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[4] & 0x02); + break; + + case 0x14 ... 0x15: /* IO Space Base Address Register */ + if (dev->rev == 0xb0) { + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + dev->pci_conf[addr] = val; + dev->usb_unk_base = (dev->pci_conf[0x14] & 0xf8) | + (dev->pci_conf[0x15] << 8); + if (dev->usb_unk_base != 0x0000) { + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + } + break; + + case 0x2c ... 0x2f: + if (dev->rev == 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x3c: /* Interrupt Line */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5572_usb_read(int addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + if (dev->sis->usb_enabled) { + ret = dev->pci_conf[addr]; + + sis_5572_usb_log("SiS 5572 USB: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5572_usb_reset(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x01; + dev->pci_conf[0x03] = 0x70; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = (dev->rev == 0xb0) ? 0x00 : 0x80; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x10; + dev->pci_conf[0x0a] = 0x03; + dev->pci_conf[0x0b] = 0x0c; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0x00; + dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = 0x00; + dev->pci_conf[0x13] = 0x00; + if (dev->rev == 0xb0) { + dev->pci_conf[0x14] = 0x01; + dev->pci_conf[0x15] = 0x00; + dev->pci_conf[0x16] = 0x00; + dev->pci_conf[0x17] = 0x00; + } else if (dev->rev == 0x11) { + dev->pci_conf[0x2c] = 0x00; + dev->pci_conf[0x2d] = 0x00; + dev->pci_conf[0x2e] = 0x00; + dev->pci_conf[0x2f] = 0x00; + } + dev->pci_conf[0x3c] = 0x00; + dev->pci_conf[0x3d] = PCI_INTA; + dev->pci_conf[0x3e] = 0x00; + dev->pci_conf[0x3f] = 0x00; + + if (dev->rev == 0xb0) { + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + + dev->usb_unk_base = 0x0000; + + memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); + } +} + +static void +sis_5572_usb_close(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + free(dev); +} + +static void * +sis_5572_usb_init(UNUSED(const device_t *info)) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) calloc(1, sizeof(sis_5572_usb_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5572_usb_reset(dev); + + return dev; +} + +const device_t sis_5572_usb_device = { + .name = "SiS 5572 USB controller", + .internal_name = "sis_5572_usb", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_usb_device = { + .name = "SiS 5582 USB controller", + .internal_name = "sis_5582_usb", + .flags = DEVICE_PCI, + .local = 0xe0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_usb_device = { + .name = "SiS 5595 USB controller", + .internal_name = "sis_5595_usb", + .flags = DEVICE_PCI, + .local = 0x11, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c new file mode 100644 index 000000000..98b37897c --- /dev/null +++ b/src/chipset/sis_5581.c @@ -0,0 +1,185 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5581/5582 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#define ENABLE_SIS_5581_LOG 1 +#ifdef ENABLE_SIS_5581_LOG +int sis_5581_do_log = ENABLE_SIS_5581_LOG; + +static void +sis_5581_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_log(fmt, ...) +#endif + +typedef struct sis_5581_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + + sis_55xx_common_t *sis; +} sis_5581_t; + +static void +sis_5581_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5581: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5581_host_to_pci_write(addr, val, dev->h2p); +} + +static uint8_t +sis_5581_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5581_host_to_pci_read(addr, dev->h2p); + + sis_5581_log("SiS 5581: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5582_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5582: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5513_ide_write(addr, val, dev->ide); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5582_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5513_ide_read(addr, dev->ide); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5581_log("SiS 5582: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_close(void *priv) +{ + sis_5581_t *dev = (sis_5581_t *) priv; + + free(dev); +} + +static void * +sis_5581_init(UNUSED(const device_t *info)) +{ + sis_5581_t *dev = (sis_5581_t *) calloc(1, sizeof(sis_5581_t)); + + /* Device 0: SiS 5581 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5581_read, sis_5581_write, dev, &dev->nb_slot); + /* Device 1: SiS 5582 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5582_read, sis_5582_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->p2i = device_add_linked(&sis_5582_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5581_h2p_device, dev->sis); + dev->ide = device_add_linked(&sis_5582_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5582_usb_device, dev->sis); + + return dev; +} + +const device_t sis_5581_device = { + .name = "SiS 5581", + .internal_name = "sis_5581", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5581_init, + .close = sis_5581_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c new file mode 100644 index 000000000..48d61f25e --- /dev/null +++ b/src/chipset/sis_5581_h2p.c @@ -0,0 +1,553 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5581 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5581_HOST_TO_PCI_LOG +int sis_5581_host_to_pci_do_log = ENABLE_SIS_5581_HOST_TO_PCI_LOG; + +static void +sis_5581_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5581_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5581_io_trap_t; + +typedef struct sis_5581_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_5581_io_trap_t io_traps[10]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5581_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5581_shadow_recalc(sis_5581_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5581_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5581_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5582_pmu_event(dev->sis->acpi); +} + +static void +sis_5581_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5581_trap_io(size, addr, write, val, priv); +} + +static void +sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5581_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x08) + trap->trap = io_trap_add(sis_5581_trap_io_mask, trap); + else + trap->trap = io_trap_add(sis_5581_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5581_trap_update(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + on = fregs[0x9a]; + + temp = ((fregs[0x96] & 0x02) | (fregs[0x97] << 2)) & 0x03ff; + mask = ~((1 << ((fregs[0x96] >> 3) & 0x07)) - 1); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x08, mask, &(fregs[0x9c]), 0x40, temp, 0x80); + + temp = fregs[0x98] | (fregs[0x99] << 8); + mask = 0xff; + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x08, mask, &(fregs[0x9c]), 0x20, temp, 0x80); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x378, 0x08); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x278, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9c]), 0x08, 0x3f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x9c]), 0x04, 0x2f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x9c]), 0x02, 0x1f0, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x00, 0xff, &(fregs[0x9c]), 0x01, 0x170, 0x08); + + on = fregs[0x9b]; + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x064, 0x01); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x060, 0x01); +} + +static void +sis_5581_smram_recalc(sis_5581_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0xa3] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfc) | (val & 0x03); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x54: + case 0x56 ... 0x57: + case 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xeb; + break; + + case 0x53: + case 0x55: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x58: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5581_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5581_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xde; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + case 0x88 ... 0x8b: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x8c ... 0x92: + case 0x9e ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0x93: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x9d] |= 0x01; + if (dev->pci_conf[0x9b] & 0x01) + acpi_sis5582_pmu_event(dev->sis->acpi); + } + break; + + case 0x94: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x96: + dev->pci_conf[addr] = val & 0xfb; + sis_5581_trap_update(dev); + break; + case 0x97 ... 0x9b: + dev->pci_conf[addr] = val; + sis_5581_trap_update(dev); + break; + + case 0x9c ... 0x9d: + dev->pci_conf[addr] &= ~val; + break; + + case 0xa3: + dev->pci_conf[addr] = val; + sis_5581_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5581_host_to_pci_read(int addr, void *priv) +{ + const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_host_to_pci_reset(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x97; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x38; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x80; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5581_shadow_recalc(dev); + + sis_5581_trap_update(dev); + + sis_5581_smram_recalc(dev); +} + +static void +sis_5581_host_to_pci_close(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5581_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) calloc(1, sizeof(sis_5581_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5581_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5581_h2p_device = { + .name = "SiS 5581 Host to PCI bridge", + .internal_name = "sis_5581_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5581_host_to_pci_init, + .close = sis_5581_host_to_pci_close, + .reset = sis_5581_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c new file mode 100644 index 000000000..969fcb8dd --- /dev/null +++ b/src/chipset/sis_5591.c @@ -0,0 +1,210 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5591/5592 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5591_LOG +int sis_5591_do_log = ENABLE_SIS_5591_LOG; + +static void +sis_5591_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_log(fmt, ...) +#endif + +typedef struct sis_5591_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5591_t; + +static void +sis_5591_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5591: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5591_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5591_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5591_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5591_log("SiS 5591: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5591_log("SiS 5592: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_close(void *priv) +{ + sis_5591_t *dev = (sis_5591_t *) priv; + + free(dev); +} + +static void * +sis_5591_init(UNUSED(const device_t *info)) +{ + sis_5591_t *dev = (sis_5591_t *) calloc(1, sizeof(sis_5591_t)); + + /* Device 0: SiS 5591 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5591_read, sis_5591_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5591_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5591_1997_device = { + .name = "SiS 5591 (1997)", + .internal_name = "sis_5591_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_device = { + .name = "SiS 5591", + .internal_name = "sis_5591", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591_h2p.c b/src/chipset/sis_5591_h2p.c new file mode 100644 index 000000000..8fcbeeb6f --- /dev/null +++ b/src/chipset/sis_5591_h2p.c @@ -0,0 +1,493 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5591 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5591_HOST_TO_PCI_LOG +int sis_5591_host_to_pci_do_log = ENABLE_SIS_5591_HOST_TO_PCI_LOG; + +static void +sis_5591_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5591_host_to_pci_t { + uint8_t pci_conf[256]; + + uint8_t states[7]; + uint8_t states_bus[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5591_host_to_pci_t; + +static uint8_t bank_codes[6] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a }; + +static uint32_t bank_sizes[6] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000 }; /* 256 MB */ + +static void +sis_5591_shadow_recalc(sis_5591_host_to_pci_t *dev) +{ + uint32_t base; + uint32_t state; + uint8_t val; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states[i & 0x0f] = val; + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x5f; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states_bus[i & 0x0f] = val; + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0xf0) | (val & 0x0f); + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x55; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states_bus[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0xf0) | (val & 0x0f); + } + } + } + + flushmmucache_nopc(); +} + +static void +sis_5591_smram_recalc(sis_5591_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5591_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf0); + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x80); + cpu_update_waitstates(); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x68: + dev->pci_conf[addr] = val; + sis_5591_smram_recalc(dev); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5591_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5591_shadow_recalc(dev); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x52: + case 0x54 ... 0x5a: + case 0x5c ... 0x5f: + case 0x64 ... 0x65: + case 0x69 ... 0x6c: + case 0x77 ... 0x7b: + case 0x80 ... 0x8d: + case 0x90: + case 0x97 ... 0xab: + case 0xb0: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xda: + case 0xe0 ... 0xe3: + case 0xef: + dev->pci_conf[addr] = val; + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0xb2: + dev->pci_conf[addr] &= ~(val & 0x01); + break; + } +} + +uint8_t +sis_5591_host_to_pci_read(int addr, void *priv) +{ + const sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_host_to_pci_reset(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x18; + dev->pci_conf[0x52] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x0e; + dev->pci_conf[0x56] = 0x40; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x50; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0x00; + dev->pci_conf[0xa0] = dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = dev->pci_conf[0xa3] = 0x00; + dev->pci_conf[0xa4] = dev->pci_conf[0xa5] = 0x00; + dev->pci_conf[0xa6] = dev->pci_conf[0xa7] = 0x00; + dev->pci_conf[0xa8] = dev->pci_conf[0xa9] = 0x00; + dev->pci_conf[0xaa] = dev->pci_conf[0xab] = 0x00; + dev->pci_conf[0xb0] = dev->pci_conf[0xb2] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xd9] = 0x00; + dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = dev->pci_conf[0xe1] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + dev->pci_conf[0xef] = 0x00; + + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5591_shadow_recalc(dev); + + sis_5591_smram_recalc(dev); +} + +static void +sis_5591_host_to_pci_close(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5591_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) calloc(1, sizeof(sis_5591_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 5; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5591_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5591_h2p_device = { + .name = "SiS 5591 Host to PCI bridge", + .internal_name = "sis_5591_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5591_host_to_pci_init, + .close = sis_5591_host_to_pci_close, + .reset = sis_5591_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c new file mode 100644 index 000000000..4c6dbf7c9 --- /dev/null +++ b/src/chipset/sis_5595_pmu.c @@ -0,0 +1,455 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5595_PMU_LOG +int sis_5595_pmu_do_log = ENABLE_SIS_5595_PMU_LOG; + +static void +sis_5595_pmu_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5595_pmu_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5595_pmu_log(fmt, ...) +#endif + +typedef struct sis_5595_pmu_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5595_pmu_io_trap_t; + +typedef struct sis_5595_pmu_t { + uint8_t is_1997; + + uint8_t pci_conf[256]; + + sis_5595_pmu_io_trap_t io_traps[22]; + + sis_55xx_common_t *sis; +} sis_5595_pmu_t; + +static void +sis_5595_pmu_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5595_pmu_event(dev->sis->acpi); + + if (trap->sts_reg[0x20] & trap->sts_mask) + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->flags & 0x03]->selected) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_ide_bm(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + if (trap->flags & 0x01) { + dev->pci_conf[0x67] |= 0x01; + dev->pci_conf[0x64] |= 0x08; + } else { + dev->pci_conf[0x67] |= 0x02; + dev->pci_conf[0x64] |= 0x10; + } + acpi_sis5595_pmu_event(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x10) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide_bm, trap); + else if (flags & 0x08) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_mask, trap); + else if (flags & 0x04) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide, trap); + else + trap->trap = io_trap_add(sis_5595_pmu_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5595_pmu_trap_update(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + temp = (fregs[0x7e] | (fregs[0x7f] << 8)) & 0xffe0; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x08, 0x10, 0xff, NULL, 0xff, temp, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x04, 0x10, 0xff, NULL, 0xff, temp + 8, 0x08); + + on = fregs[0x63] | fregs[0x83]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x04, 0xff, &(fregs[0x63]), 0x02, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x06, 0xff, &(fregs[0x63]), 0x01, 0x170, 0x08); + + on = fregs[0x62] | fregs[0x82]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x064, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x060, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x62]), 0x40, 0x3f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x62]), 0x20, 0x2f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x378, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x278, 0x08); + + temp = (fregs[0x5c] | (fregs[0x5d] << 8)) & 0x03ff; + mask = fregs[0x5d] >> 2; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x08, mask, &(fregs[0x62]), 0x04, temp, 0x40); + + temp = fregs[0x5e] | (fregs[0x5f] << 8); + + if (dev->is_1997) { + mask = fregs[0x4d] & 0x1f; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x20); + } else { + mask = fregs[0x4d]; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x100); + } + + on = fregs[0x61] | fregs[0x81]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x61]), 0x40, 0x3b0, 0x30); + + switch ((fregs[0x4c] >> 6) & 0x03) { + case 0x00: + temp = 0xf40; + break; + case 0x01: + temp = 0xe80; + break; + case 0x02: + temp = 0x604; + break; + default: + temp = 0x530; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x61]), 0x10, temp, 0x08); + + switch ((fregs[0x4c] >> 4) & 0x03) { + case 0x00: + temp = 0x280; + break; + case 0x01: + temp = 0x260; + break; + case 0x02: + temp = 0x240; + break; + default: + temp = 0x220; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x61]), 0x08, temp, 0x14); + + switch ((fregs[0x4c] >> 2) & 0x03) { + case 0x00: + temp = 0x330; + break; + case 0x01: + temp = 0x320; + break; + case 0x02: + temp = 0x310; + break; + default: + temp = 0x300; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x61]), 0x04, temp, 0x04); + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x200, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x388, 0x04); + + on = fregs[0x60] | fregs[0x80]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x3f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x370, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x05, 0xff, &(fregs[0x60]), 0x10, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x07, 0xff, &(fregs[0x60]), 0x08, 0x170, 0x08); +} + +void +sis_5595_pmu_write(int addr, uint8_t val, void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + sis_5595_pmu_log("SiS 5595 PMU: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x40 ... 0x4b: + case 0x50 ... 0x5b: + case 0x68 ... 0x7b: + case 0x7d: + dev->pci_conf[addr] = val; + break; + case 0x4c ... 0x4d: + case 0x5c ... 0x63: + case 0x7e ... 0x7f: + case 0x80 ... 0x83: + dev->pci_conf[addr] = val; + sis_5595_pmu_trap_update(dev); + break; + case 0x64 ... 0x67: + dev->pci_conf[addr] &= ~val; + break; + case 0x7c: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x64] |= 0x04; + if (dev->pci_conf[0x60] & 0x04) + acpi_sis5595_pmu_event(dev->sis->acpi); + } + break; + } +} + +uint8_t +sis_5595_pmu_read(int addr, void *priv) +{ + const sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5595_pmu_log("SiS 5595 PMU: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_pmu_reset(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x09; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0xff; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = dev->pci_conf[0x5b] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = dev->pci_conf[0x63] = 0x00; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + + sis_5595_pmu_trap_update(dev); + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_close(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + free(dev); +} + +static void * +sis_5595_pmu_init(UNUSED(const device_t *info)) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) calloc(1, sizeof(sis_5595_pmu_t)); + + dev->sis = device_get_common_priv(); + dev->sis->pmu_regs = dev->pci_conf; + + dev->is_1997 = info->local; + + sis_5595_pmu_reset(dev); + + return dev; +} + +const device_t sis_5595_1997_pmu_device = { + .name = "SiS 5595 (1997) PMU", + .internal_name = "sis_5595_1997_pmu", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_pmu_device = { + .name = "SiS 5595 PMU", + .internal_name = "sis_5595_pmu", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_55xx.c b/src/chipset/sis_55xx.c new file mode 100644 index 000000000..2cad21f22 --- /dev/null +++ b/src/chipset/sis_55xx.c @@ -0,0 +1,96 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 55xx common structure. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_55XX_COMMON_LOG +int sis_55xx_common_do_log = ENABLE_SIS_55XX_COMMON_LOG; + +static void +sis_55xx_common_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_55xx_common_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_55xx_common_log(fmt, ...) +#endif + +static void +sis_55xx_common_close(void *priv) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) priv; + + free(dev); +} + +static void * +sis_55xx_common_init(UNUSED(const device_t *info)) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) calloc(1, sizeof(sis_55xx_common_t)); + + return dev; +} + +const device_t sis_55xx_common_device = { + .name = "SiS 55xx Common Structure", + .internal_name = "sis_55xx_common", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_55xx_common_init, + .close = sis_55xx_common_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c new file mode 100644 index 000000000..ed7384740 --- /dev/null +++ b/src/chipset/sis_5600.c @@ -0,0 +1,210 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS (5)600 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5600_LOG +int sis_5600_do_log = ENABLE_SIS_5600_LOG; + +static void +sis_5600_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_log(fmt, ...) +#endif + +typedef struct sis_5600_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5600_t; + +static void +sis_5600_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5600: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5600_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5600_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5600_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5600_log("SiS 5600: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5600_log("SiS 5602: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_close(void *priv) +{ + sis_5600_t *dev = (sis_5600_t *) priv; + + free(dev); +} + +static void * +sis_5600_init(UNUSED(const device_t *info)) +{ + sis_5600_t *dev = (sis_5600_t *) calloc(1, sizeof(sis_5600_t)); + + /* Device 0: SiS 5600 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5600_read, sis_5600_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5600_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5600_1997_device = { + .name = "SiS (5)600 (1997)", + .internal_name = "sis_5600_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5600_device = { + .name = "SiS (5)600", + .internal_name = "sis_5600", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600_h2p.c b/src/chipset/sis_5600_h2p.c new file mode 100644 index 000000000..f6ee926da --- /dev/null +++ b/src/chipset/sis_5600_h2p.c @@ -0,0 +1,434 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS (5)600 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5600_HOST_TO_PCI_LOG +int sis_5600_host_to_pci_do_log = ENABLE_SIS_5600_HOST_TO_PCI_LOG; + +static void +sis_5600_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5600_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5600_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5600_shadow_recalc(sis_5600_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0; i < 8; i++) { + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x70] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x72] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x70] ^ dev->states[0]) & (1 << i)) || + ((dev->pci_conf[0x72] ^ dev->states[2]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + for (uint8_t i = 0; i < 4; i++) { + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x71] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << i)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + base = 0x000f0000; + state = (dev->pci_conf[0x71] & (1 << 4)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << 4)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << 4)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << 4))) { + mem_set_mem_state_both(base, 0x10000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0xffff); + } + + for (uint8_t i = 0; i < 4; i++) + dev->states[i] = dev->pci_conf[0x70 + i]; + + flushmmucache_nopc(); +} + +static void +sis_5600_smram_recalc(sis_5600_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x6a] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x6a] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5600_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & ~(val & 0x70)) | (val & 0x01); + break; + + case 0x0d: /* Master latency timer */ + case 0x50 ... 0x5a: + case 0x64 ... 0x69: + case 0x6b ... 0x6c: + case 0x74 ... 0x75: + case 0x77 ... 0x80: + case 0x82 ... 0x8f: + case 0x97 ... 0x9b: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xd8: + case 0xda: + case 0xe0: + case 0xe2 ... 0xe3: + dev->pci_conf[addr] = val; + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x6a: + dev->pci_conf[addr] = val; + sis_5600_smram_recalc(dev); + break; + + case 0x70 ... 0x73: + dev->pci_conf[addr] = val; + sis_5600_shadow_recalc(dev); + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + } +} + +uint8_t +sis_5600_host_to_pci_read(int addr, void *priv) +{ + const sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_host_to_pci_reset(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x00; + dev->pci_conf[0x03] = 0x56; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x10; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x02; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x62; + dev->pci_conf[0x8e] = dev->pci_conf[0x8f] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + + sis_5600_shadow_recalc(dev); + + sis_5600_smram_recalc(dev); +} + +static void +sis_5600_host_to_pci_close(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5600_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) calloc(1, sizeof(sis_5600_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5600_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5600_h2p_device = { + .name = "SiS (5)600 Host to PCI bridge", + .internal_name = "sis_5600_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5600_host_to_pci_init, + .close = sis_5600_host_to_pci_close, + .reset = sis_5600_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 7f4aebb7c..8ec0498ff 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -6,15 +6,13 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 85C50x Chipset. + * Implementation of the SiS 85C50x and 550x Chipsets. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * Miran Grca, - * - * Copyright 2020-2021 Tiseno100. - * Copyright 2020-2021 Miran Grca. + * Copyright 2020-2024 Miran Grca. + * Copyright 2020-2024 Tiseno100. */ #include #include @@ -27,16 +25,20 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/apm.h> #include <86box/machine.h> #include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> #include <86box/plat_unused.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/smram.h> #include <86box/pci.h> #include <86box/port_92.h> - +#include <86box/spd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -58,17 +60,23 @@ sis_85c50x_log(const char *fmt, ...) #endif typedef struct sis_85c50x_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t type; - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[256]; - uint8_t regs[256]; + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[256]; + uint8_t pci_conf_ide[256]; + uint8_t regs[256]; + uint32_t states[13]; smram_t *smram[2]; port_92_t *port_92; + void *pit; + nvr_t *nvr; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_85c50x_t; static void @@ -77,23 +85,59 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev) uint32_t base; uint32_t can_read; uint32_t can_write; + uint32_t state; can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; - if (!can_read) - can_write = MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); - shadowbios = 1; - shadowbios_write = 1; + state = can_read | can_write; + if (dev->states[12] != state) { + mem_set_mem_state_both(0x000f0000, 0x00010000, state); + sis_85c50x_log("F0000-FFFFF: R%c, W%c\n", + (dev->pci_conf[0x53] & 0x40) ? 'I' : 'E', + (dev->pci_conf[0x53] & 0x20) ? 'P' : 'I'); + dev->states[12] = state; + } for (uint8_t i = 0; i < 4; i++) { - base = 0xe0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xd0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xc0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x54] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[8 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x543 & (0x80 >> i)) ? + ((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x54] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[8 + i] = state; + } + + base = 0x000d0000 + (i << 14); + state = (dev->pci_conf[0x55] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[4 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[4 + i] = state; + } + + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x56] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[i] = state; + } } flushmmucache_nopc(); @@ -117,27 +161,35 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) break; case 0x01: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x02: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x04: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x06: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; default: break; @@ -160,7 +212,10 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06); break; case 0x50: - dev->pci_conf[addr] = val; + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xf7; + else + dev->pci_conf[addr] = val; break; case 0x51: /* Cache */ dev->pci_conf[addr] = val; @@ -176,8 +231,6 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) case 0x56: dev->pci_conf[addr] = val; sis_85c50x_shadow_recalc(dev); - if (addr == 0x54) - sis_85c50x_smm_recalc(dev); break; case 0x57: case 0x58: @@ -223,6 +276,31 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) case 0x69: dev->pci_conf[addr] &= ~val; break; + case 0x70 ... 0x77: + if (dev->type & 1) + spd_write_drbs(dev->pci_conf, 0x70, 0x77, 2); + break; + case 0x78: + case 0x7c ... 0x7e: + if (dev->type & 1) + dev->pci_conf[addr] = val; + break; + case 0x79: + if (dev->type & 1) { + spd_write_drbs(dev->pci_conf, 0xf8, 0xff, 4); + dev->pci_conf[addr] = 0x00; + for (uint8_t i = 0; i < 8; i++) + if (dev->pci_conf[0xf8 + i] & 0x80) dev->pci_conf[addr] |= (1 << i); + } + break; + case 0x7a: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xfe; + break; + case 0x7b: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xe0; + break; default: break; @@ -235,14 +313,33 @@ sis_85c50x_read(int func, int addr, void *priv) const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) - ret = dev->pci_conf[addr]; + if (func == 0x00) { + if (addr >= 0xf8) + ret = 0x00; + else + ret = dev->pci_conf[addr]; + } sis_85c50x_log("85C501: [R] (%02X, %02X) = %02X\n", func, addr, ret); return ret; } +static void +sis_85c50x_ide_recalc(sis_85c50x_t *dev) +{ + ide_pri_disable(); + ide_set_base(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0170 : 0x01f0); + ide_set_side(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0376 : 0x03f6); + ide_pri_enable(); + + ide_sec_disable(); + ide_set_base(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x01f0 : 0x0170); + ide_set_side(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x03f6 : 0x0376); + if (dev->pci_conf_ide[0x41] & 0x01) + ide_sec_enable(); +} + static void sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) { @@ -250,38 +347,46 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, val); - if (func == 0x00) - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[addr] = val & 0x0f; - break; - case 0x07: /* Status */ - dev->pci_conf_sb[addr] &= ~(val & 0x30); - break; - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[addr] = val & 0x3f; - break; - case 0x41: - case 0x42: - case 0x43: - case 0x44: - /* INTA/B/C/D# Remapping Control Register */ - dev->pci_conf_sb[addr] = val & 0x8f; - if (val & 0x80) - pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); - break; - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[addr] = val; - break; + if (func == 0x00) switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[addr] = val & 0x0f; + break; + case 0x07: /* Status */ + dev->pci_conf_sb[addr] &= ~(val & 0x30); + break; + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[addr] = val & 0x3f; + break; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + /* INTA/B/C/D# Remapping Control Register */ + dev->pci_conf_sb[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); + break; + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[addr] = val; + break; - default: - break; - } + default: + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) switch (addr) { + case 0x40: + case 0x41: + dev->pci_conf_ide[addr] = val; + sis_85c50x_ide_recalc(dev); + break; + + default: + break; + } } static uint8_t @@ -290,8 +395,42 @@ sis_85c50x_sb_read(int func, int addr, void *priv) const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) - ret = dev->pci_conf_sb[addr]; + if (func == 0x00) switch (addr) { + default: + ret = dev->pci_conf_sb[addr]; + break; + case 0x4c ... 0x4f: + if (dev->type & 2) + ret = pic_read_icw(0, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x50 ... 0x53: + if (dev->type & 2) + ret = pic_read_icw(1, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x54 ... 0x55: + if (dev->type & 2) + ret = pic_read_ocw(0, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x56 ... 0x57: + if (dev->type & 2) + ret = pic_read_ocw(1, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x58 ... 0x5f: + if (dev->type & 2) + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + else + ret = dev->pci_conf_sb[addr]; + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) + ret = dev->pci_conf_ide[addr]; sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, ret); @@ -313,10 +452,39 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) case 0x23: switch (dev->index) { case 0x80: - dev->regs[dev->index] = val & 0xe7; + if (dev->type & 2) { + dev->regs[dev->index] = val; + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + } else + dev->regs[dev->index] = val & 0xe7; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } break; case 0x81: - dev->regs[dev->index] = val & 0xf4; + if (dev->type & 2) + dev->regs[dev->index] = val & 0xf6; + else + dev->regs[dev->index] = val & 0xf4; + break; + case 0x82: + if (dev->type & 2) + dev->regs[dev->index] = val; + break; + case 0x83: + if (dev->type & 2) + dev->regs[dev->index] = val & 0x03; break; case 0x84: case 0x88: @@ -394,6 +562,12 @@ sis_85c50x_reset(void *priv) sis_85c50x_write(0, 0x68, 0x00, dev); sis_85c50x_write(0, 0x69, 0xff, dev); + if (dev->type & 1) { + for (uint8_t i = 0; i < 8; i++) + dev->pci_conf[0x70 + i] = 0x00; + dev->pci_conf[0x79] = 0x00; + } + /* South Bridge (SiS 85C503) */ dev->pci_conf_sb[0x00] = 0x39; dev->pci_conf_sb[0x01] = 0x10; @@ -407,10 +581,51 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x09] = 0x00; dev->pci_conf_sb[0x0a] = 0x01; dev->pci_conf_sb[0x0b] = 0x06; + if (dev->type & 2) + dev->pci_conf_sb[0x0e] = 0x80; sis_85c50x_sb_write(0, 0x41, 0x80, dev); sis_85c50x_sb_write(0, 0x42, 0x80, dev); sis_85c50x_sb_write(0, 0x43, 0x80, dev); sis_85c50x_sb_write(0, 0x44, 0x80, dev); + + if (dev->type & 2) { + /* IDE (SiS 5503) */ + dev->pci_conf_ide[0x00] = 0x39; + dev->pci_conf_ide[0x01] = 0x10; + dev->pci_conf_ide[0x02] = 0x01; + dev->pci_conf_ide[0x03] = 0x06; + dev->pci_conf_ide[0x04] = 0x89; + dev->pci_conf_ide[0x05] = 0x00; + dev->pci_conf_ide[0x06] = 0x00; + dev->pci_conf_ide[0x07] = 0x00; + dev->pci_conf_ide[0x08] = 0x00; + dev->pci_conf_ide[0x09] = 0x00; + dev->pci_conf_ide[0x0a] = 0x01; + dev->pci_conf_ide[0x0b] = 0x01; + dev->pci_conf_ide[0x0c] = 0x00; + dev->pci_conf_ide[0x0d] = 0x00; + dev->pci_conf_ide[0x0e] = 0x80; + dev->pci_conf_ide[0x0f] = 0x00; + dev->pci_conf_ide[0x10] = 0x71; + dev->pci_conf_ide[0x11] = 0x01; + dev->pci_conf_ide[0x14] = 0xf1; + dev->pci_conf_ide[0x15] = 0x01; + dev->pci_conf_ide[0x18] = 0x71; + dev->pci_conf_ide[0x19] = 0x03; + dev->pci_conf_ide[0x1c] = 0xf1; + dev->pci_conf_ide[0x1d] = 0x03; + dev->pci_conf_ide[0x20] = 0x01; + dev->pci_conf_ide[0x24] = 0x01; + dev->pci_conf_ide[0x40] = 0x00; + dev->pci_conf_ide[0x41] = 0x40; + + sis_85c50x_ide_recalc(dev); + } + + cpu_set_isa_speed(7159091); + + if (dev->type & 2) + nvr_bank_set(0, 0, dev->nvr); } static void @@ -426,8 +641,10 @@ sis_85c50x_close(void *priv) static void * sis_85c50x_init(UNUSED(const device_t *info)) { - sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t)); - memset(dev, 0x00, sizeof(sis_85c50x_t)); + sis_85c50x_t *dev = (sis_85c50x_t *) calloc(1, sizeof(sis_85c50x_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->type = info->local; /* 501/502 (Northbridge) */ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot); @@ -441,6 +658,17 @@ sis_85c50x_init(UNUSED(const device_t *info)) dev->port_92 = device_add(&port_92_device); + if (dev->type & 2) { + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + device_add(&ide_pci_2ch_device); + } + sis_85c50x_reset(dev); return dev; @@ -459,3 +687,45 @@ const device_t sis_85c50x_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_550x_85c503_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_85c50x_5503_device = { + .name = "SiS 85C50x", + .internal_name = "sis_85c50x", + .flags = DEVICE_PCI, + .local = 2, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_550x_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 3, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index f6a923346..7a049b1cb 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -79,17 +79,14 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> - #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/pic.h> #include <86box/pci.h> - +#include <86box/port_92.h> #include <86box/chipset.h> -#define IDE_BIT 0x01 - #ifdef ENABLE_UMC_8886_LOG int umc_8886_do_log = ENABLE_UMC_8886_LOG; @@ -108,18 +105,6 @@ umc_8886_log(const char *fmt, ...) # define umc_8886_log(fmt, ...) #endif -/* PCI IRQ Flags */ -#define INTA (PCI_INTA + (2 * !(addr & 1))) -#define INTB (PCI_INTB + (2 * !(addr & 1))) -#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED) -#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED) - -/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */ -#define HAS_IDE dev->has_ide - -/* Southbridge Revision */ -#define SB_ID dev->sb_id - typedef struct umc_8886_t { uint8_t max_func; /* Last function number */ uint8_t pci_slot; @@ -128,19 +113,24 @@ typedef struct umc_8886_t { uint8_t pci_conf_sb[2][256]; /* PCI Registers */ - uint16_t sb_id; /* Southbridge Revision */ - int has_ide; /* Check if Southbridge Revision is AF or F */ + uint16_t sb_id; /* Southbridge Revision */ + uint16_t ide_id; /* IDE Revision */ + + int has_ide; /* Check if Southbridge Revision is F, AF, or BF */ } umc_8886_t; static void -umc_8886_ide_handler(int status) +umc_8886_ide_handler(umc_8886_t *dev) { ide_pri_disable(); ide_sec_disable(); - if (status) { - ide_pri_enable(); - ide_sec_enable(); + if (dev->pci_conf_sb[1][0x04] & 0x01) { + if (dev->pci_conf_sb[1][0x40] & 0x80) + ide_pri_enable(); + + if (dev->pci_conf_sb[1][0x40] & 0x40) + ide_sec_enable(); } } @@ -148,6 +138,7 @@ static void umc_8886_write(int func, int addr, uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; + int irq_routing; if (func <= dev->max_func) switch (func) { @@ -155,8 +146,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80)); switch (addr) { - case 0x04: - case 0x05: + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x42: + case 0x45: + case 0x50 ... 0x55: + case 0x57: + case 0x70 ... 0x76: + case 0x80 ... 0x82: + case 0x90 ... 0x92: + case 0xa0 ... 0xa1: + case 0xa5 ... 0xa8: dev->pci_conf_sb[func][addr] = val; break; @@ -164,46 +164,31 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf_sb[func][addr] &= ~(val & 0xf9); break; - case 0x0c: - case 0x0d: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x40: - case 0x41: - case 0x42: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x43: + dev->pci_conf_sb[func][addr] = val; + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTA, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTB, irq_routing); + break; case 0x44: dev->pci_conf_sb[func][addr] = val; - pci_set_irq_routing(INTA, IRQRECALCA); - pci_set_irq_routing(INTB, IRQRECALCB); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTC, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTD, irq_routing); break; - case 0x45: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x46: + case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */ + case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */ /* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */ dev->pci_conf_sb[func][addr] = val; break; - case 0x47: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x56: dev->pci_conf_sb[func][addr] = val; @@ -220,16 +205,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) default: break; } - - break; - - case 0x57: - case 0x70 ... 0x76: - case 0x80: - case 0x81: - case 0x90 ... 0x92: - case 0xa0 ... 0xa1: - dev->pci_conf_sb[func][addr] = val; break; case 0xa2: @@ -243,7 +218,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10)); else smi_raise(); - dev->pci_conf_sb[0][0xa3] |= 0x04; } dev->pci_conf_sb[func][addr] = val; @@ -254,10 +228,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2)); break; - case 0xa5 ... 0xa8: - dev->pci_conf_sb[func][addr] = val; - break; - default: break; } @@ -269,7 +239,8 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: dev->pci_conf_sb[func][addr] = val; - umc_8886_ide_handler(val & 1); + if (dev->ide_id == 0x673a) + umc_8886_ide_handler(dev); break; case 0x07: @@ -277,9 +248,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) break; case 0x3c: + case 0x41 ... 0x4b: + case 0x54 ... 0x59: + if (dev->ide_id == 0x673a) + dev->pci_conf_sb[func][addr] = val; + break; + case 0x40: - case 0x41: - dev->pci_conf_sb[func][addr] = val; + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[func][addr] = val; + umc_8886_ide_handler(dev); + } break; default: @@ -311,47 +290,73 @@ umc_8886_reset(void *priv) memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0])); memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1])); - dev->pci_conf_sb[0][0] = 0x60; /* UMC */ - dev->pci_conf_sb[0][1] = 0x10; - - dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */ - dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff); - - dev->pci_conf_sb[0][4] = 0x0f; - dev->pci_conf_sb[0][7] = 2; - - dev->pci_conf_sb[0][8] = 0x0e; - + dev->pci_conf_sb[0][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = (dev->sb_id & 0xff); /* 8886xx */ + dev->pci_conf_sb[0][0x03] = ((dev->sb_id >> 8) & 0xff); + dev->pci_conf_sb[0][0x04] = 0x0f; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = 0x0e; dev->pci_conf_sb[0][0x09] = 0x00; dev->pci_conf_sb[0][0x0a] = 0x01; dev->pci_conf_sb[0][0x0b] = 0x06; - - dev->pci_conf_sb[0][0x40] = 1; - dev->pci_conf_sb[0][0x41] = 6; - dev->pci_conf_sb[0][0x42] = 8; - dev->pci_conf_sb[0][0x43] = 0x9a; - dev->pci_conf_sb[0][0x44] = 0xbc; - dev->pci_conf_sb[0][0x45] = 4; + dev->pci_conf_sb[0][0x40] = 0x01; + dev->pci_conf_sb[0][0x41] = 0x06; + dev->pci_conf_sb[0][0x42] = 0x08; + dev->pci_conf_sb[0][0x43] = 0x00; + dev->pci_conf_sb[0][0x44] = 0x00; + dev->pci_conf_sb[0][0x45] = 0x04; + dev->pci_conf_sb[0][0x46] = 0x00; dev->pci_conf_sb[0][0x47] = 0x40; - dev->pci_conf_sb[0][0x50] = 1; - dev->pci_conf_sb[0][0x51] = 3; + dev->pci_conf_sb[0][0x50] = 0x01; + dev->pci_conf_sb[0][0x51] = 0x03; + dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00; + dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; + dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; + dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00; + dev->pci_conf_sb[0][0x82] = 0x00; + dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00; + dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00; + dev->pci_conf_sb[0][0xa4] = 0x00; dev->pci_conf_sb[0][0xa8] = 0x20; - if (HAS_IDE) { - dev->pci_conf_sb[1][0] = 0x60; /* UMC */ - dev->pci_conf_sb[1][1] = 0x10; + if (dev->has_ide) { + dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = (dev->ide_id & 0xff); /* 8886xx IDE */ + dev->pci_conf_sb[1][0x03] = ((dev->ide_id >> 8) & 0xff); + dev->pci_conf_sb[1][0x04] = 0x05; /* Start with Internal IDE Enabled */ + dev->pci_conf_sb[1][0x08] = 0x10; + dev->pci_conf_sb[1][0x09] = 0x8f; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0x10; - dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */ - dev->pci_conf_sb[1][3] = 0x67; + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[1][0x40] = 0xc0; + dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; + dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; + dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; + dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00; + dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00; + dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00; - dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */ + umc_8886_ide_handler(dev); - dev->pci_conf_sb[1][8] = 0x10; - - dev->pci_conf_sb[1][0x09] = 0x0f; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1; - - umc_8886_ide_handler(1); + picintc(1 << 14); + picintc(1 << 15); + } } for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */ @@ -375,17 +380,28 @@ umc_8886_init(const device_t *info) umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t)); memset(dev, 0, sizeof(umc_8886_t)); - dev->has_ide = !!(info->local == 0x886a); - pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */ - - /* Add IDE if UM8886AF variant */ - if (HAS_IDE) - device_add(&ide_pci_2ch_device); - - dev->max_func = (HAS_IDE) ? 1 : 0; + /* Device 12: UMC 8886xx */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Get the Southbridge Revision */ - SB_ID = info->local; + dev->sb_id = info->local & 0xffff; + + /* IDE Revision */ + dev->ide_id = info->local >> 16; + + dev->has_ide = (dev->ide_id != 0x0000); + + dev->max_func = 0; + + /* Add IDE if this is the UM8886AF or UM8886BF. */ + if (dev->ide_id == 0x673a) { + /* UM8886BF */ + device_add(&ide_pci_2ch_device); + dev->max_func = 1; + } else if (dev->ide_id == 0x1001) { + /* UM8886AF */ + device_add(&ide_um8673f_device); + } umc_8886_reset(dev); @@ -396,7 +412,7 @@ const device_t umc_8886f_device = { .name = "UMC 8886F", .internal_name = "umc_8886f", .flags = DEVICE_PCI, - .local = 0x8886, + .local = 0x00008886, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, @@ -407,10 +423,24 @@ const device_t umc_8886f_device = { }; const device_t umc_8886af_device = { - .name = "UMC 8886AF/8886BF", + .name = "UMC 8886AF", .internal_name = "umc_8886af", .flags = DEVICE_PCI, - .local = 0x886a, + .local = 0x1001886a, + .init = umc_8886_init, + .close = umc_8886_close, + .reset = umc_8886_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t umc_8886bf_device = { + .name = "UMC 8886BF", + .internal_name = "umc_8886bf", + .flags = DEVICE_PCI, + .local = 0x673a888a, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c new file mode 100644 index 000000000..d515e1c97 --- /dev/null +++ b/src/chipset/umc_8890.c @@ -0,0 +1,241 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC 8890 Chipset. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021-2024 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/apm.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UMC_8890_LOG +int umc_8890_do_log = ENABLE_UMC_8890_LOG; + +static void +umc_8890_log(const char *fmt, ...) +{ + va_list ap; + + if (umc_8890_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define umc_8890_log(fmt, ...) +#endif + +typedef struct umc_8890_t { + uint8_t pci_slot; + + uint8_t pci_conf[256]; /* PCI Registers */ + + int mem_state[2]; + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ +} umc_8890_t; + +static void +um8890_shadow(umc_8890_t *dev) +{ + uint8_t flag; + uint16_t state; + + flag = (dev->pci_conf[0x5f] & 0x0c) >> 2; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) { + mem_set_mem_state_both(0xe0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[2] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); + } + + flag = (dev->pci_conf[0x5f] & 0xc0) >> 6; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0xc0) { + mem_set_mem_state_both(0xf0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[1] & 0x0f) | (dev->pci_conf[0x5f] & 0xf0); + } + + for (uint8_t i = 0; i < 8; i++) { + state = (dev->pci_conf[0x5d] & (1 << i)) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[0] ^ dev->pci_conf[0x5d]) & (1 << i)) { + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, state); + dev->mem_state[0] = (dev->mem_state[0] & ~(1 << i)) | (dev->pci_conf[0x5d] & (1 << i)); + } + } + + flushmmucache_nopc(); +} + + +static void +um8890_smram(umc_8890_t *dev) +{ + smram_disable_all(); + + /* Bit 4, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled + in SMM, and is always set to A0000-BFFFF. */ + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x65] & 0x10, 1); +} + +static void +um8890_write(int func, int addr, uint8_t val, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + if (func == 0) switch (addr) { + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x5b: + case 0x60 ... 0x63: + case 0x66 ... 0xff: + dev->pci_conf[addr] = val; + break; + + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x5c ... 0x5f: + dev->pci_conf[addr] = val; + um8890_shadow(dev); + break; + + /* Register 64h, 16-bit: + Bit 12: SMRAM enabled outside SMM (1 = yes, 0 = no); + Bit 10: ???? (set by Award BIOS); + Bits 7- 0: SMM handler offset to SMBASE, shifted to the right by 14. + */ + case 0x64: case 0x65: + dev->pci_conf[addr] = val; + if (addr == 0x65) + um8890_smram(dev); + break; + } + + umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + + +static uint8_t +um8890_read(int func, int addr, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pci_conf[addr]; + + return ret; +} + +static void +umc_8890_reset(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); + + /* Defaults */ + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; /* 8891F */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x01; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + + um8890_shadow(dev); + + um8890_smram(dev); +} + + +static void +umc_8890_close(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + smram_del(dev->smram); + free(dev); +} + + +static void * +umc_8890_init(const device_t *info) +{ + umc_8890_t *dev = (umc_8890_t *) calloc(1, sizeof(umc_8890_t)); + + /* Device 0: UMC 8890 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev, &dev->pci_slot); + + /* Port 92 */ + device_add(&port_92_pci_device); + + dev->smram = smram_add(); + + umc_8890_reset(dev); + + return dev; +} + +const device_t umc_8890_device = { + .name = "UMC 8890(8891BF/8892BF)", + .internal_name = "umc_8890", + .flags = DEVICE_PCI, + .local = 0x886a, + .init = umc_8890_init, + .close = umc_8890_close, + .reset = umc_8890_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index d5cce0fca..a7ed0b880 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -14,13 +14,11 @@ * Note 2: Additional information were also used from all * around the web. * - * - * * Authors: Tiseno100, * Miran Grca, * * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * Copyright 2021-2024 Miran Grca. */ /* @@ -75,15 +73,24 @@ Bit 3: CC000-CFFFF Read Enable Bit 2: C8000-CBFFF Read Enable Bit 1: C0000-C7FFF Read Enable - Bit 0: Enable C0000-DFFFF Shadow Segment Bits + Bit 0: E0000-EFFFF Read Enable Register 55: - Bit 7: E0000-FFFF Read Enable + Bit 7: F0000-FFFF Read Enable Bit 6: Shadow Write Status (1: Write Protect/0: Write) Register 56h & 57h: DRAM Bank 0 Configuration Register 58h & 59h: DRAM Bank 1 Configuration + Register 5A: + Bit 2: Detrubo + + Register 5C: + Bits 7-0: SMRAM base A27-A20 + + Register 5D: + Bits 3-0: SMRAM base A31-A28 + Register 60: Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM @@ -129,14 +136,15 @@ hb4_log(const char *fmt, ...) #endif typedef struct hb4_t { - uint8_t shadow; - uint8_t shadow_read; - uint8_t shadow_write; uint8_t pci_slot; uint8_t pci_conf[256]; /* PCI Registers */ + int mem_state[9]; - smram_t *smram[3]; /* SMRAM Handlers */ + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ } hb4_t; static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY), @@ -167,7 +175,8 @@ hb4_shadow_bios_low(hb4_t *dev) { int state; - state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)]; + /* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */ + state = shadow_bios[dev->pci_conf[0x55] >> 6]; if (state != dev->mem_state[7]) { mem_set_mem_state_both(0xe0000, 0x10000, state); @@ -185,7 +194,8 @@ hb4_shadow_main(hb4_t *dev) int n = 0; for (uint8_t i = 0; i < 6; i++) { - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[i + 1]) { n++; @@ -202,7 +212,8 @@ hb4_shadow_video(hb4_t *dev) { int state; - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[0]) { mem_set_mem_state_both(0xc0000, 0x8000, state); @@ -232,22 +243,26 @@ static void hb4_smram(hb4_t *dev) { smram_disable_all(); + if (dev->smram_base != 0x00000000) + umc_smram_recalc(dev->smram_base >> 12, 0); + + dev->smram_base = ((uint32_t) dev->pci_conf[0x5c]) << 20; + dev->smram_base |= ((uint32_t) (dev->pci_conf[0x5d] & 0x0f)) << 28; + dev->smram_base |= 0x000a0000; /* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled in SMM, and is always set to A0000-BFFFF. */ - smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */ - smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */ - smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + smram_enable(dev->smram, dev->smram_base, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); /* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses this. */ if (dev->pci_conf[0x60] & 0x20) { if (dev->pci_conf[0x60] & 0x01) - mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02); - mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02); + mem_set_mem_state_smram_ex(0, dev->smram_base, 0x20000, 0x02); + mem_set_mem_state_smram_ex(1, dev->smram_base, 0x20000, 0x02); } + + umc_smram_recalc(dev->smram_base >> 12, 1); } static void @@ -278,38 +293,27 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) cpu_update_waitstates(); break; - case 0x51: - case 0x52: + case 0x51 ... 0x53: dev->pci_conf[addr] = val; break; - case 0x53: - dev->pci_conf[addr] = val; - hb4_log("HB53: %02X\n", val); - break; - - case 0x55: - dev->shadow_read = (val & 0x80); - dev->shadow_write = (val & 0x40); - dev->pci_conf[addr] = val; - hb4_shadow(dev); - break; - case 0x54: - dev->shadow = (val & 0x01) << 1; + case 0x54 ... 0x55: dev->pci_conf[addr] = val; hb4_shadow(dev); break; - case 0x56 ... 0x5f: + case 0x56 ... 0x5b: + case 0x5e ... 0x5f: dev->pci_conf[addr] = val; break; + case 0x5c ... 0x5d: case 0x60: dev->pci_conf[addr] = val; hb4_smram(dev); break; - case 0x61: + case 0x61 ... 0x62: dev->pci_conf[addr] = val; break; @@ -336,30 +340,35 @@ hb4_reset(void *priv) hb4_t *dev = (hb4_t *) priv; memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); - dev->pci_conf[0] = 0x60; /* UMC */ - dev->pci_conf[1] = 0x10; - - dev->pci_conf[2] = 0x81; /* 8881x */ - dev->pci_conf[3] = 0x88; - - dev->pci_conf[7] = 2; - - dev->pci_conf[8] = 4; - + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x81; /* 8881x */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x04; dev->pci_conf[0x09] = 0x00; dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; - - dev->pci_conf[0x51] = 1; - dev->pci_conf[0x52] = 1; - dev->pci_conf[0x5a] = 4; - dev->pci_conf[0x5c] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x01; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x04; + dev->pci_conf[0x5c] = 0x00; dev->pci_conf[0x5d] = 0x20; dev->pci_conf[0x5f] = 0xff; + dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; - hb4_write(0, 0x54, 0x00, dev); - hb4_write(0, 0x55, 0x00, dev); - hb4_write(0, 0x60, 0x80, dev); + hb4_shadow(dev); + hb4_smram(dev); cpu_cache_ext_enabled = 0; cpu_update_waitstates(); @@ -372,6 +381,7 @@ hb4_close(void *priv) { hb4_t *dev = (hb4_t *) priv; + smram_del(dev->smram); free(dev); } @@ -387,10 +397,9 @@ hb4_init(UNUSED(const device_t *info)) device_add(&port_92_pci_device); /* SMRAM */ - dev->smram[0] = smram_add(); - dev->smram[1] = smram_add(); - dev->smram[2] = smram_add(); + dev->smram = smram_add(); + dev->smram_base = 0x000a0000; hb4_reset(dev); return dev; diff --git a/src/device.c b/src/device.c index 6125674db..b934e7246 100644 --- a/src/device.c +++ b/src/device.c @@ -62,6 +62,7 @@ static device_t *devices[DEVICE_MAX]; static void *device_priv[DEVICE_MAX]; static device_context_t device_current; static device_context_t device_prev; +static void *device_common_priv; #ifdef ENABLE_DEVICE_LOG int device_do_log = ENABLE_DEVICE_LOG; @@ -209,6 +210,16 @@ device_add(const device_t *dev) return device_add_common(dev, dev, NULL, NULL, 0); } +void * +device_add_linked(const device_t *dev, void *priv) +{ + void *ret; + device_common_priv = priv; + ret = device_add_common(dev, dev, NULL, NULL, 0); + device_common_priv = NULL; + return ret; +} + void * device_add_parameters(const device_t *dev, void *params) { @@ -305,6 +316,12 @@ device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *pr device_add_common(dev, cd, priv, params, inst); } +void * +device_get_common_priv(void) +{ + return device_common_priv; +} + void device_close_all(void) { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 24a9d7ac4..9c5705325 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c + smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 8183f8afa..c1f551162 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -41,11 +41,13 @@ #define AGP_BRIDGE_VIA_598 0x11068598 #define AGP_BRIDGE_VIA_691 0x11068691 #define AGP_BRIDGE_VIA_8601 0x11068601 +#define AGP_BRIDGE_SIS_5XXX 0x10390001 #define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9) #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) #define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106) -#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_ALI_M5243) +#define AGP_BRIDGE_SIS(x) (((x) >> 16) == 0x1039) +#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_SIS_5XXX) typedef struct pci_bridge_t { uint32_t local; @@ -134,6 +136,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) val |= 0x02; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0xc3; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x27; else val &= 0x67; break; @@ -194,7 +198,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x22: case 0x24: case 0x26: - val &= 0xf0; + val &= 0xf0; /* SiS datasheets say 0Fh for 1Ch but that's clearly an erratum since the + definition of the bits is identical to the other vendors' AGP bridges. */ break; case 0x3c: @@ -205,6 +210,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x3e: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x0c; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x0e; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0x0f; else if (dev->local == AGP_BRIDGE_ALI_M5243) @@ -668,3 +675,17 @@ const device_t via_vt8601_agp_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_5xxx_agp_device = { + .name = "SiS 5591/(5)600 AGP Bridge", + .internal_name = "via_5xxx_agp", + .flags = DEVICE_PCI, + .local = AGP_BRIDGE_SIS_5XXX, + .init = pci_bridge_init, + .close = NULL, + .reset = pci_bridge_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/smbus_sis5595.c b/src/device/smbus_sis5595.c new file mode 100644 index 000000000..b76b38e17 --- /dev/null +++ b/src/device/smbus_sis5595.c @@ -0,0 +1,386 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of a generic SiS 5595-compatible SMBus host + * controller. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2020-2021 RichardG. + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/i2c.h> +#include <86box/pci.h> +#include <86box/smbus.h> +#include <86box/plat_fallthrough.h> + +#ifdef ENABLE_SMBUS_SIS5595_LOG +int smbus_sis5595_do_log = ENABLE_SMBUS_SIS5595_LOG; + +static void +smbus_sis5595_log(const char *fmt, ...) +{ + va_list ap; + + if (smbus_sis5595_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define smbus_sis5595_log(fmt, ...) +#endif + +static void +smbus_sis5595_irq(smbus_sis5595_t *dev, int raise) +{ + if (dev->irq_enable) { + if (raise) + pci_set_mirq(6, 1, &dev->irq_state); + else + pci_clear_mirq(6, 1, &dev->irq_state); + } +} + +void +smbus_sis5595_irq_enable(void *priv, uint8_t enable) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (!enable && dev->irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + + dev->irq_enable = enable; +} + +uint8_t +smbus_sis5595_read_index(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + return dev->index; +} + +uint8_t +smbus_sis5595_read_data(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t ret = 0x00; + + switch (dev->index) { + case 0x00: + ret = dev->stat & 0xff; + break; + case 0x01: + ret = dev->stat >> 8; + break; + + case 0x02: + ret = dev->ctl & 0xff; + break; + case 0x03: + ret = dev->ctl >> 8; + break; + + case 0x04: + ret = dev->addr; + break; + + case 0x05: + ret = dev->cmd; + break; + + case 0x06: + ret = dev->block_ptr; + break; + + case 0x07: + ret = dev->count; + break; + + case 0x08 ... 0x0f: + ret = dev->data[(dev->index & 0x07) + (dev->block_ptr << 3)]; + if (dev->index == 0x0f) { + dev->block_ptr = (dev->block_ptr + 1) & 3; + smbus_sis5595_irq(dev, dev->block_ptr != 0x00); + } + break; + + case 0x10: + ret = dev->saved_addr; + break; + + case 0x11: + ret = dev->data0; + break; + + case 0x12: + ret = dev->data1; + break; + + case 0x13: + ret = dev->alias; + break; + + case 0xff: + ret = dev->reg_ff & 0xc0; + break; + + default: + break; + } + + smbus_sis5595_log("SMBus SIS5595: read(%02X) = %02x\n", addr, ret); + + return ret; +} + +void +smbus_sis5595_write_index(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + dev->index = val; +} + +void +smbus_sis5595_write_data(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t smbus_addr; + uint8_t cmd; + uint8_t read; + uint16_t prev_stat; + uint16_t timer_bytes = 0; + + smbus_sis5595_log("SMBus SIS5595: write(%02X, %02X)\n", addr, val); + + prev_stat = dev->next_stat; + dev->next_stat = 0x0000; + switch (dev->index) { + case 0x00: + dev->stat &= ~(val & 0xf0); + /* Make sure IDLE is set if we're not busy or errored. */ + if (dev->stat == 0x04) + dev->stat = 0x00; + break; + case 0x01: + dev->stat &= ~(val & 0x07); + break; + + case 0x02: + dev->ctl = (dev->ctl & 0xff00) | val; + if (val & 0x20) { /* cancel an in-progress command if KILL is set */ + if (prev_stat) { /* cancel only if a command is in progress */ + timer_disable(&dev->response_timer); + dev->stat = 0x80; /* raise FAILED */ + } + } else if (val & 0x10) { + /* dispatch command if START is set */ + timer_bytes++; /* address */ + + smbus_addr = (dev->addr >> 1); + read = dev->addr & 0x01; + + cmd = (dev->ctl >> 1) & 0x7; + smbus_sis5595_log("SMBus SIS5595: addr=%02X read=%d protocol=%X cmd=%02X " + "data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, + dev->data0, dev->data1); + + /* Raise DEV_ERR if no device is at this address, or if the device returned + NAK when starting the transfer. */ + if (!i2c_start(i2c_smbus, smbus_addr, read)) { + dev->next_stat = 0x0020; + break; + } + + dev->next_stat = 0x0040; /* raise INTER (command completed) by default */ + + /* Decode the command protocol. */ + dev->block_ptr = 0x01; + switch (cmd) { + case 0x0: /* quick R/W */ + break; + + case 0x1: /* byte R/W */ + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x2: /* byte data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x3: /* word data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) { /* word read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + dev->data[1] = i2c_read(i2c_smbus, smbus_addr); + } else { /* word write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + i2c_write(i2c_smbus, smbus_addr, dev->data[1]); + } + timer_bytes += 2; + + break; + + case 0x5: /* block R/W */ + dev->block_ptr = 0x00; + timer_bytes++; /* count the SMBus length byte now */ + fallthrough; + + default: /* unknown */ + dev->next_stat = 0x0010; /* raise DEV_ERR */ + timer_bytes = 0; + break; + } + + /* Finish transfer. */ + i2c_stop(i2c_smbus, smbus_addr); + } + break; + case 0x03: + dev->ctl = (dev->ctl & 0x00ff) | (val << 8); + break; + + case 0x04: + dev->addr = val; + break; + + case 0x05: + dev->cmd = val; + break; + + case 0x08 ... 0x0f: + dev->data[dev->index & 0x07] = val; + break; + + case 0x10: + dev->saved_addr = val; + break; + + case 0x11: + dev->data0 = val; + break; + + case 0x12: + dev->data1 = val; + break; + + case 0x13: + dev->alias = val & 0xfe; + break; + + case 0xff: + dev->reg_ff = val & 0x3f; + break; + + default: + break; + } + + if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */ + dev->stat = 0x08; /* raise HOST_BUSY while waiting */ + timer_disable(&dev->response_timer); + /* delay = ((half clock for start + half clock for stop) + (bytes * (8 bits + ack))) * 60us period measured on real VIA 686B */ + timer_set_delay_u64(&dev->response_timer, (1 + (timer_bytes * 9)) * 60 * TIMER_USEC); + } +} + +static void +smbus_sis5595_response(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + /* Dispatch the status register update. */ + dev->stat = dev->next_stat; +} + +static void +smbus_sis5595_reset(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + timer_disable(&dev->response_timer); + dev->stat = 0x0000; + dev->block_ptr = 0x01; +} + +static void * +smbus_sis5595_init(const device_t *info) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) malloc(sizeof(smbus_sis5595_t)); + memset(dev, 0, sizeof(smbus_sis5595_t)); + + dev->local = info->local; + + /* We save the I2C bus handle on dev but use i2c_smbus for all operations because + dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */ + i2c_smbus = dev->i2c = i2c_addbus("smbus_sis5595"); + + timer_add(&dev->response_timer, smbus_sis5595_response, dev, 0); + + smbus_sis5595_reset(dev); + + return dev; +} + +static void +smbus_sis5595_close(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (i2c_smbus == dev->i2c) + i2c_smbus = NULL; + i2c_removebus(dev->i2c); + + free(dev); +} + +const device_t sis5595_smbus_device = { + .name = "SiS 5595-compatible SMBus Host Controller", + .internal_name = "sis5595_smbus", + .flags = DEVICE_AT, + .local = 0, + .init = smbus_sis5595_init, + .close = smbus_sis5595_close, + .reset = smbus_sis5595_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 00da385d4..310354ccf 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c - hdc_ide_sff8038i.c) + hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 3f43f80e6..631afa931 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -436,9 +436,9 @@ sff_bus_master_set_irq(uint8_t status, void *priv) case IRQ_MODE_SIS_551X: /* SiS 551x mode. */ if (irq) - pci_set_mirq(2, 1, &dev->irq_state); + pci_set_mirq(dev->mirq, 1, &dev->irq_state); else - pci_clear_mirq(2, 1, &dev->irq_state); + pci_clear_mirq(dev->mirq, 1, &dev->irq_state); break; } } @@ -554,6 +554,12 @@ sff_set_irq_pin(sff8038i_t *dev, int irq_pin) dev->irq_pin = irq_pin; } +void +sff_set_mirq(sff8038i_t *dev, uint8_t mirq) +{ + dev->mirq = mirq; +} + static void sff_close(void *priv) { @@ -586,6 +592,7 @@ sff_init(UNUSED(const device_t *info)) dev->pci_irq_line = 14; dev->irq_level = 0; dev->irq_state = 0; + dev->mirq = 2; dev->channel = next_id; next_id++; diff --git a/src/disk/hdc_ide_um8673f.c b/src/disk/hdc_ide_um8673f.c new file mode 100644 index 000000000..9ee149c7f --- /dev/null +++ b/src/disk/hdc_ide_um8673f.c @@ -0,0 +1,212 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC UMF8673F IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UM8673F_LOG +int um8673f_do_log = ENABLE_UM8673F_LOG; + +static void +um8673f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8673f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8673f_log(fmt, ...) +#endif + +typedef struct um8673f_t { + uint8_t index; + uint8_t tries; + uint8_t unlocked; + + uint8_t regs[256]; +} um8673f_t; + +static void +um8673f_ide_handler(um8673f_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0xb0] & 0x80) + ide_pri_enable(); + if (dev->regs[0xb0] & 0x40) + ide_sec_enable(); +} + +static void +um8673f_write(uint16_t addr, uint8_t val, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + um8673f_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0x108: + if (dev->unlocked) { + if (dev->index == 0x34) { + dev->unlocked = 0; + dev->tries = 0; + } else + dev->index = val; + } else if (((dev->tries == 0) && (val == 0x4a)) || + ((dev->tries == 1) && (val == 0x6c))) { + dev->tries++; + if (dev->tries == 2) + dev->unlocked = 1; + } else + dev->tries = 0; + break; + + case 0x109: + switch (dev->index) { + case 0xb0: + dev->regs[dev->index] = val; + um8673f_ide_handler(dev); + break; + case 0xb1 ... 0xb8: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +um8673f_read(uint16_t addr, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x108: + if (dev->unlocked) + ret = dev->index; + else + dev->tries = 0; + break; + case 0x109: + if ((dev->index >= 0xb0) && (dev->index <= 0xb8)) + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + um8673f_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +um8673f_reset(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0xb0] = 0xc0; + + um8673f_ide_handler(dev); +} + +static void +um8673f_close(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + free(dev); +} + +static void * +um8673f_init(UNUSED(const device_t *info)) +{ + um8673f_t *dev = (um8673f_t *) calloc(1, sizeof(um8673f_t)); + + io_sethandler(0x0108, 0x0002, um8673f_read, NULL, NULL, um8673f_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + um8673f_reset(dev); + + return dev; +} + +const device_t ide_um8886af_device = { + .name = "UMC UM8886F IDE", + .internal_name = "um8886af_ide", + .flags = 0, + .local = 1, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_um8673f_device = { + .name = "UMC UM8673F", + .internal_name = "um8673f", + .flags = 0, + .local = 0, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c new file mode 100644 index 000000000..ed34bc9fc --- /dev/null +++ b/src/disk/hdc_ide_w83769f.c @@ -0,0 +1,460 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Winbond W83769F controller. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/zip.h> +#include <86box/mo.h> + +typedef struct w83769f_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t regs[256]; +} w83769f_t; + +static int next_id = 0; + +#ifdef ENABLE_W83769F_LOG +int w83769f_do_log = ENABLE_W83769F_LOG; + +static void +w83769f_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd640_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define w83769f_log(fmt, ...) +#endif + +void +w83769f_set_irq_0(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 1)) + return; + + if (irq) + picint(1 << 14); + else + picintc(1 << 14); +} + +void +w83769f_set_irq_1(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 2)) + return; + + if (irq) + picint(1 << 15); + else + picintc(1 << 15); +} + +static void +w83769f_ide_handlers(w83769f_t *dev) +{ + if (dev->channels & 0x01) { + ide_pri_disable(); + + if (!dev->pci || (dev->regs[0x04] & 0x01)) + ide_pri_enable(); + } + + if (dev->channels & 0x02) { + ide_sec_disable(); + + if ((!dev->pci || (dev->regs[0x04] & 0x01)) && (dev->regs[0x57] & 0x01)) + ide_sec_enable(); + } +} + +static void +w83769f_common_write(int addr, uint8_t val, w83769f_t *dev) +{ + switch (addr) { + case 0x50: + case 0x57: + dev->regs[0x57] = val & 0x01; + w83769f_ide_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0x7f; + break; + case 0x52: + case 0x54: + case 0x56: + case 0x58 ... 0x59: + dev->regs[addr] = val; + break; + case 0x53: + case 0x55: + dev->regs[addr] = val & 0xcf; + break; + + default: + break; + } +} + +static void +w83769f_vlb_write(uint16_t addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + dev->vlb_idx = val; + break; + case 0x0038: + case 0x00b8: + w83769f_common_write(dev->vlb_idx, val, dev); + break; + + default: + break; + } +} + +static void +w83769f_vlb_writew(uint16_t addr, uint16_t val, void *priv) +{ + w83769f_vlb_write(addr, val & 0xff, priv); + w83769f_vlb_write(addr + 1, val >> 8, priv); +} + +static void +w83769f_vlb_writel(uint16_t addr, uint32_t val, void *priv) +{ + w83769f_vlb_writew(addr, val & 0xffff, priv); + w83769f_vlb_writew(addr + 2, val >> 16, priv); +} + +static uint8_t +w83769f_vlb_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + ret = dev->vlb_idx; + break; + case 0x0038: + case 0x00b8: + ret = dev->regs[dev->vlb_idx]; + if (dev->vlb_idx == 0x50) + dev->regs[0x50] &= ~0x04; + break; + + default: + break; + } + + return ret; +} + +static uint16_t +w83769f_vlb_readw(uint16_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + ret = w83769f_vlb_read(addr, priv); + ret |= (w83769f_vlb_read(addr + 1, priv) << 8); + + return ret; +} + +static uint32_t +w83769f_vlb_readl(uint16_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + ret = w83769f_vlb_readw(addr, priv); + ret |= (w83769f_vlb_readw(addr + 2, priv) << 16); + + return ret; +} + +static void +w83769f_pci_write(int func, int addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + w83769f_log("w83769f_pci_write(%i, %02X, %02X)\n", func, addr, val); + + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (dev->regs[addr] & 0xbf) | (val & 0x40); + w83769f_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + break; + } +} + +static uint8_t +w83769f_pci_read(int func, int addr, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = dev->regs[addr]; + + w83769f_log("w83769f_pci_read(%i, %02X, %02X)\n", func, addr, ret); + + return ret; +} + +static void +w83769f_reset(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < ZIP_NUM; i++) { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && + (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + if (dev->channels & 0x01) + w83769f_set_irq_0(0x00, priv); + + if (dev->channels & 0x02) + w83769f_set_irq_1(0x00, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x50] = (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + dev->regs[0x51] = 0x40; + dev->regs[0x57] = 0x01; /* Required by the MSI MS-5109 */ + dev->regs[0x59] = 0x40; + + if (dev->pci) { + dev->regs[0x00] = 0xad; /* Winbond */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x01; /* W83769 */ + dev->regs[0x03] = 0x00; + dev->regs[0x04] = 0x01; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* 00h for Rev BB, 02h for Rev A3C */ + dev->regs[0x09] = 0x00; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + } else + dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */ + + w83769f_ide_handlers(dev); +} + +static void +w83769f_close(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + free(dev); + + next_id = 0; +} + +static void * +w83769f_init(const device_t *info) +{ + w83769f_t *dev = (w83769f_t *) malloc(sizeof(w83769f_t)); + memset(dev, 0x00, sizeof(w83769f_t)); + + dev->id = next_id | 0x60; + + dev->pci = !!(info->flags & DEVICE_PCI); + + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + + if (info->flags & DEVICE_PCI) { + device_add(&ide_pci_2ch_device); + + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + } else if (info->flags & DEVICE_VLB) + device_add(&ide_vlb_2ch_device); + + if (dev->channels & 0x01) + ide_set_bus_master(0, NULL, w83769f_set_irq_0, dev); + + if (dev->channels & 0x02) + ide_set_bus_master(1, NULL, w83769f_set_irq_1, dev); + + /* The CMD PCI-0640B IDE controller has no DMA capability, + so set our devices IDE devices to force ATA-3 (no DMA). */ + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); + + io_sethandler(info->local & 0xffff, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + io_sethandler((info->local & 0xffff) + 0x0004, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + + next_id++; + + w83769f_reset(dev); + + return dev; +} + +const device_t ide_w83769f_vlb_device = { + .name = "Winbond W83769F VLB", + .internal_name = "ide_w83769f_vlb", + .flags = DEVICE_VLB, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_vlb_34_device = { + .name = "Winbond W83769F VLB (Port 34h)", + .internal_name = "ide_w83769f_vlb_34", + .flags = DEVICE_VLB, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_device = { + .name = "Winbond W83769F PCI", + .internal_name = "ide_w83769f_pci", + .flags = DEVICE_PCI, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_34_device = { + .name = "Winbond W83769F PCI (Port 34h)", + .internal_name = "ide_w83769f_pci_34", + .flags = DEVICE_PCI, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 2b8a6396f..5a3eb39ec 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -52,12 +52,14 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -#define VEN_ALI 0x010b9 -#define VEN_INTEL 0x08086 -#define VEN_SIS 0x01039 -#define VEN_SMC 0x01055 -#define VEN_VIA 0x01106 -#define VEN_VIA_596B 0x11106 +#define VEN_ALI 0x010b9 +#define VEN_INTEL 0x08086 +#define VEN_SIS_5582 0x01039 +#define VEN_SIS_5595_1997 0x11039 +#define VEN_SIS_5595 0x21039 +#define VEN_SMC 0x01055 +#define VEN_VIA 0x01106 +#define VEN_VIA_596B 0x11106 typedef struct acpi_regs_t { uint8_t acpitst; @@ -76,6 +78,25 @@ typedef struct acpi_regs_t { uint8_t gporeg[4]; uint8_t extiotrapsts; uint8_t extiotrapen; + uint8_t enter_c2_ps; + uint8_t enter_c3_ps; + uint8_t reg_12; + uint8_t reg_13; + uint8_t smi_cmd; + uint8_t reg_24; + uint8_t reg_25; + uint8_t reg_26; + uint8_t smi_en_val; + uint8_t smi_dis_val; + uint8_t mail_box; + uint8_t reg_2b; + uint8_t gp_tmr; + uint8_t leg_sts; + uint8_t leg_en; + uint8_t tst_ctl; + uint8_t reg_34; + uint8_t index; + uint8_t reg_ff; uint16_t pmsts; uint16_t pmen; uint16_t pmcntrl; @@ -91,6 +112,15 @@ typedef struct acpi_regs_t { uint16_t gpsmien; uint16_t pscntrl; uint16_t gpscists; + uint16_t reg_14; + uint16_t reg_16; + uint16_t reg_18; + uint16_t reg_1a; + uint16_t reg_1c; + uint16_t gpe_mul; + uint16_t gpe_ctl; + uint16_t gpe_smi; + uint16_t gpe_rl; int smi_lock; int smi_active; uint32_t pcntrl; @@ -107,7 +137,12 @@ typedef struct acpi_regs_t { uint32_t gpo_val; uint32_t gpi_val; uint32_t extsmi_val; - uint32_t pad0; + uint32_t reg_0c; + uint32_t gpe_sts; + uint32_t gpe_en; + uint32_t gpe_pin; + uint32_t gpe_io; + uint32_t gpe_pol; } acpi_regs_t; typedef struct acpi_t { @@ -128,11 +163,15 @@ typedef struct acpi_t { pc_timer_t timer; pc_timer_t resume_timer; pc_timer_t pwrbtn_timer; + pc_timer_t gp_timer; + pc_timer_t per_timer; nvr_t *nvr; apm_t *apm; void *i2c; void (*trap_update)(void *priv); void *trap_priv; + void *smbus; + void *priv; } acpi_t; /* Global variables. */ @@ -145,6 +184,9 @@ extern const device_t acpi_intel_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; extern const device_t acpi_via_596b_device; +extern const device_t acpi_sis_5582_device; +extern const device_t acpi_sis_5595_1997_device; +extern const device_t acpi_sis_5595_device; /* Functions */ extern void acpi_update_irq(acpi_t *dev); @@ -163,6 +205,12 @@ extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr); extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv); extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev); extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi); +extern void * acpi_get_smbus(void *priv); +extern void acpi_sis5582_pmu_event(void *priv); +extern void acpi_sis5595_smi_raise(void *priv); +extern void acpi_sis5595_pmu_event(void *priv); +extern void acpi_sis5595_smbus_event(void *priv); +extern void acpi_sis5595_software_smi(void *priv); #ifdef __cplusplus } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 4aa3ee3e9..d5a96baf9 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -130,8 +130,16 @@ extern const device_t sis_85c471_device; extern const device_t sis_85c496_device; extern const device_t sis_85c496_ls486e_device; extern const device_t sis_85c50x_device; +extern const device_t sis_550x_85c503_device; +extern const device_t sis_85c50x_5503_device; +extern const device_t sis_550x_device; extern const device_t sis_5511_device; extern const device_t sis_5571_device; +extern const device_t sis_5581_device; +extern const device_t sis_5591_1997_device; +extern const device_t sis_5591_device; +extern const device_t sis_5600_1997_device; +extern const device_t sis_5600_device; /* ST */ extern const device_t stpc_client_device; @@ -144,6 +152,8 @@ extern const device_t stpc_lpt_device; /* UMC */ extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; +extern const device_t umc_8886bf_device; +extern const device_t umc_8890_device; extern const device_t umc_hb4_device; /* VIA */ diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 71a76c6b1..bd39a02e4 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -202,6 +202,7 @@ extern void device_context(const device_t *dev); extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); extern void *device_add(const device_t *d); +extern void *device_add_linked(const device_t *d, void *priv); extern void *device_add_parameters(const device_t *dev, void *params); extern void device_add_ex(const device_t *dev, void *priv); extern void device_add_ex_parameters(const device_t *dev, void *priv, void *params); @@ -217,6 +218,7 @@ extern void *device_cadd_inst(const device_t *dev, const device_t *cd, int inst) extern void *device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params); extern void device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst); extern void device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params); +extern void *device_get_common_priv(void); extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); extern void *device_find_first_priv(uint32_t match_flags); diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 01f927185..a3d562b62 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -77,8 +77,16 @@ extern const device_t ide_cmd646_device; /* CMD PCI-646 * extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ -extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ -extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ +extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ +extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ + +extern const device_t ide_um8673f_device; /* UMC UM8673F */ +extern const device_t ide_um8886af_device; /* UMC UM8886AF */ + +extern const device_t ide_w83769f_vlb_device; /* Winbond W83769F VLB */ +extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */ +extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */ +extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */ extern const device_t ide_ter_device; extern const device_t ide_ter_pnp_device; diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 2283497bb..3a69fdfac 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -43,6 +43,7 @@ typedef struct sff8038i_t uint8_t irq_state; uint8_t channel; uint8_t irq_line; + uint8_t mirq; uint16_t base; uint16_t pad; uint32_t ptr; @@ -72,10 +73,9 @@ extern void sff_bus_master_reset(sff8038i_t *dev); extern void sff_set_slot(sff8038i_t *dev, int slot); extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); - extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); - extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); +extern void sff_set_mirq(sff8038i_t *dev, uint8_t mirq); #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4fba180b2..6817a0de5 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -245,8 +245,12 @@ enum { MACHINE_CHIPSET_SIS_471, MACHINE_CHIPSET_SIS_496, MACHINE_CHIPSET_SIS_501, + MACHINE_CHIPSET_SIS_5501, MACHINE_CHIPSET_SIS_5511, MACHINE_CHIPSET_SIS_5571, + MACHINE_CHIPSET_SIS_5581, + MACHINE_CHIPSET_SIS_5591, + MACHINE_CHIPSET_SIS_5600, MACHINE_CHIPSET_SMSC_VICTORYBX_66, MACHINE_CHIPSET_STPC_CLIENT, MACHINE_CHIPSET_STPC_CONSUMER_II, @@ -641,6 +645,11 @@ extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); extern int machine_at_p54sps_init(const machine_t *); +extern int machine_at_ms5109_init(const machine_t *); +extern int machine_at_torino_init(const machine_t *); + +extern int machine_at_hot539_init(const machine_t *); + /* m_at_socket7_3v.c */ extern int machine_at_p54tp4xe_init(const machine_t *); extern int machine_at_p54tp4xe_mr_init(const machine_t *); @@ -669,6 +678,8 @@ extern int machine_at_ms5124_init(const machine_t *); extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); +extern int machine_at_5sbm2_init(const machine_t *); + /* m_at_socket7.c */ extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); @@ -718,6 +729,12 @@ extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); +extern int machine_at_sp97xv_init(const machine_t *); +extern int machine_at_sq578_init(const machine_t *); + +extern int machine_at_5sg100_init(const machine_t *); +extern int machine_at_ms5172_init(const machine_t *); + /* m_at_sockets7.c */ extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); @@ -780,6 +797,8 @@ extern int machine_at_vei8_init(const machine_t *); extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); +extern int machine_at_p6f99_init(const machine_t *); + /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); extern int machine_at_s2dge_init(const machine_t *); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index d24ca903c..85e0954f0 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -122,6 +122,8 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_read_addr_set(int set, nvr_t *nvr); +extern uint8_t nvr_get_index(void *priv, uint8_t addr_id); +extern void nvr_at_data_port(int set, nvr_t *nvr); extern void nvr_wp_set(int set, int h, nvr_t *nvr); 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); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 2bcb6b3b8..8483eb417 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -286,6 +286,7 @@ extern const device_t via_vp3_agp_device; extern const device_t via_mvp3_agp_device; extern const device_t via_apro_agp_device; extern const device_t via_vt8601_agp_device; +extern const device_t sis_5xxx_agp_device; #endif #endif /*EMU_PCI_H*/ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index b07e73e8e..31d5d12ae 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -75,6 +75,12 @@ extern const device_t ps1_m2133_sio; #if defined(DEV_BRANCH) && defined(USE_SIO_DETECT) extern const device_t sio_detect_device; #endif +extern const device_t um8663af_device; +extern const device_t um8663af_ide_device; +extern const device_t um8663af_sec_device; +extern const device_t um8663bf_device; +extern const device_t um8663bf_ide_device; +extern const device_t um8663bf_sec_device; extern const device_t um8669f_device; extern const device_t um8669f_ide_device; extern const device_t um8669f_ide_sec_device; diff --git a/src/include/86box/sis_55xx.h b/src/include/86box/sis_55xx.h new file mode 100644 index 000000000..99ccf7dfa --- /dev/null +++ b/src/include/86box/sis_55xx.h @@ -0,0 +1,78 @@ +/* + * 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. + * + * Header for the implementation of the SiS 55xx Pentium + * PCI/ISA Chipsets. + * + * Authors: Miran Grca, + * + * Copyright 2019-2020 Miran Grca. + */ +#ifndef EMU_SIS_55XX_H +#define EMU_SIS_55XX_H + +typedef struct +{ + uint8_t sb_pci_slot; + uint8_t ide_bits_1_3_writable; + uint8_t usb_enabled; + + uint8_t *pmu_regs; + + sff8038i_t *bm[2]; + acpi_t *acpi; +} sis_55xx_common_t; + +extern void sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5511_host_to_pci_read(int addr, void *priv); +extern void sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5571_host_to_pci_read(int addr, void *priv); +extern void sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5581_host_to_pci_read(int addr, void *priv); +extern void sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5591_host_to_pci_read(int addr, void *priv); +extern void sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5600_host_to_pci_read(int addr, void *priv); + +extern void sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_pci_to_isa_read(int addr, void *priv); +extern void sis_5513_ide_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_ide_read(int addr, void *priv); +extern void sis_5572_usb_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5572_usb_read(int addr, void *priv); +extern void sis_5595_pmu_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5595_pmu_read(int addr, void *priv); + +extern const device_t sis_5511_h2p_device; +extern const device_t sis_5571_h2p_device; +extern const device_t sis_5581_h2p_device; +extern const device_t sis_5591_h2p_device; +extern const device_t sis_5600_h2p_device; + +extern const device_t sis_5513_p2i_device; +extern const device_t sis_5572_p2i_device; +extern const device_t sis_5582_p2i_device; +extern const device_t sis_5595_1997_p2i_device; +extern const device_t sis_5595_p2i_device; + +extern const device_t sis_5513_ide_device; +extern const device_t sis_5572_ide_device; +extern const device_t sis_5582_ide_device; +extern const device_t sis_5591_5600_ide_device; + +extern const device_t sis_5572_usb_device; +extern const device_t sis_5582_usb_device; +extern const device_t sis_5595_usb_device; + +extern const device_t sis_5595_pmu_device; +extern const device_t sis_5595_1997_pmu_device; + +extern const device_t sis_55xx_common_device; + + +#endif /*EMU_SIS_55XX_H*/ diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index 340d1d00e..2c06c3d4e 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -15,8 +15,8 @@ * Copyright 2020 RichardG. */ -#ifndef EMU_SMBUS_PIIX4_H -#define EMU_SMBUS_PIIX4_H +#ifndef EMU_SMBUS_H +#define EMU_SMBUS_H #define SMBUS_PIIX4_BLOCK_DATA_SIZE 32 #define SMBUS_PIIX4_BLOCK_DATA_MASK (SMBUS_PIIX4_BLOCK_DATA_SIZE - 1) @@ -24,6 +24,9 @@ #define SMBUS_ALI7101_BLOCK_DATA_SIZE 32 #define SMBUS_ALI7101_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) +#define SMBUS_SIS5595_BLOCK_DATA_SIZE 32 +#define SMBUS_SIS5595_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) + enum { SMBUS_PIIX4 = 0, SMBUS_VIA = 1 @@ -63,16 +66,47 @@ typedef struct smbus_ali7101_t { void *i2c; } smbus_ali7101_t; -extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); -extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); +typedef struct smbus_sis5595_t { + uint32_t local; + uint16_t stat; + uint16_t next_stat; + uint16_t ctl; + uint8_t cmd; + uint8_t addr; + uint8_t saved_addr; + uint8_t block_ptr; + uint8_t count; + uint8_t data0; + uint8_t data1; + uint8_t alias; + uint8_t reg_ff; + uint8_t index; + uint8_t irq_enable; + uint8_t irq_state; + uint8_t data[SMBUS_SIS5595_BLOCK_DATA_SIZE]; + pc_timer_t response_timer; + void *i2c; +} smbus_sis5595_t; -extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); + +extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); + +extern void smbus_sis5595_irq_enable(void *priv, uint8_t enable); + +extern uint8_t smbus_sis5595_read_index(void *priv); +extern uint8_t smbus_sis5595_read_data(void *priv); +extern void smbus_sis5595_write_index(void *priv, uint8_t val); +extern void smbus_sis5595_write_data(void *priv, uint8_t val); #ifdef EMU_DEVICE_H extern const device_t piix4_smbus_device; extern const device_t via_smbus_device; extern const device_t ali7101_smbus_device; + +extern const device_t sis5595_smbus_device; #endif -#endif /*EMU_SMBUS_PIIX4_H*/ +#endif /*EMU_SMBUS_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 47d237b10..33375f765 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -368,8 +368,9 @@ extern const device_t gd5434_onboard_pci_device; extern const device_t gd5434_vlb_device; extern const device_t gd5434_pci_device; extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; +extern const device_t gd5436_onboard_pci_device; extern const device_t gd5440_pci_device; +extern const device_t gd5440_onboard_pci_device; extern const device_t gd5446_pci_device; extern const device_t gd5446_stb_pci_device; extern const device_t gd5480_pci_device; @@ -539,6 +540,7 @@ extern const device_t tgui9440_vlb_device; extern const device_t tgui9440_pci_device; extern const device_t tgui9440_onboard_pci_device; extern const device_t tgui9660_pci_device; +extern const device_t tgui9660_onboard_pci_device; extern const device_t tgui9680_pci_device; /* IBM PS/1 (S)VGA */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 63f59cb07..1dd63ce32 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1908,7 +1908,7 @@ machine_at_hot433a_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&um8669f_device); device_add(&winbond_flash_w29c010_device); device_add(&keyboard_at_ami_device); @@ -1937,7 +1937,7 @@ machine_at_atc1415_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_at_ami_device); @@ -1966,10 +1966,9 @@ machine_at_actionpc2600_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_ps2_tg_ami_device); @@ -2001,7 +2000,7 @@ machine_at_actiontower8400_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886f_device); device_add(&fdc37c665_device); device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. @@ -2033,8 +2032,8 @@ machine_at_m919_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */ + device_add(&um8663bf_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_ami_device); @@ -2226,7 +2225,7 @@ machine_at_ap4100aa_init(const machine_t *model) device_add(&ali1429g_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&ide_vlb_device); - device_add(&um8669f_device); // needs um8663 + device_add(&um8663bf_device); return ret; } diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 12c84ffdf..d31d763d4 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -807,3 +807,37 @@ machine_at_m729_init(const machine_t *model) return ret; } + +int +machine_at_p6f99_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6f99/99-8.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_SOUND, 2, 3, 4, 1); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5600_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&winbond_flash_w29c020_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&es1371_onboard_device); + + return ret; +} + diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4a86c75d0..916f8490b 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -511,3 +511,99 @@ machine_at_p54sps_init(const machine_t *model) return ret; } + +int +machine_at_ms5109_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5109/A778.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 3, 2, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_550x_85c503_device); + device_add(&ide_w83769f_pci_device); + device_add(&keyboard_ps2_ami_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_torino_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/torino/PER113.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&sis_550x_85c503_device); + device_add(&ide_um8673f_device); + device_add(&keyboard_ps2_tg_ami_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_hot539_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hot539/539_R17.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x15, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x16, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&umc_8890_device); + device_add(&umc_8886af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&um8663af_device); + + return ret; +} diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index fd453f9af..09441ad4f 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1268,6 +1268,119 @@ machine_at_cb52xsi_init(const machine_t *model) return ret; } +int +machine_at_sp97xv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sp97xv/0109XVJ2.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */ + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_sq578_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sq578/578b03.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_5sg100_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sg100/5sg.20g", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_ms5172_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5172/A572MS15.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_m560_init(const machine_t *model) { @@ -1347,7 +1460,7 @@ machine_at_thunderbolt_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 1, 2, 3); /* PIIX4 */ + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 1, 2, 3); /* PIIX4 */ pci_register_slot(0x11, PCI_CARD_NORMAL, 0, 1, 2, 3); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 0, 1); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 2e642082d..676f50fb1 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -858,3 +858,31 @@ machine_at_vectra54_init(const machine_t *model) return ret; } + +int +machine_at_5sbm2_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sbm2/5SBM0717.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&keyboard_at_ami_device); + device_add(&sis_550x_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d6849c7ac..beac1cf6e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -139,8 +139,12 @@ const machine_filter_t machine_chipsets[] = { { "SiS 471", MACHINE_CHIPSET_SIS_471 }, { "SiS 496", MACHINE_CHIPSET_SIS_496 }, { "SiS 501", MACHINE_CHIPSET_SIS_501 }, + { "SiS 5501", MACHINE_CHIPSET_SIS_5501 }, { "SiS 5511", MACHINE_CHIPSET_SIS_5511 }, { "SiS 5571", MACHINE_CHIPSET_SIS_5571 }, + { "SiS 5581", MACHINE_CHIPSET_SIS_5581 }, + { "SiS 5591", MACHINE_CHIPSET_SIS_5591 }, + { "SiS (5)600", MACHINE_CHIPSET_SIS_5600 }, { "SMSC VictoryBX-66", MACHINE_CHIPSET_SMSC_VICTORYBX_66 }, { "STPC Client", MACHINE_CHIPSET_STPC_CLIENT }, { "STPC Consumer-II", MACHINE_CHIPSET_STPC_CONSUMER_II }, @@ -9744,6 +9748,128 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 5501] MSI MS-5109", + .internal_name = "ms5109", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_ms5109_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[SiS 5501] TriGem Torino", + .internal_name = "torino", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_torino_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9660_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + + /* UMC 889x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[UMC 889x] Shuttle HOT-539", + .internal_name = "hot539", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_UMC_UM8890BF, + .init = machine_at_hot539_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 40000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3600, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Socket 7 (Single Voltage) machines */ /* 430FX */ @@ -10528,6 +10654,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5501 */ + /* Has the Lance LT38C41 KBC. */ + { + .name = "[SiS 5501] Chaintech 5SBM2 (M103)", + .internal_name = "5sbm2", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_5sbm2_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* SiS 5511 */ /* Has AMIKey H KBC firmware (AMIKey-2). */ { @@ -12159,6 +12327,171 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5581 */ + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] ASUS SP97-XV", + .internal_name = "sp97xv", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sp97xv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] BCM SQ-578", + .internal_name = "sq578", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sq578_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] MSI MS-5172", + .internal_name = "ms5172", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_ms5172_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { @@ -14057,6 +14390,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS (5)600 */ + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] Freetech/Flexus P6F99", + .internal_name = "p6f99", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_p6f99_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ + .net_device = NULL + }, + /* Slot 1/2 machines */ /* 440GX */ /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC diff --git a/src/nvr_at.c b/src/nvr_at.c index 7e356f55d..4ddec729f 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -686,6 +686,19 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) } } +/* Get the NVR register index (used for APC). */ +uint8_t +nvr_get_index(void *priv, uint8_t addr_id) +{ + nvr_t *nvr = (nvr_t *) priv; + local_t *local = (local_t *) nvr->data; + uint8_t ret; + + ret = local->addr[addr_id]; + + return ret; +} + /* Read from one of the NVR registers. */ static uint8_t nvr_read(uint16_t addr, void *priv) @@ -932,6 +945,17 @@ nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr) } } +void +nvr_at_data_port(int set, nvr_t *nvr) +{ + io_handler(0, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); + + if (set) + io_handler(1, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); +} + void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr) { diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 3140a7181..dff0fcd0f 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -18,7 +18,8 @@ add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c sio_it86x1f.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c - sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c + sio_w83787f.c sio_w83877f.c sio_w83977f.c + sio_um8663f.c sio_um8669f.c sio_vt82c686.c) if(SIO_DETECT) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index 74e79bbed..ece59501f 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -414,8 +414,10 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) case 0x23: val &= (1 << dev->gpio_ldn) - 1; dev->global_regs[reg & 0x0f] = val; +#ifdef ENABLE_IT86X1F_LOG if (val) - pclog("IT86x1F: Warning: ISAPnP mode enabled.\n"); + it86x1f_log("IT86x1F: Warning: ISAPnP mode enabled.\n"); +#endif break; case 0x24: diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c new file mode 100644 index 000000000..7391b029f --- /dev/null +++ b/src/sio/sio_um8663f.c @@ -0,0 +1,366 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC UMF8663F Super I/O chip. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/sio.h> +#include <86box/random.h> +#include <86box/plat_unused.h> + +#ifdef ENABLE_UM8663F_LOG +int um8663f_do_log = ENABLE_UM8663F_LOG; + +static void +um8663f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8663f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8663f_log(fmt, ...) +#endif + +typedef struct um8663f_t { + uint8_t max_reg; + uint8_t ide; + uint8_t locked; + uint8_t cur_reg; + uint8_t regs[5]; + + fdc_t *fdc; + serial_t *uart[2]; +} um8663f_t; + +static void +um8663f_fdc_handler(um8663f_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0] & 0x01) + fdc_set_base(dev->fdc, (dev->regs[1] & 0x01) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); +} + +static void +um8663f_uart_handler(um8663f_t *dev, int port) +{ + uint8_t shift = (port + 1); + + serial_remove(dev->uart[port]); + if (dev->regs[0] & (2 << port)) { + switch ((dev->regs[1] >> shift) & 0x01) { + case 0x00: + if (port == 1) + serial_setup(dev->uart[port], COM4_ADDR, COM4_IRQ); + else + serial_setup(dev->uart[port], COM3_ADDR, COM1_IRQ); + break; + case 0x01: + if (port == 1) + serial_setup(dev->uart[port], COM2_ADDR, COM2_IRQ); + else + serial_setup(dev->uart[port], COM1_ADDR, COM1_IRQ); + break; + + default: + break; + } + } +} + +static void +um8663f_lpt_handler(um8663f_t *dev) +{ + lpt1_remove(); + if (dev->regs[0] & 0x08) { + switch ((dev->regs[1] >> 3) & 0x01) { + case 0x01: + lpt1_init(LPT1_ADDR); + lpt1_irq(7); + break; + case 0x00: + lpt1_init(LPT2_ADDR); + lpt1_irq(5); + break; + + default: + break; + } + } +} + +static void +um8663f_ide_handler(um8663f_t *dev) +{ + int board = dev->ide - 1; + + if (dev->ide > 0) { + ide_handlers(board, 0); + ide_set_base(board, (dev->regs[1] & 0x10) ? 0x01f0 : 0x0170); + ide_set_side(board, (dev->regs[1] & 0x10) ? 0x03f6 : 0x0376); + if (dev->regs[0] & 0x10) + ide_handlers(board, 1); + } +} + +static void +um8663f_write(uint16_t port, uint8_t val, void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + uint8_t valxor; + + um8663f_log("UM8663F: write(%04X, %02X)\n", port, val); + + if (dev->locked) { + if ((port == 0x108) && (val == 0xaa)) + dev->locked = 0; + } else { + if (port == 0x108) { + if (val == 0x55) + dev->locked = 1; + else + dev->cur_reg = val; + } else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + valxor = (dev->regs[dev->cur_reg - 0xc0] ^ val); + dev->regs[dev->cur_reg - 0xc0] = val; + switch (dev->cur_reg - 0xc0) { + /* Port enable register. */ + case 0x00: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + /* + Port configuration register: + - Bits 7, 6: + - 0, 0 = LPT 1 is none; + - 0, 1 = LPT 1 is EPP; + - 1, 0 = LPT 1 is SPP; + - 1, 1 = LPT 1 is ECP; + - Bit 4 = 0 = IDE is secondary, 1 = IDE is primary; + - Bit 3 = 0 = LPT 1 is 278h, 1 = LPT 1 is 378h; + - Bit 2 = 0 = UART 2 is COM4, 1 = UART 2 is COM2; + - Bit 1 = 0 = UART 1 is COM3, 1 = UART 2 is COM1; + - Bit 0 = 0 = FDC is 370h, 1 = UART 2 is 3f0h. + */ + case 0x01: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + } + } + } +} + +static uint8_t +um8663f_read(uint16_t port, void *priv) +{ + const um8663f_t *dev = (um8663f_t *) priv; + uint8_t ret = 0xff; + + if (!dev->locked) { + if (port == 0x108) + ret = dev->cur_reg; /* ??? */ + else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + ret = dev->regs[dev->cur_reg - 0xc0]; + if (dev->cur_reg == 0xc0) + ret = (ret & 0x1f) | ((random_generate() & 0x07) << 5); + } + } + + um8663f_log("UM8663F: read(%04X) = %02X\n", port, ret); + + return ret; +} + +static void +um8663f_reset(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + + lpt1_remove(); + lpt1_init(LPT1_ADDR); + + fdc_reset(dev->fdc); + fdc_remove(dev->fdc); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x00] = (dev->ide > 0) ? 0x1f : 0x0f; + dev->regs[0x01] = (dev->ide == 2) ? 0x0f : 0x1f; + + um8663f_fdc_handler(dev); + um8663f_uart_handler(dev, 0); + um8663f_uart_handler(dev, 1); + um8663f_lpt_handler(dev); + um8663f_ide_handler(dev); + + dev->locked = 1; +} + +static void +um8663f_close(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + free(dev); +} + +static void * +um8663f_init(UNUSED(const device_t *info)) +{ + um8663f_t *dev = (um8663f_t *) calloc(1, sizeof(um8663f_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->ide = info->local & 0xff; + if (dev->ide < IDE_BUS_MAX) + device_add(&ide_isa_device); + + dev->max_reg = info->local >> 8; + + io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + + um8663f_reset(dev); + + return dev; +} + +const device_t um8663af_device = { + .name = "UMC UM8663AF Super I/O", + .internal_name = "um8663af", + .flags = 0, + .local = 0xc300, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_device = { + .name = "UMC UM8663AF Super I/O (With IDE)", + .internal_name = "um8663af_ide", + .flags = 0, + .local = 0xc301, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_sec_device = { + .name = "UMC UM8663AF Super I/O (With Secondary IDE)", + .internal_name = "um8663af_ide_sec", + .flags = 0, + .local = 0xc302, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_device = { + .name = "UMC UM8663BF Super I/O", + .internal_name = "um8663bf", + .flags = 0, + .local = 0xc400, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_device = { + .name = "UMC UM8663BF Super I/O (With IDE)", + .internal_name = "um8663bf_ide", + .flags = 0, + .local = 0xc401, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_sec_device = { + .name = "UMC UM8663BF Super I/O (With Secondary IDE)", + .internal_name = "um8663bf_ide_sec", + .flags = 0, + .local = 0xc402, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index e83d4593f..bf27a700a 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4132,7 +4132,11 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else + romfn = BIOS_GD5436_PATH; break; case CIRRUS_ID_CLGD5430: @@ -5148,6 +5152,20 @@ const device_t gd5434_pci_device = { .config = gd5434_config }; +const device_t gd5436_onboard_pci_device = { + .name = "Cirrus Logic GD5436 (PCI) (On-Board)", + .internal_name = "cl_gd5436_onboard_pci", + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5436 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config +}; + const device_t gd5436_pci_device = { .name = "Cirrus Logic GD5436 (PCI)", .internal_name = "cl_gd5436_pci", diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 86159ed0a..490c724ce 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -3155,7 +3155,7 @@ tgui_init(const device_t *info) break; case TGUI_9660: case TGUI_9680: - bios_fn = ROM_TGUI_96xx; + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_96xx; break; default: free(tgui); @@ -3402,6 +3402,20 @@ const device_t tgui9660_pci_device = { .config = tgui96xx_config }; +const device_t tgui9660_onboard_pci_device = { + .name = "Trident TGUI 9660XGi On-Board PCI", + .internal_name = "tgui9660_onboard_pci", + .flags = DEVICE_PCI, + .local = TGUI_9660 | ONBOARD, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = tgui_speed_changed, + .force_redraw = tgui_force_redraw, + .config = tgui96xx_config +}; + const device_t tgui9680_pci_device = { .name = "Trident TGUI 9680XGi PCI", .internal_name = "tgui9680_pci", From fcabd353d9bd13a06f008d7be4d689a22ed59da0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 00:56:28 +0100 Subject: [PATCH 140/690] Check IOPL on 286 task segments. --- src/cpu/386_common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 847408ba8..0abf8e936 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1605,8 +1605,12 @@ checkio(uint32_t port, int mask) { uint32_t t; - if (!(tr.access & 0x08)) + if (!(tr.access & 0x08)) { + if ((CPL) > (IOPL)) + return 1; + return 0; + } cpl_override = 1; t = readmemw(tr.base, 0x66); From 8cf8ccf3b3463306ea1edb4d489f5057d5c89c7a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 01:08:21 +0100 Subject: [PATCH 141/690] Added the STB PowerGraph 64 Video (S3 Trio64V+ VLB). --- src/include/86box/video.h | 1 + src/video/vid_s3.c | 36 +++++++++++++++++++++++++++++++++++- src/video/vid_table.c | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 33375f765..65d96a4b6 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -491,6 +491,7 @@ extern const device_t s3_spea_mirage_p64_vlb_device; extern const device_t s3_phoenix_trio64_vlb_device; extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_stb_powergraph_64_video_vlb_device; extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; extern const device_t s3_cardex_trio64vplus_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 0ef48fa0e..46ed8eba0 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -63,6 +63,7 @@ #define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" +#define ROM_STB_POWERGRAPH_64_VIDEO "roms/video/s3/VBIOS.BIN" #define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" #define ROM_CARDEX_TRIO64VPLUS "roms/video/s3/S3T64VP.VBI" #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" @@ -94,6 +95,7 @@ enum { S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, + S3_STB_POWERGRAPH_64_VIDEO, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, S3_CARDEX_TRIO64VPLUS, @@ -3079,7 +3081,8 @@ s3_in(uint16_t addr, void *priv) temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ - if (((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || + if (((s3->card_type == S3_STB_POWERGRAPH_64_VIDEO) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; @@ -9478,6 +9481,7 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: case S3_CARDEX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: @@ -9721,6 +9725,14 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_STB_POWERGRAPH_64_VIDEO: + bios_fn = ROM_STB_POWERGRAPH_64_VIDEO; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; case S3_PHOENIX_TRIO64VPLUS: bios_fn = ROM_PHOENIX_TRIO64VPLUS; chip = S3_TRIO64V; @@ -10181,6 +10193,7 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_CARDEX_TRIO64VPLUS: @@ -10420,6 +10433,12 @@ s3_phoenix_trio64_available(void) return rom_present(ROM_PHOENIX_TRIO64); } +static int +s3_stb_powergraph_64_video_available(void) +{ + return rom_present(ROM_STB_POWERGRAPH_64_VIDEO); +} + static int s3_phoenix_trio64vplus_available(void) { @@ -11063,6 +11082,21 @@ const device_t s3_phoenix_trio64_pci_device = { .config = s3_standard_config }; +const device_t s3_stb_powergraph_64_video_vlb_device = { + .name = "S3 Trio64V+ (STB PowerGraph 64 Video) VLB", + .name = "S3 Trio64V+ PCI (Phoenix)", + .internal_name = "px_trio64vplus_pci", + .flags = DEVICE_VLB, + .local = S3_STB_POWERGRAPH_64_VIDEO, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_stb_powergraph_64_video_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_trio64vplus_onboard_pci_device = { .name = "S3 Trio64V+ PCI On-Board (Phoenix)", .internal_name = "px_trio64vplus_onboard_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 1faa04783..5b9c3f8f3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -254,6 +254,7 @@ video_cards[] = { { &s3_spea_mirage_p64_vlb_device }, { &s3_phoenix_vision968_vlb_device }, { &s3_phoenix_vision868_vlb_device }, + { &s3_stb_powergraph_64_video_vlb_device }, { &ht216_32_standalone_device }, { &tgui9400cxi_device }, { &tgui9440_vlb_device }, From 2fe92a2f26a5d176bc21395b2885fed48af563f8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 12:22:07 +0100 Subject: [PATCH 142/690] Fixed a typo in chipset/umc_8890.c. --- src/chipset/umc_8890.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c index d515e1c97..7de2ca1d0 100644 --- a/src/chipset/umc_8890.c +++ b/src/chipset/umc_8890.c @@ -81,7 +81,7 @@ um8890_shadow(umc_8890_t *dev) if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) { mem_set_mem_state_both(0xe0000, 0x10000, state); - dev->mem_state[1] = (dev->mem_state[2] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); + dev->mem_state[1] = (dev->mem_state[1] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); } flag = (dev->pci_conf[0x5f] & 0xc0) >> 6; From 46fbb3bb9ecbb94ad044dcaf9004cef105500222 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 22 Feb 2024 13:35:04 +0100 Subject: [PATCH 143/690] Video related changes: IBM/ATI 8514/A side: Made mode switches more immediate when actually switching from VGA to 8514/A and viceversa. Tseng ET4000AX/W32 series side: Actually use bit 2 of index 0x3f for the horizontal blank start bit 8 instead of bit 4 (horizontal retrace start), fixes skew issues with the et4000w32i rev B. card with resolutions like 1024x768 at 15 or 16bpp and others. --- src/video/vid_8514a.c | 2 +- src/video/vid_ati_mach8.c | 2 +- src/video/vid_et4000.c | 14 +++++++------- src/video/vid_et4000w32.c | 19 ++++++++----------- src/video/vid_svga.c | 6 +++--- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index a94b974b0..ff1470164 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -4454,7 +4454,7 @@ ibm8514_init(const device_t *info) } #endif - timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); return svga; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b49806177..3888e9c26 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -6057,7 +6057,7 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); - timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); return mach; } diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index fa671e2f6..ae6b7ae82 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -650,22 +650,22 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 1) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 2) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 4) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 8) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (!svga->rowoffset) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) - svga->htotal += 256; + svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 7adb6bc89..39b5b9ecc 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -432,22 +432,22 @@ et4000w32p_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 0x01) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 0x02) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 0x04) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 0x08) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (svga->crtc[0x3F] & 0x80) - svga->rowoffset += 0x100; + svga->rowoffset |= 0x100; if (svga->crtc[0x3F] & 0x01) - svga->htotal += 256; + svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; @@ -535,9 +535,6 @@ et4000w32p_recalctimings(svga_t *svga) } else { switch (svga->gdcreg[5] & 0x60) { case 0x00: - if (et4000->rev == 5) - svga->ma_latch++; - if (svga->seqregs[1] & 8) /* Low res (320) */ svga->render = svga_render_4bpp_lowres; else diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d60a5de0e..cbb7f12e8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -899,7 +899,7 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on[0] || dev->on[1]) { - disptime8514 = dev->htotal; + disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC; _dispontime8514 = dev->hdisped; } } @@ -934,10 +934,10 @@ svga_recalctimings(svga_t *svga) dev->dispofftime = TIMER_USEC; timer_disable(&svga->timer); - timer_enable(&svga->timer8514); + timer_set_delay_u64(&svga->timer8514, TIMER_USEC); } else { timer_disable(&svga->timer8514); - timer_enable(&svga->timer); + timer_set_delay_u64(&svga->timer, TIMER_USEC); } } From 4ee4e8f2b7feb4361127a34c99321d621fa1092e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 06:41:02 +0100 Subject: [PATCH 144/690] Fixed the flags and classification of some SiS machines, closes #4192. --- src/include/86box/machine.h | 3 +- src/machine/m_at_socket7.c | 29 ----------- src/machine/m_at_sockets7.c | 29 +++++++++++ src/machine/machine_table.c | 97 +++++++++++++++++++------------------ 4 files changed, 80 insertions(+), 78 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6817a0de5..e27a70d79 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -732,7 +732,6 @@ extern int machine_at_ms5164_init(const machine_t *); extern int machine_at_sp97xv_init(const machine_t *); extern int machine_at_sq578_init(const machine_t *); -extern int machine_at_5sg100_init(const machine_t *); extern int machine_at_ms5172_init(const machine_t *); /* m_at_sockets7.c */ @@ -747,6 +746,8 @@ extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); +extern int machine_at_5sg100_init(const machine_t *); + /* m_at_socket8.c */ extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 09441ad4f..9ab24b7c2 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1324,35 +1324,6 @@ machine_at_sq578_init(const machine_t *model) return ret; } -int -machine_at_5sg100_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/5sg100/5sg.20g", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); - device_add(&sis_5591_1997_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83877tf_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - int machine_at_ms5172_init(const machine_t *model) { diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 8ff1a367d..32319e160 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -337,3 +337,32 @@ machine_at_5emapro_init(const machine_t *model) return ret; } + +int +machine_at_5sg100_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sg100/5sg.20g", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index beac1cf6e..6251f171f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12349,8 +12349,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -12389,8 +12389,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -12409,49 +12409,8 @@ const machine_t machines[] = { .net_device = NULL }, - /* SiS 5591 */ /* Has the SiS 5591 chipset with on-chip KBC. */ - { - .name = "[SiS 5591] Gigabyte GA-5SG100", - .internal_name = "5sg100", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5591, - .init = machine_at_5sg100_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 786432, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the SiS 5591 chipset with on-chip KBC. */ { .name = "[SiS 5591] MSI MS-5172", .internal_name = "ms5172", @@ -12472,8 +12431,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12944,6 +12903,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ @@ -14412,7 +14413,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_AGP, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, From 6de7c7cd5e5f5144486606143e1615b1c426fb83 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:10:15 +0100 Subject: [PATCH 145/690] Fixed LOCK legality with prefixes, closes #4189. --- src/cpu/386.c | 3 + src/cpu/386_common.c | 50 ++++++++++- src/cpu/808x.c | 2 - src/cpu/cpu.h | 4 + src/cpu/x86.c | 4 + src/cpu/x86_ops_misc.h | 37 +-------- src/cpu/x86_ops_prefix_2386.h | 151 +++++++++++++++++++++++++++++----- 7 files changed, 193 insertions(+), 58 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index ad310d31e..5379dccf9 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -280,7 +280,10 @@ exec386_2386(int32_t cycs) cpu_state.pc++; cpu_state.eflags &= ~(RF_FLAG); + if (opcode == 0xf0) + in_lock = 1; x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + in_lock = 0; if (x86_was_reset) break; } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 0abf8e936..5c1b95e0f 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -123,11 +123,11 @@ int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* /* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */ int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */ - 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x2x */ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 1, 1, 1, 1, 1, 1, 4, 0, 1, 1, 1, 1, 1, 1, 4, 0, /* 0x2x */ + 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, /* 0x3x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ @@ -423,6 +423,50 @@ x386_common_log(const char *fmt, ...) # define x386_common_log(fmt, ...) #endif +int +is_lock_legal(uint32_t fetchdat) +{ + int legal; + fetch_dat_t fetch_dat; + + fetch_dat.fd = fetchdat; + + legal = lock_legal[fetch_dat.b[0]]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal_0f[fetch_dat.b[1]]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; + } + + return legal; +} + /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. - Cycles used for non-instruction memory accesses are counted and subtracted diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 90563d9ab..caff0fa60 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -56,7 +56,6 @@ static uint32_t *opseg[4]; static x86seg *_opseg[4]; static int noint = 0; -static int in_lock = 0; static int cpu_alu_op, pfq_size; static uint32_t cpu_src = 0, cpu_dest = 0; @@ -545,7 +544,6 @@ reset_808x(int hard) { biu_cycles = 0; in_rep = 0; - in_lock = 0; completed = 1; repeating = 0; clear_lock = 0; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 1456d2ee8..16a9eba10 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -829,4 +829,8 @@ extern int lock_legal_80[8]; extern int lock_legal_f6[8]; extern int lock_legal_fe[8]; +extern int in_lock; + +extern int is_lock_legal(uint32_t fetchdat); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 2c8c29d49..cf2867182 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -80,6 +80,8 @@ int hlt_reset_pending; int fpu_cycles = 0; +int in_lock = 0; + #ifdef ENABLE_X86_LOG void dumpregs(int); @@ -351,6 +353,8 @@ reset_common(int hard) if (!is286) reset_808x(hard); + in_lock = 0; + cpu_cpurst_on_sr = 0; } diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index dd05fb9d9..519bdbe3c 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -731,46 +731,15 @@ static int opLOCK(uint32_t fetchdat) { int legal; - fetch_dat_t fetch_dat; fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 0; cpu_state.pc++; - fetch_dat.fd = fetchdat; + legal = is_lock_legal(fetchdat); - legal = lock_legal[fetch_dat.b[0]]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - else if (legal == 2) { - legal = lock_legal_0f[fetch_dat.b[1]]; - if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ - else if (legal == 3) { - legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ - } - } else if (legal == 3) switch(fetch_dat.b[0]) { - case 0x80 ... 0x83: - legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xf6 ... 0xf7: - legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xfe ... 0xff: - legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - default: - legal = 0; - break; - } + if (legal == 4) + pclog("PREFIX: F0 %08X\n", fetchdat); ILLEGAL_ON(legal == 0); diff --git a/src/cpu/x86_ops_prefix_2386.h b/src/cpu/x86_ops_prefix_2386.h index 7c87f0bf3..87d114944 100644 --- a/src/cpu/x86_ops_prefix_2386.h +++ b/src/cpu/x86_ops_prefix_2386.h @@ -1,4 +1,110 @@ #define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) +op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) + // clang-format on + +#define op_srp(name, seg, opcode_table, normal_opcode_table) \ static int op##name##_w_a16(uint32_t fetchdat) \ { \ fetchdat = fastreadl(cs + cpu_state.pc); \ @@ -68,36 +174,36 @@ } // clang-format off -op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) -op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) -op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) +op_srp(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) - -op_seg(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) // clang-format on static int op_66(uint32_t fetchdat) /*Data size select*/ { + int legal; fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); CLOCK_CYCLES(2); PREFETCH_PREFIX(); @@ -106,11 +212,18 @@ op_66(uint32_t fetchdat) /*Data size select*/ static int op_67(uint32_t fetchdat) /*Address size select*/ { + int legal; fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); CLOCK_CYCLES(2); PREFETCH_PREFIX(); From 5c1cdb3c457d8b99d3ac0f65226d4bc3a4e18e85 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:13:02 +0100 Subject: [PATCH 146/690] Bump version to 4.1.1. --- src/include_make/86box/version.h | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 4004f58b3..4bb6c71d7 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -22,12 +22,12 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "4.1" +#define EMU_VERSION "4.1.1" #define EMU_VERSION_W LSTR(EMU_VERSION) #define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 4 #define EMU_VERSION_MIN 1 -#define EMU_VERSION_PATCH 0 +#define EMU_VERSION_PATCH 1 #define EMU_BUILD_NUM 0 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index a7e4786be..99d01c594 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 4.1 +Version: 4.1.1 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Mon Oct 16 2023 Robert de Rooy 4.1-1 +* Fri Feb 23 2024 Robert de Rooy 4.1.1-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 9e2c5dc88..7602ffb11 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + From b55c7b91ddaca9962c060ef6f1d2c8f4100e5a84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:23:52 +0100 Subject: [PATCH 147/690] The forgotten version bumped files. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- vcpkg.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 196952cb4..cacf1aaa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.1 + VERSION 4.1.1 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 29ec6d3af..00179d466 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.1) UNRELEASED; urgency=medium +86box (4.1.1) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Mon, 16 Oct 2023 20:24:46 +0200 + -- Jasmine Iwanek Fri, 23 Feb 2024 07:23:12 +0100 diff --git a/vcpkg.json b/vcpkg.json index 5fdfc175b..d7d7ffd82 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.1", + "version-string": "4.1.1", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From a893aba1caa387f5c0045664f43c762ec38755cb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 14:27:26 +0600 Subject: [PATCH 148/690] S3 ViRGE: Respect blend control compose modes on pre-GX2 ViRGE Fixes video overlay staying on-screen on Linux. --- src/video/vid_s3_virge.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index be6382ec9..9277be24a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -918,6 +918,10 @@ s3_virge_recalctimings(svga_t *svga) svga->overlay.v_acc = virge->streams.dda_vert_accumulator; svga->rowoffset = virge->streams.pri_stride >> 3; + if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { + svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; @@ -1963,6 +1967,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) break; case 0x81a0: virge->streams.blend_ctrl = val; + svga_recalctimings(svga); break; case 0x81c0: virge->streams.pri_fb0 = val & 0x7fffff; From 45dff17d58c578791e0578486a5705cd3e2bed03 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 16:25:50 +0600 Subject: [PATCH 149/690] S3 ViRGE/GX2: Fix screen overlay staying on Windows XP --- src/video/vid_s3_virge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 9277be24a..398284d99 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -920,6 +920,10 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { + /* 0x20 = Secondary Stream enabled */ + /* 0x2000 = Primary Stream enabled */ + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20) && (svga->crtc[0x67] & 0xC); } switch ((virge->streams.pri_ctrl >> 24) & 0x7) { From 181ffbcffb5da1a80ebf4f83662028e39ba31145 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 20:47:27 +0600 Subject: [PATCH 150/690] S3 ViRGE: a bit of cleanup --- src/video/vid_s3_virge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 398284d99..52184d88b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -893,6 +893,7 @@ s3_virge_recalctimings(svga_t *svga) } } svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; + svga->overlay.ena = 0; s3_virge_log("VGA mode\n"); } else /*Streams mode*/ { @@ -923,7 +924,7 @@ s3_virge_recalctimings(svga_t *svga) } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { /* 0x20 = Secondary Stream enabled */ /* 0x2000 = Primary Stream enabled */ - svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20) && (svga->crtc[0x67] & 0xC); + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20); } switch ((virge->streams.pri_ctrl >> 24) & 0x7) { From c57dfed4e7595102a83a6cacab3868544610ccb6 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Fri, 23 Feb 2024 18:41:41 +0300 Subject: [PATCH 151/690] Fix the internal name of the S3 Trio64V+ VLB --- src/video/vid_s3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 46ed8eba0..c526ecf62 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -11084,8 +11084,7 @@ const device_t s3_phoenix_trio64_pci_device = { const device_t s3_stb_powergraph_64_video_vlb_device = { .name = "S3 Trio64V+ (STB PowerGraph 64 Video) VLB", - .name = "S3 Trio64V+ PCI (Phoenix)", - .internal_name = "px_trio64vplus_pci", + .internal_name = "stb_trio64vplus_vlb", .flags = DEVICE_VLB, .local = S3_STB_POWERGRAPH_64_VIDEO, .init = s3_init, From 9124e8165b2f785689c3bc588acf767302665414 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 17:02:42 +0100 Subject: [PATCH 152/690] Removed the incorrect usage of CRTC register 3 bits 5 and 6. --- src/video/vid_et4000.c | 2 +- src/video/vid_svga.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index ae6b7ae82..5fe524fd8 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -745,7 +745,7 @@ et4000_kasan_recalctimings(svga_t *svga) if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { svga->hdisp += svga->dots_per_clock; - svga->ma_latch -= 5; + svga->ma_latch -= 4; svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index cbb7f12e8..b20364689 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1158,9 +1158,9 @@ svga_poll(void *priv) if (ret) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->hblank_sub; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -1230,10 +1230,9 @@ svga_poll(void *priv) svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + - ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; svga->ma = (svga->ma << 2); From 25203be56ad77b709a3cb7736a99fa9088e1e61b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 17:35:54 +0100 Subject: [PATCH 153/690] Change the default hard disk image format to fixed-size VHD. --- src/qt/qt_harddiskdialog.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 9de61c51b..300f1381d 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -55,7 +55,9 @@ private: QStringList filters; // "Dynamic-size VHD" is number 4 in the `filters` list and the // comboBoxFormat model - const uint8_t DEFAULT_DISK_FORMAT = 4; + // Temporary change to fixed-size VHD due to MiniVHD's handling of + // dynamic-size VHD being buggy. + const uint8_t DEFAULT_DISK_FORMAT = 3; bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); From f417a347a6075905402ed4c3dc1918a572811780 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 18:13:52 +0100 Subject: [PATCH 154/690] Revert the default hard disk format change. --- src/qt/qt_harddiskdialog.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 300f1381d..9de61c51b 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -55,9 +55,7 @@ private: QStringList filters; // "Dynamic-size VHD" is number 4 in the `filters` list and the // comboBoxFormat model - // Temporary change to fixed-size VHD due to MiniVHD's handling of - // dynamic-size VHD being buggy. - const uint8_t DEFAULT_DISK_FORMAT = 3; + const uint8_t DEFAULT_DISK_FORMAT = 4; bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); From b49cd0baf42af4ad1dfd7264f869dfa292c53397 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 24 Feb 2024 02:51:42 +0600 Subject: [PATCH 155/690] S3 ViRGE: Buffer flips no longer trigger recalctimings --- src/video/vid_s3_virge.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 52184d88b..a4cec9c09 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -835,6 +835,7 @@ s3_virge_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; + video_force_resize_set_monitor(1, svga->monitor_index); } else { svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; @@ -959,6 +960,27 @@ s3_virge_recalctimings(svga_t *svga) } } +static void +s3_virge_update_buffer(virge_t *virge) +{ + svga_t *svga = &virge->svga; + + if ((svga->crtc[0x67] & 0xc) != 0xc) + return; + + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->rowoffset = virge->streams.pri_stride >> 3; +} + static void s3_virge_updatemapping(virge_t *virge) { @@ -1976,37 +1998,36 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) break; case 0x81c0: virge->streams.pri_fb0 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c4: virge->streams.pri_fb1 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c8: virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81cc: virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d0: virge->streams.sec_fb0 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d4: virge->streams.sec_fb1 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d8: virge->streams.sec_stride = val; - svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81dc: From 1d2f8937b76803e964798956177bd602a0bf1810 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Feb 2024 04:57:35 +0100 Subject: [PATCH 156/690] SiS 5581 machines are not supposed to support AGP. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 6251f171f..da3dc01e4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12349,7 +12349,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12389,7 +12389,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, From 6b435088f9dd3cdd70d2a33f4aca12ee6a3d36fd Mon Sep 17 00:00:00 2001 From: rilysh Date: Sat, 24 Feb 2024 13:59:14 +0530 Subject: [PATCH 157/690] unix_serial_passthrough.c: check errno for EWOULDBLOCK plat_serpt_write_vcon(): write() returns how much data it has written to the file descriptor, and in case an error, it returns -1. So the EWOULDBLOCK never really triggers, as in the following condition we're not checking the errno, but the return value of the write() function. --- src/unix/unix_serial_passthrough.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index d80f8a1e7..646b77d6c 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -112,7 +112,7 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) if (dev->mode == SERPT_MODE_HOSTSER) { do { res = write(dev->master_fd, &data, 1); - } while (res == 0 || (res == -1 && (errno == EAGAIN || res == EWOULDBLOCK))); + } while (res == 0 || (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); } else res = write(dev->master_fd, &data, 1); } From 52ffbe582fe5a252bc07d02996c21366a3c95423 Mon Sep 17 00:00:00 2001 From: AsciiWolf Date: Sat, 24 Feb 2024 14:08:26 +0100 Subject: [PATCH 158/690] Fix AppStream metainfo file --- src/unix/assets/net.86box.86Box.metainfo.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 7602ffb11..1f15f39a5 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -4,9 +4,10 @@ CC0-1.0 GPL-2.0-or-later 86Box + 86Box developers An emulator for classic IBM PC clones - Emulation + Emulator net.86box.86Box.desktop From 1dfb6fd111482173f43f44941545ffe240a434ed Mon Sep 17 00:00:00 2001 From: rilysh Date: Sat, 24 Feb 2024 23:19:32 +0530 Subject: [PATCH 159/690] bswap.h: fix GCC requirements for bswap* builtins 1. __builtin_bswap{32,64} were added in GCC 4.3, and __builtin_bswap16 was added in GCC 4.8, however, currently, the GCC requirements in bswap.h file has >= 10. This requirement of GCC version is false for bswap* but true for __has_builtin() (as it first was added in GCC 10.1). As bswap* builtins were added before GCC 10, the preprocessor check will always going to be true for bswap but will be false if GCC version is < 10 as __has_builtin() won't be present. Since the byteswap function, on x86-64, can boil down to a single bswap instruction, this optimization may left behind (unless GCC do some pattern matching). To avoid this, just use the compiler macros (for GCC: __GNUC__, clang: __GNUC__ or __clang__) and if the compiler is neither GCC or Clang, fall-back to native implementation. 2. Remove the useless casts (uint{16,32,64}_t) from the constants. These constants already has their own suffix, and casting to a different type will just get ignored as the return value already gets casts to it's appropriate type. 3. Previously, Clang couldn't able to use __builtin_bswap* (even if it was newer) as LLVM define __GNUC__ macro to a specific constant (usually lower than GCC's (__GNUC__) and on my system it's 4) which is indeed < 10. The first comment also fixes this issue. Link: Link: Link: --- src/include/86box/bswap.h | 94 ++++++++++++--------------------------- 1 file changed, 28 insertions(+), 66 deletions(-) diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index ac758b20a..78183d137 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -40,91 +40,55 @@ #include -#ifdef HAVE_BYTESWAP_H -# include -#else -# define bswap_16(x) \ - ( \ - ((uint16_t)( \ - (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \ - ) +#define bswap_16(x) \ + ((uint16_t)((((x) & 0x00ffu) << 8) | \ + (((x) & 0xff00u) >> 8))) -# define bswap_32(x) \ - ( \ - ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \ - ) +#define bswap_32(x) \ + ((uint32_t)((((x) & 0x000000fful) << 24) | \ + (((x) & 0x0000ff00ul) << 8) | \ + (((x) & 0x00ff0000ul) >> 8) | \ + (((x) & 0xff000000ul) >> 24))) -# define bswap_64(x) \ - ( \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \ - ) -#endif /*HAVE_BYTESWAP_H*/ +# define bswap_64(x) \ + ((uint64_t)((((x) & 0x00000000000000ffull) << 56) | \ + (((x) & 0x000000000000ff00ull) << 40) | \ + (((x) & 0x0000000000ff0000ull) << 24) | \ + (((x) & 0x00000000ff000000ull) << 8) | \ + (((x) & 0x000000ff00000000ull) >> 8) | \ + (((x) & 0x0000ff0000000000ull) >> 24) | \ + (((x) & 0x00ff000000000000ull) >> 40) | \ + (((x) & 0xff00000000000000ull) >> 56))) -#if __GNUC__ >= 10 -#if defined __has_builtin && __has_builtin(__builtin_bswap16) -#define bswap16(x) __builtin_bswap16(x) -#else -static __inline uint16_t bswap16(uint16_t x) -{ - return bswap_16(x); -} -# endif -#else static __inline uint16_t bswap16(uint16_t x) { +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap16(x); +#else return bswap_16(x); -} #endif +} -#if __GNUC__ >= 10 -# if defined __has_builtin && __has_builtin(__builtin_bswap32) -# define bswap32(x) __builtin_bswap32(x) -# else static __inline uint32_t bswap32(uint32_t x) { - return bswap_32(x); -} -# endif +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap32(x); #else -static __inline uint32_t -bswap32(uint32_t x) -{ return bswap_32(x); -} #endif +} -#if __GNUC__ >= 10 -# if defined __has_builtin && __has_builtin(__builtin_bswap64) -# define bswap64(x) __builtin_bswap64(x) -# else static __inline uint64_t bswap64(uint64_t x) { - return bswap_64(x); -} -# endif +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap64(x); #else -static __inline uint64_t -bswap64(uint64_t x) -{ - return bswap_64(x); -} + return bswap_16(x); #endif +} static __inline void bswap16s(uint16_t *s) @@ -198,12 +162,10 @@ CPU_CONVERT(le, 64, uint64_t) /* unaligned versions (optimized for frequent unaligned accesses)*/ #if defined(__i386__) || defined(__powerpc__) - # define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) # define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) # define le16_to_cpupu(p) le16_to_cpup(p) # define le32_to_cpupu(p) le32_to_cpup(p) - # define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) # define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) From 21230f933ebd4eafc9aeb375d93676b478716364 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 24 Feb 2024 21:50:01 +0100 Subject: [PATCH 160/690] Temporary solution to a 24bpp issue and hblank. So that 24bpp color is not discolored anymore as well as hblank bugs being nulled. --- src/video/vid_s3_virge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index a4cec9c09..2c740819b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -958,13 +958,15 @@ s3_virge_recalctimings(svga_t *svga) } svga->vram_display_mask = virge->vram_mask; } + + svga->hoverride = 1 } static void s3_virge_update_buffer(virge_t *virge) { svga_t *svga = &virge->svga; - + if ((svga->crtc[0x67] & 0xc) != 0xc) return; @@ -977,7 +979,7 @@ s3_virge_update_buffer(virge_t *virge) svga->overlay.addr = virge->streams.sec_fb1; else svga->overlay.addr = virge->streams.sec_fb0; - + svga->rowoffset = virge->streams.pri_stride >> 3; } From c00e854fce92c132dc802c8919e1a7d45001d174 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 24 Feb 2024 21:52:06 +0100 Subject: [PATCH 161/690] Fix compile. See above. --- src/video/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 2c740819b..56ddcec46 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -959,7 +959,7 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = virge->vram_mask; } - svga->hoverride = 1 + svga->hoverride = 1; } static void From 868beac26e80c53ecf776ddbdc6717e070d36e38 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 17:58:58 -0500 Subject: [PATCH 162/690] Add 86BoxManagerX to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 370bc940e..d56cbf19f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Performance may vary depending on both host and guest configuration. Most emulat It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines. * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) +* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) From cf0e4edbb76a57f66a0cf934e95c0d5adeb55ad4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 18:00:49 -0500 Subject: [PATCH 163/690] Add sl86 to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d56cbf19f..ff98742e1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) +* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python) * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) From 31a5aad0f25100f1963026808ccad96f5f6fc480 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 18:01:55 -0500 Subject: [PATCH 164/690] Link to Dungeonseekers github in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff98742e1..b4b4142be 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) * [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python) -* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) +* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option. From f6c66248e0f5f79e186bef9b34d86dc57d56e17b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Feb 2024 08:13:45 +0100 Subject: [PATCH 165/690] Moved the FDC FIFO implementation to fifo.c/h, fixes a few length masking bugs in fifo.c, and fixed FDC MSR register RQM bit behavior in DMA mode, which makes 386BSD work, fixes #530. --- src/fifo.c | 8 +-- src/floppy/fdc.c | 127 ++++++++++++++++------------------------ src/include/86box/fdc.h | 6 +- 3 files changed, 59 insertions(+), 82 deletions(-) diff --git a/src/fifo.c b/src/fifo.c index 72084e11b..f51809fd8 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -72,7 +72,7 @@ fifo_write(uint8_t val, void *priv) fifo->overrun = 1; else { fifo->buf[fifo->end] = val; - fifo->end = (fifo->end + 1) & 0x0f; + fifo->end = (fifo->end + 1) % fifo->len; if (fifo->end == fifo->start) fifo->full = 1; @@ -99,7 +99,7 @@ fifo_write_evt(uint8_t val, void *priv) fifo->d_overrun_evt(fifo->priv); } else { fifo->buf[fifo->end] = val; - fifo->end = (fifo->end + 1) & 0x0f; + fifo->end = (fifo->end + 1) % fifo->len; if (fifo->end == fifo->start) { fifo->d_full = (fifo->full != 1); @@ -131,7 +131,7 @@ fifo_read(void *priv) if (!fifo->empty) { ret = fifo->buf[fifo->start]; - fifo->start = (fifo->start + 1) & 0x0f; + fifo->start = (fifo->start + 1) % fifo->len; fifo->full = 0; @@ -160,7 +160,7 @@ fifo_read_evt(void *priv) if (!fifo->empty) { ret = fifo->buf[fifo->start]; - fifo->start = (fifo->start + 1) & 0x0f; + fifo->start = (fifo->start + 1) % fifo->len; fifo->d_full = (fifo->full != 0); fifo->full = 0; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index f30d86168..8f8fd404e 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -38,6 +38,7 @@ #include <86box/fdc_ext.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#include <86box/fifo.h> extern uint64_t motoron[FDD_NUM]; @@ -78,6 +79,7 @@ int floppyrate[4]; int fdc_type = 0; +// #define ENABLE_FDC_LOG 1 #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -309,7 +311,7 @@ fdc_request_next_sector_id(fdc_t *fdc) fdc->stat = 0xf0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0xd0; + fdc->stat = 0x50; } } @@ -337,39 +339,6 @@ fdc_get_format_sectors(fdc_t *fdc) return (int) fdc->format_sectors; } -static void -fdc_reset_fifo_buf(fdc_t *fdc) -{ - memset(fdc->fifobuf, 0, 16); - fdc->fifobufpos = 0; -} - -static void -fdc_fifo_buf_advance(fdc_t *fdc) -{ - if (fdc->fifobufpos == fdc->tfifo) - fdc->fifobufpos = 0; - else - fdc->fifobufpos++; -} - -static void -fdc_fifo_buf_write(fdc_t *fdc, uint8_t val) -{ - fdc->fifobuf[fdc->fifobufpos] = val; - fdc_fifo_buf_advance(fdc); -} - -static int -fdc_fifo_buf_read(fdc_t *fdc) -{ - int temp = fdc->fifobuf[fdc->fifobufpos]; - fdc_fifo_buf_advance(fdc); - if (!fdc->fifobufpos) - fdc->data_ready = 0; - return temp; -} - static void fdc_int(fdc_t *fdc, int set_fintr) { @@ -669,7 +638,7 @@ fdc_io_command_phase1(fdc_t *fdc, int out) pclog_toggle_suppr(); #endif - fdc_reset_fifo_buf(fdc); + fifo_reset(fdc->fifo_p); fdc_rate(fdc, fdc->drive); fdc->head = fdc->params[2]; fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); @@ -687,7 +656,7 @@ fdc_io_command_phase1(fdc_t *fdc, int out) } ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1); - fdc->stat = out ? 0x90 : 0x50; + fdc->stat = out ? 0x10 : 0x50; if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat |= 0x20; else @@ -825,8 +794,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->dat = val; fdc->stat &= ~0x80; } else { - fdc_fifo_buf_write(fdc, val); - if (fdc->fifobufpos == 0) + fifo_write(val, fdc->fifo_p); + if (fifo_get_full(fdc->fifo_p)) fdc->stat &= ~0x80; } break; @@ -849,7 +818,11 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_log("Starting FDC command %02X\n", fdc->command); fdc->error = 0; - if (((fdc->command & 0x1f) == 0x02) || ((fdc->command & 0x1f) == 0x05) || ((fdc->command & 0x1f) == 0x06) || ((fdc->command & 0x1f) == 0x0a) || ((fdc->command & 0x1f) == 0x0c) || ((fdc->command & 0x1f) == 0x0d) || ((fdc->command & 0x1f) == 0x11) || ((fdc->command & 0x1f) == 0x16) || ((fdc->command & 0x1f) == 0x19) || ((fdc->command & 0x1f) == 0x1d)) + if (((fdc->command & 0x1f) == 0x02) || ((fdc->command & 0x1f) == 0x05) || + ((fdc->command & 0x1f) == 0x06) || ((fdc->command & 0x1f) == 0x0a) || + ((fdc->command & 0x1f) == 0x0c) || ((fdc->command & 0x1f) == 0x0d) || + ((fdc->command & 0x1f) == 0x11) || ((fdc->command & 0x1f) == 0x16) || + ((fdc->command & 0x1f) == 0x19) || ((fdc->command & 0x1f) == 0x1d)) fdc->processed_cmd = fdc->command & 0x1f; else fdc->processed_cmd = fdc->command; @@ -997,6 +970,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } if (fdc->pnum == fdc->ptot) { fdc_log("Got all params %02X\n", fdc->command); + fifo_reset(fdc->fifo_p); fdc->interrupt = fdc->processed_cmd; fdc->reset_stat = 0; /* Disable timer if enabled. */ @@ -1386,11 +1360,11 @@ fdc_read(uint16_t addr, void *priv) fdc->data_ready = 0; ret = fdc->dat; } else - ret = fdc_fifo_buf_read(fdc); + ret = fifo_read(fdc->fifo_p); break; } - fdc->stat &= ~0x80; if (fdc->paramstogo) { + fdc->stat &= ~0x80; fdc_log("%i parameters to go\n", fdc->paramstogo); fdc->paramstogo--; ret = fdc->res[10 - fdc->paramstogo]; @@ -1398,7 +1372,11 @@ fdc_read(uint16_t addr, void *priv) fdc->stat = 0x80; else fdc->stat |= 0xC0; + } else if (fdc->dma) { + ret = fdc->dat; + break; } else { + fdc->stat &= ~0x80; if (lastbyte) fdc->stat = 0x80; lastbyte = 0; @@ -1689,7 +1667,7 @@ fdc_callback(void *priv) fdc->stat = 0xb0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } break; case 6: @@ -1711,7 +1689,7 @@ fdc_callback(void *priv) fdc->stat = 0xb0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } break; @@ -1802,6 +1780,9 @@ fdc_callback(void *priv) fdc->pretrk = fdc->params[2]; fdc->fifo = (fdc->params[1] & 0x20) ? 0 : 1; fdc->tfifo = (fdc->params[1] & 0xF); + fifo_reset(fdc->fifo_p); + fifo_set_len(fdc->fifo_p, fdc->tfifo + 1); + fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1); fdc->stat = 0x80; return; case 0x14: /*Unlock*/ @@ -1928,7 +1909,6 @@ int fdc_data(fdc_t *fdc, uint8_t data, int last) { int result = 0; - int n; if (fdc->deleted & 2) { /* We're in a VERIFY command, so return with 0. */ @@ -1950,8 +1930,8 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) fdc->stat = 0xf0; } else { /* FIFO enabled */ - fdc_fifo_buf_write(fdc, data); - if (fdc->fifobufpos == 0) { + fifo_write(data, fdc->fifo_p); + if (fifo_get_full(fdc->fifo_p)) { /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; fdc->stat = 0xf0; @@ -1963,11 +1943,10 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) if (!fdc->fifo || (fdc->tfifo < 1)) { fdc->data_ready = 1; - fdc->stat = 0xd0; + fdc->stat = 0x50; dma_set_drq(fdc->dma_ch, 1); - fdc->fifobufpos = 0; - + fdc->dat = data; result = dma_channel_write(fdc->dma_ch, data); if (result & DMA_OVER) { @@ -1978,19 +1957,15 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) dma_set_drq(fdc->dma_ch, 0); } else { /* FIFO enabled */ - fdc_fifo_buf_write(fdc, data); - if (last || (fdc->fifobufpos == 0)) { + fifo_write(data, fdc->fifo_p); + if (last || fifo_get_full(fdc->fifo_p)) { /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; - fdc->stat = 0xd0; + fdc->stat = 0x50; dma_set_drq(fdc->dma_ch, 1); - n = (fdc->fifobufpos > 0) ? (fdc->fifobufpos - 1) : fdc->tfifo; - if (fdc->fifobufpos > 0) - fdc->fifobufpos = 0; - - for (int i = 0; i <= n; i++) { - result = dma_channel_write(fdc->dma_ch, fdc->fifobuf[i]); + while (!fifo_get_empty(fdc->fifo_p)) { + result = dma_channel_write(fdc->dma_ch, fifo_read(fdc->fifo_p)); if (result & DMA_OVER) { dma_set_drq(fdc->dma_ch, 0); @@ -2101,9 +2076,9 @@ fdc_getdata(fdc_t *fdc, int last) if (!last) fdc->stat = 0xb0; } else { - data = fdc_fifo_buf_read(fdc); + data = fifo_read(fdc->fifo_p); - if (!last && (fdc->fifobufpos == 0)) + if (!last && fifo_get_empty(fdc->fifo_p)) fdc->stat = 0xb0; } } else { @@ -2115,14 +2090,14 @@ fdc_getdata(fdc_t *fdc, int last) fdc->tc = 1; if (!last) { - fdc->stat = 0x90; dma_set_drq(fdc->dma_ch, 1); + fdc->stat = 0x10; } } else { - if (fdc->fifobufpos == 0) { - for (int i = 0; i <= fdc->tfifo; i++) { + if (fifo_get_empty(fdc->fifo_p)) { + while (!fifo_get_full(fdc->fifo_p)) { data = dma_channel_read(fdc->dma_ch); - fdc->fifobuf[i] = data; + fifo_write(data, fdc->fifo_p); if (data & DMA_OVER) { dma_set_drq(fdc->dma_ch, 0); @@ -2133,11 +2108,11 @@ fdc_getdata(fdc_t *fdc, int last) dma_set_drq(fdc->dma_ch, 0); } - data = fdc_fifo_buf_read(fdc); + data = fifo_read(fdc->fifo_p); - if (!last && (fdc->fifobufpos == 0)) { + if (!last && fifo_get_empty(fdc->fifo_p)) { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } } } @@ -2335,15 +2310,14 @@ fdc_reset(void *priv) fdc->max_track = (fdc->flags & FDC_FLAG_MORE_TRACKS) ? 85 : 79; fdc_remove(fdc); - if (fdc->flags & FDC_FLAG_SEC) { + if (fdc->flags & FDC_FLAG_SEC) fdc_set_base(fdc, FDC_SECONDARY_ADDR); - } else if (fdc->flags & FDC_FLAG_TER) { + else if (fdc->flags & FDC_FLAG_TER) fdc_set_base(fdc, FDC_TERTIARY_ADDR); - } else if (fdc->flags & FDC_FLAG_QUA) { + else if (fdc->flags & FDC_FLAG_QUA) fdc_set_base(fdc, FDC_QUATERNARY_ADDR); - } else { + else fdc_set_base(fdc, (fdc->flags & FDC_FLAG_PCJR) ? FDC_PRIMARY_PCJR_ADDR : FDC_PRIMARY_ADDR); - } current_drive = 0; @@ -2358,10 +2332,11 @@ fdc_close(void *priv) { fdc_t *fdc = (fdc_t *) priv; - fdc_reset(fdc); - /* Stop timers. */ - fdc->watchdog_count = 0; + timer_disable(&fdc->watchdog_timer); + timer_disable(&fdc->timer); + + fifo_close(fdc->fifo_p); free(fdc); } @@ -2396,6 +2371,8 @@ fdc_init(const device_t *info) fdc_log("FDC added: %04X (flags: %08X)\n", fdc->base_address, fdc->flags); + fdc->fifo_p = (void *) fifo16_init(); + timer_add(&fdc->timer, fdc_callback, fdc, 0); d86f_set_fdc(fdc); diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 09c9c4578..37c992a1b 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -115,14 +115,12 @@ typedef struct fdc_t { uint8_t rw_drive; uint8_t lock; + uint8_t specify[2]; - uint8_t res[11]; - uint8_t eot[4]; uint8_t rwc[4]; uint8_t params[8]; - uint8_t fifobuf[16]; uint16_t pcn[4]; @@ -145,6 +143,8 @@ typedef struct fdc_t { int drvrate[4]; + void *fifo_p; + sector_id_t read_track_sector; sector_id_t format_sector_id; From a0ef980a2cef663f21b7b7c8823c9bfd9223cc25 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 25 Feb 2024 14:20:39 +0600 Subject: [PATCH 166/690] S3 ViRGE/GX2: Fix frozen display when stream processors are enabled --- src/video/vid_s3_virge.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 56ddcec46..4d64dffbd 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -842,9 +842,11 @@ s3_virge_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); svga->hblank_end_mask = 0x7f; + video_force_resize_set_monitor(1, svga->monitor_index); } - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ + /* ViRGE/GX2 and later does not use primary stream registers. */ + if ((svga->crtc[0x67] & 0xc) != 0xc || virge->chip >= S3_VIRGEGX2) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) @@ -896,6 +898,22 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; svga->overlay.ena = 0; s3_virge_log("VGA mode\n"); + if (virge->chip >= S3_VIRGEGX2 && (svga->crtc[0x67] & 0xc) == 0xc) { + /* ViRGE/GX2 and later does not use primary stream registers. */ + svga->overlay.x = virge->streams.sec_x; + svga->overlay.y = virge->streams.sec_y; + svga->overlay.cur_ysize = virge->streams.sec_h; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->overlay.ena = (svga->overlay.x >= 0) && !!(virge->streams.blend_ctrl & 0x20); + svga->overlay.v_acc = virge->streams.dda_vert_accumulator; + svga->rowoffset = virge->streams.pri_stride >> 3; + svga->vram_display_mask = virge->vram_mask; + } } else /*Streams mode*/ { if (virge->streams.buffer_ctrl & 1) @@ -970,10 +988,12 @@ s3_virge_update_buffer(virge_t *virge) if ((svga->crtc[0x67] & 0xc) != 0xc) return; - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; + if (virge->chip < S3_VIRGEGX2) { + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + } if (virge->streams.buffer_ctrl & 2) svga->overlay.addr = virge->streams.sec_fb1; From c13272ec48bb9860105cbd359428080b22f51111 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 25 Feb 2024 14:06:25 +0100 Subject: [PATCH 167/690] S3 80x cursor fixes: 1. The SPEA specific cards using the 801/5 chip apparently have an ID that's not 0xa0, rather, they either use 0xa2 or greater for the stepping. Fixes wrong colors in 800x600 modes and greater in 8bpp mode. 2. HWCursor addresses for 8bpp are now properly implemented if the 8bpp mode bit (CRTC3a bit 4) is checked, no longer relaying on GDCREG5 bit 6). Fixes garbage cursor in the SPEA 80x cards drivers (BigWin) using 8bpp mode. --- src/video/vid_s3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index c526ecf62..fe06f05f5 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2128,8 +2128,8 @@ s3_vblank_start(svga_t *svga) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { - if ((svga->gdcreg[5] & 0x60) >= 0x40) + if ((svga->bpp == 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { + if (svga->crtc[0x3a] & 0x10) return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300; @@ -10002,14 +10002,14 @@ s3_init(const device_t *info) case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ + stepping = 0xa2; /*86C801/86C805*/ s3->id = stepping; s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att490_ramdac_device); + svga->ramdac = device_add(&att491_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; From 74e9bcd0844fcee308688d7f2f9c39cdba665977 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 03:15:44 +0600 Subject: [PATCH 168/690] Add Novell NetWare 2.x Card Key emulation --- src/86box.c | 4 + src/config.c | 12 ++- src/device/CMakeLists.txt | 3 +- src/device/novell_cardkey.c | 115 +++++++++++++++++++++++++ src/include/86box/86box.h | 1 + src/include/86box/novell_cardkey.h | 37 ++++++++ src/qt/qt_settingsotherperipherals.cpp | 24 +++++- src/qt/qt_settingsotherperipherals.hpp | 4 + src/qt/qt_settingsotherperipherals.ui | 70 +++++++++++---- 9 files changed, 244 insertions(+), 26 deletions(-) create mode 100644 src/device/novell_cardkey.c create mode 100644 src/include/86box/novell_cardkey.h diff --git a/src/86box.c b/src/86box.c index 8218c208c..9e3bc9dca 100644 --- a/src/86box.c +++ b/src/86box.c @@ -66,6 +66,7 @@ #include <86box/bugger.h> #include <86box/postcard.h> #include <86box/unittester.h> +#include <86box/novell_cardkey.h> #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/lpt.h> @@ -173,6 +174,7 @@ char video_shader[512] = { '\0' }; /* (C) video * bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of pass-through for serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ +int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */ int postcard_enabled = 0; /* (C) enable POST card */ int unittester_enabled = 0; /* (C) enable unit tester device */ int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */ @@ -1226,6 +1228,8 @@ pc_reset_hard_init(void) device_add(&postcard_device); if (unittester_enabled) device_add(&unittester_device); + if (novell_keycard_enabled) + device_add(&novell_keycard_device); if (IS_ARCH(machine, MACHINE_BUS_PCI)) { pci_register_cards(); diff --git a/src/config.c b/src/config.c index 3e4fd7222..e4a86d7bd 100644 --- a/src/config.c +++ b/src/config.c @@ -1568,9 +1568,10 @@ load_other_peripherals(void) char *p; char temp[512]; - bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); - postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); - unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); + bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); + postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); + novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0); for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -2365,6 +2366,11 @@ save_other_peripherals(void) else ini_section_set_int(cat, "unittester_enabled", unittester_enabled); + if (novell_keycard_enabled == 0) + ini_section_delete_var(cat, "novell_keycard_enabled"); + else + ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled); + for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 9c5705325..c0719af2a 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -22,7 +22,8 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h kbc_at.c kbc_at_dev.c keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c - serial_passthrough.c) + serial_passthrough.c + novell_cardkey.c) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_link_libraries(86Box atomic) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c new file mode 100644 index 000000000..ad3f0a5ea --- /dev/null +++ b/src/device/novell_cardkey.c @@ -0,0 +1,115 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Novell NetWare 2.x Key Card, which + * was used for anti-piracy protection. + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345. + */ + +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/novell_cardkey.h> + +typedef struct novell_cardkey_t +{ + char serial_number_str[13]; +} novell_cardkey_t; + +static uint8_t +novell_cardkey_read(uint16_t port, void *priv) +{ + novell_cardkey_t* cardkey = (novell_cardkey_t*)priv; + uint8_t val = 0x00; + switch (port) { + case 0x23A: + val = ((cardkey->serial_number_str[11] - '0') << 4) | ((cardkey->serial_number_str[9] - '0')); + break; + case 0x23B: + val = ((cardkey->serial_number_str[10] - '0') << 4) | ((cardkey->serial_number_str[8] - '0')); + break; + + case 0x23C: + val = ((cardkey->serial_number_str[4] - '0') << 4) | ((cardkey->serial_number_str[2] - '0')); + break; + case 0x23D: + val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0')); + break; + case 0x23E: + val = ((cardkey->serial_number_str[0] - '0') << 4) | ((cardkey->serial_number_str[7] - '0')); + break; + case 0x23F: + val = ((cardkey->serial_number_str[3] - '0') << 4) | ((cardkey->serial_number_str[5] - '0')); + break; + } + return val ^ 0xFF; +} + +void* novell_cardkey_init(const device_t* info) +{ + char sernumstr[13] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 0 }; + int i = 0; + novell_cardkey_t* cardkey = calloc(1, sizeof(novell_cardkey_t)); + + strncpy(sernumstr, device_get_config_string("serial_number"), sizeof(sernumstr) - 1); + + for (i = 0; i < sizeof(sernumstr); i++) { + if (sernumstr[i] > '8' || sernumstr[i] < '0') + sernumstr[i] = '0'; + } + sernumstr[12] = 0; + strncpy(cardkey->serial_number_str, sernumstr, sizeof(sernumstr)); + io_sethandler(NOVELL_KEYCARD_ADDR, NOVELL_KEYCARD_ADDRLEN, novell_cardkey_read, NULL, NULL, NULL, NULL, NULL, cardkey); + return cardkey; +} + +void novell_cardkey_close(void* priv) +{ + free(priv); +} + +static const device_config_t keycard_config[] = { + // clang-format off + { + .name = "serial_number", + .description = "Serial Number", + .type = CONFIG_STRING, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { 0 } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t novell_keycard_device = { + .name = "Novell Netware 2.x Key Card", + .internal_name = "mssystems", + .flags = DEVICE_ISA, + .local = 0, + .init = novell_cardkey_init, + .close = novell_cardkey_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = keycard_config +}; \ No newline at end of file diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 20f3fffcc..8a11cc610 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -124,6 +124,7 @@ extern int video_framerate; /* (C) video */ extern int gfxcard[2]; /* (C) graphics/video card */ extern char video_shader[512]; /* (C) video */ extern int bugger_enabled; /* (C) enable ISAbugger */ +extern int novell_keycard_enabled; /* (C) enable Novell NetWare 2.x key card emulation. */ extern int postcard_enabled; /* (C) enable POST card */ extern int unittester_enabled; /* (C) enable unit tester device */ extern int isamem_type[]; /* (C) enable ISA mem cards */ diff --git a/src/include/86box/novell_cardkey.h b/src/include/86box/novell_cardkey.h new file mode 100644 index 000000000..8ad3eabab --- /dev/null +++ b/src/include/86box/novell_cardkey.h @@ -0,0 +1,37 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Novell NetWare 2.x Key Card, which + * was used for anti-piracy protection. + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345. + */ +#ifndef NOVELL_KEYCARD_H +#define NOVELL_KEYCARD_H + +/* I/O port range used. */ +#define NOVELL_KEYCARD_ADDR 0x23a +#define NOVELL_KEYCARD_ADDRLEN 6 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t novell_keycard_device; + +/* Functions. */ + +#ifdef __cplusplus +} +#endif + +#endif /*BUGGER_H*/ \ No newline at end of file diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index f662b644c..3904b653a 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/unittester.h> +#include <86box/novell_cardkey.h> } #include "qt_deviceconfig.hpp" @@ -46,7 +47,10 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->checkBoxISABugger->setChecked((machineHasIsa && (bugger_enabled > 0)) ? true : false); ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); ui->checkBoxUnitTester->setChecked(unittester_enabled > 0 ? true : false); + ui->checkBoxKeyCard->setChecked((machineHasIsa && (novell_keycard_enabled > 0)) ? true : false); ui->checkBoxISABugger->setEnabled(machineHasIsa); + ui->checkBoxKeyCard->setEnabled(machineHasIsa); + ui->pushButtonConfigureKeyCard->setEnabled(novell_keycard_enabled > 0); ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); ui->comboBoxRTC->setEnabled(machineHasIsa); ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); @@ -115,10 +119,11 @@ void SettingsOtherPeripherals::save() { /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; - postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; + unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; + novell_keycard_enabled = ui->checkBoxKeyCard->isChecked() ? 1 : 0; + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { @@ -213,3 +218,14 @@ SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() { DeviceConfig::ConfigureDevice(&unittester_device); } + +void SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() +{ + DeviceConfig::ConfigureDevice(&novell_keycard_device); +} + +void SettingsOtherPeripherals::on_checkBoxKeyCard_stateChanged(int arg1) +{ + ui->pushButtonConfigureKeyCard->setEnabled(arg1 != 0); +} + diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index feaa7a001..d5804a68b 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -33,6 +33,10 @@ private slots: void on_checkBoxUnitTester_stateChanged(int arg1); void on_pushButtonConfigureUT_clicked(); + void on_pushButtonConfigureKeyCard_clicked(); + + void on_checkBoxKeyCard_stateChanged(int arg1); + private: Ui::SettingsOtherPeripherals *ui; int machineId { 0 }; diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index af953a984..41df2deac 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -37,15 +37,15 @@ - - 30 - 0 0 + + 30 + @@ -72,15 +72,15 @@ - - 30 - 0 0 + + 30 + @@ -113,15 +113,15 @@ - - 30 - 0 0 + + 30 + @@ -133,28 +133,28 @@ - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + @@ -196,15 +196,15 @@ - - 86Box Unit Tester - 0 0 + + 86Box Unit Tester + @@ -216,6 +216,40 @@ + + + + 0 + + + + + Novell NetWare 2.x Key Card + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Configure + + + + + From 1be08f9a9f5d4419ff2a28767de2077911f949f5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 13:43:35 +0600 Subject: [PATCH 169/690] Handle Application Number part correctly --- src/device/novell_cardkey.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index ad3f0a5ea..54b716cc3 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -39,10 +39,10 @@ novell_cardkey_read(uint16_t port, void *priv) uint8_t val = 0x00; switch (port) { case 0x23A: - val = ((cardkey->serial_number_str[11] - '0') << 4) | ((cardkey->serial_number_str[9] - '0')); + val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4); break; case 0x23B: - val = ((cardkey->serial_number_str[10] - '0') << 4) | ((cardkey->serial_number_str[8] - '0')); + val = (((cardkey->serial_number_str[10] > 'A') ? ((cardkey->serial_number_str[10] - 'A') + 10) : (cardkey->serial_number_str[10] - '0')) << 4) | (((cardkey->serial_number_str[8] > 'A') ? ((cardkey->serial_number_str[8] - 'A') + 10) : (cardkey->serial_number_str[8] - '0')) << 4); break; case 0x23C: @@ -69,7 +69,7 @@ void* novell_cardkey_init(const device_t* info) strncpy(sernumstr, device_get_config_string("serial_number"), sizeof(sernumstr) - 1); - for (i = 0; i < sizeof(sernumstr); i++) { + for (i = 0; i < sizeof(sernumstr) - 4; i++) { if (sernumstr[i] > '8' || sernumstr[i] < '0') sernumstr[i] = '0'; } From 8363144dbf9b8d7c2333ab4d62d08d454ea890b3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 13:49:13 +0600 Subject: [PATCH 170/690] More validation --- src/device/novell_cardkey.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 54b716cc3..9f489cad7 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -73,6 +73,14 @@ void* novell_cardkey_init(const device_t* info) if (sernumstr[i] > '8' || sernumstr[i] < '0') sernumstr[i] = '0'; } + if (sernumstr[8] > 'F' || sernumstr[8] < '0') + sernumstr[8] = '0'; + if (sernumstr[9] > 'F' || sernumstr[9] < '0') + sernumstr[9] = '0'; + if (sernumstr[10] > 'F' || sernumstr[10] < '0') + sernumstr[10] = '0'; + if (sernumstr[11] > 'F' || sernumstr[11] < '0') + sernumstr[11] = '0'; sernumstr[12] = 0; strncpy(cardkey->serial_number_str, sernumstr, sizeof(sernumstr)); io_sethandler(NOVELL_KEYCARD_ADDR, NOVELL_KEYCARD_ADDRLEN, novell_cardkey_read, NULL, NULL, NULL, NULL, NULL, cardkey); From 0275ff352311d4f5bc9d5edbcc12f6cab7fea61e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 27 Feb 2024 16:16:06 +0600 Subject: [PATCH 171/690] MGA: Implement BPLAN for BITBLT operations --- src/video/vid_mga.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f40385fef..87e267eb4 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -315,6 +315,7 @@ #define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) #define DWGCTRL_BLTMOD_MASK (0xf << 25) #define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) +#define DWGCTRL_BLTMOD_BPLAN (0x1 << 25) #define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) #define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) #define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) @@ -5371,6 +5372,91 @@ blit_bitblt(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + /* TODO: This isn't exactly perfect. */ + case DWGCTRL_BLTMOD_BPLAN: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; + + while (1) { + uint32_t byte_addr = src_addr & mystique->vram_mask; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; From e68b062ca0cb0683712fee3c416f45beaf9f279e 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: Tue, 27 Feb 2024 20:38:04 +0800 Subject: [PATCH 172/690] Add files via upload --- src/win/languages/ja-JP.rc | 4 ++-- src/win/languages/ko-KR.rc | 2 +- src/win/languages/zh-CN.rc | 4 ++-- src/win/languages/zh-TW.rc | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index 4090abf00..74ae06092 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0コア)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "カートリッジ %i: %ls" IDS_2152 "カートリッジ イメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" IDS_2153 "レンダラーの初期化エラー" - IDS_2154 "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" + IDS_2154 "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" IDS_2155 "実行を再開" IDS_2156 "実行を一時停止" IDS_2157 "Ctrl+Alt+DELを押す" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 7550e0779..a63090c9b 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 코어)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 1139de4ea..676574720 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "卡带 %i: %ls" IDS_2152 "卡带映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" IDS_2153 "初始化渲染器时出错" - IDS_2154 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" + IDS_2154 "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" IDS_2155 "恢复执行" IDS_2156 "暂停执行" IDS_2157 "按下 Ctrl+Alt+Del" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 58324442d..171d8e3f6 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "卡帶 %i: %ls" IDS_2152 "卡帶映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有檔案 (*.*)\0*.*\0" IDS_2153 "初始化渲染器時出錯" - IDS_2154 "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" + IDS_2154 "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" IDS_2155 "恢復執行" IDS_2156 "暫停執行" IDS_2157 "按下 Ctrl+Alt+Del" From fd3b29a5d077e3352255f7173c05e00558da5305 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: Tue, 27 Feb 2024 20:43:14 +0800 Subject: [PATCH 173/690] Add files via upload --- src/qt/languages/ja-JP.po | 4 ++-- src/qt/languages/ko-KR.po | 2 +- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index d0f206dc9..ebcaf9cfb 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0コア)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "レンダラーの初期化エラー" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" +msgstr "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" msgid "Resume execution" msgstr "実行を再開" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index f5d1502b0..949548ed1 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 코어)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 94c468d80..dd819deb0 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 核心)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "初始化渲染器时出错" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" +msgstr "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" msgid "Resume execution" msgstr "恢复执行" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 7836f7ef8..aef164704 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 核心)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "初始化渲染器時出錯" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" +msgstr "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" msgid "Resume execution" msgstr "恢復執行" From 9d4f4f0a70277d3efda10c422489ddd01ef78046 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 28 Feb 2024 14:08:55 +0600 Subject: [PATCH 174/690] MGA: Move BPLAN handling to the right place --- src/video/vid_mga.c | 170 ++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 87e267eb4..6b0c563b2 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5372,91 +5372,6 @@ blit_bitblt(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - /* TODO: This isn't exactly perfect. */ - case DWGCTRL_BLTMOD_BPLAN: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); - - src_addr = mystique->dwgreg.ar[3]; - - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x = x_start; - - while (1) { - uint32_t byte_addr = src_addr & mystique->vram_mask; - - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { - uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst; - uint32_t old_dst; - - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; - - case MACCESS_PWIDTH_16: - dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; - - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK - - *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; - - case MACCESS_PWIDTH_32: - dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; - - default: - fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; - - if (x != x_end) { - if ((x > x_end) && (x_dir == 1)) - x--; - else if ((x < x_end) && (x_dir == -1)) - x++; - else - x += x_dir; - } else - break; - } - - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; @@ -5564,6 +5479,91 @@ blit_bitblt(mystique_t *mystique) } case DWGCTRL_ATYPE_RSTR: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + /* TODO: This isn't exactly perfect. */ + case DWGCTRL_BLTMOD_BPLAN: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; + + while (1) { + uint32_t byte_addr = src_addr & mystique->vram_mask; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) From 901e2568fe382115e7aac711b5f52ba6501645b7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:46:37 +0100 Subject: [PATCH 175/690] Mask out serial passthrough MSR bits when in loopback mode, fixes #4217. --- src/device/serial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/device/serial.c b/src/device/serial.c index 37aadf8fe..dcdffb71c 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -686,7 +686,10 @@ serial_read(uint16_t addr, void *priv) serial_update_ints(dev); break; case 6: - ret = dev->msr | dev->msr_set; + if (dev->mctrl & 0x10) + ret = dev->msr; + else + ret = dev->msr | dev->msr_set; dev->msr &= ~0x0f; dev->int_status &= ~SERIAL_INT_MSR; serial_update_ints(dev); From 5af0ccd145bbfcfafd456640c8bcc0442db124e1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:48:16 +0100 Subject: [PATCH 176/690] Assorted Voodoo and warning fixes. --- src/network/net_pcnet.c | 3 +- src/video/vid_voodoo_banshee.c | 3 ++ src/video/vid_voodoo_banshee_blitter.c | 48 ++++++++++++++++++++++++++ src/video/vid_voodoo_render.c | 4 ++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 9ddcfe29d..1e28c5846 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -787,8 +787,9 @@ static int ladr_match(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { const struct ether_header *hdr = (const struct ether_header *) buf; + uint64_t *p = (uint64_t *) &dev->aCSR[8]; - if ((hdr->ether_dhost[0] & 0x01) && ((uint64_t *) &dev->aCSR[8])[0] != 0LL) { + if ((hdr->ether_dhost[0] & 0x01) && p[0] != 0LL) { int index; uint8_t ladr[8]; ladr[0] = dev->aCSR[8] & 0xff; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 098e919d4..a333062e1 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -510,6 +510,9 @@ banshee_render_16bpp_tiled(svga_t *svga) else addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + if (addr >= svga->vram_max) + return; + for (int x = 0; x <= svga->hdisp; x += 64) { if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 33ee602b5..b8809d3fd 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -216,6 +216,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -226,6 +229,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -236,6 +242,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -246,6 +255,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -265,6 +277,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -274,6 +289,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -283,6 +301,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -292,6 +313,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -573,6 +597,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -584,6 +611,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -595,6 +625,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -606,6 +639,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -904,6 +940,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); @@ -918,6 +957,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); @@ -932,6 +974,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); @@ -946,6 +991,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 42426744a..0f31fbc9f 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -1394,7 +1394,7 @@ next_line: void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) { - voodoo_state_t state; + voodoo_state_t state = { 0 }; int vertexAy_adjusted; int vertexCy_adjusted; int dx; @@ -1406,6 +1406,8 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) int LOD; int lodbias; + state.dx1 = state.dx2 = 0; + voodoo->tri_count++; dx = 8 - (params->vertexAx & 0xf); From 71ecdc1b55b31a81cf64c3358a5c56fe222a2e8b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:52:45 +0100 Subject: [PATCH 177/690] No longer raise TS# when (CS & 0xFFF8) is zero and (CS & 0x0004) is not, fixes #4214. --- src/cpu/x86seg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index c50c97a39..d912a755b 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2401,7 +2401,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.base |= (readmemb(0, templ + 7) << 24); } - if (!(new_cs & 0xfff8)) { + if (!(new_cs & 0xfff8) && !(new_cs & 0x0004)) { x86ts(NULL, 0); return; } From fd31aba2a1e2ffe8c67efe42363d09c470ffcd7b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 13:58:05 +0600 Subject: [PATCH 178/690] MGA: Implement X11 hardware cursor --- src/video/vid_mga.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 6b0c563b2..074303553 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6016,6 +6016,17 @@ mystique_hwcursor_draw(svga_t *svga, int displine) } break; + case XCURCTRL_CURMODE_XWIN: + for (uint8_t x = 0; x < 64; x++) { + if ((dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? (mystique->cursor.col[1]) : (mystique->cursor.col[0]); + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; + default: break; } From e0d80aefb4be625d2a26dbb3e7e8ffa52ce4b9c8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 06:52:48 +0100 Subject: [PATCH 179/690] Moved OPL2 and OPL3 to a new 49716 Hz source so resampling is no longer needed, also fixed SB OPL and PC Speaker filtering (OPL was being downsampled to the selected DSP sample rate, which is incorrect, and the PC Speaker filter was using the wrong filter index in some liens). --- src/include/86box/filters.h | 66 +++---- src/include/86box/snd_sb.h | 2 +- src/include/86box/snd_sb_dsp.h | 4 + src/include/86box/sound.h | 10 + src/sound/openal.c | 46 +++-- src/sound/snd_adlib.c | 2 +- src/sound/snd_adlibgold.c | 130 ++++++++++++- src/sound/snd_azt2316a.c | 3 + src/sound/snd_cs423x.c | 25 ++- src/sound/snd_opl_nuked.c | 22 ++- src/sound/snd_opl_ymfm.cpp | 45 +++-- src/sound/snd_optimc.c | 8 +- src/sound/snd_pas16.c | 16 +- src/sound/snd_sb.c | 342 ++++++++++++++++++++++++--------- src/sound/snd_sb_dsp.c | 16 +- src/sound/snd_wss.c | 29 ++- src/sound/sound.c | 91 +++++++++ src/sound/xaudio2.c | 19 +- 18 files changed, 683 insertions(+), 193 deletions(-) diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index dfe19c654..16c9c7221 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -5,7 +5,7 @@ /* fc=150Hz */ static inline float -adgold_highpass_iir(int i, float NewSample) +adgold_highpass_iir(int c, int i, float NewSample) { float ACoef[NCoef + 1] = { 0.98657437157334349000, @@ -19,28 +19,28 @@ adgold_highpass_iir(int i, float NewSample) 0.97261396931534050000 }; - static float y[2][NCoef + 1]; /* output samples */ - static float x[2][NCoef + 1]; /* input samples */ + static float y[2][2][NCoef + 1]; /* output samples */ + static float x[2][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ for (n = NCoef; n > 0; n--) { - x[i][n] = x[i][n - 1]; - y[i][n] = y[i][n - 1]; + x[c][i][n] = x[c][i][n - 1]; + y[c][i][n] = y[c][i][n - 1]; } /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; + x[c][i][0] = NewSample; + y[c][i][0] = ACoef[0] * x[c][i][0]; for (n = 1; n <= NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - return y[i][0]; + return y[c][i][0]; } /* fc=150Hz */ static inline float -adgold_lowpass_iir(int i, float NewSample) +adgold_lowpass_iir(int c, int i, float NewSample) { float ACoef[NCoef + 1] = { 0.00009159473951071446, @@ -54,23 +54,23 @@ adgold_lowpass_iir(int i, float NewSample) 0.97261396931306277000 }; - static float y[2][NCoef + 1]; /* output samples */ - static float x[2][NCoef + 1]; /* input samples */ + static float y[2][2][NCoef + 1]; /* output samples */ + static float x[2][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ for (n = NCoef; n > 0; n--) { - x[i][n] = x[i][n - 1]; - y[i][n] = y[i][n - 1]; + x[c][i][n] = x[c][i][n - 1]; + y[c][i][n] = y[c][i][n - 1]; } /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; + x[c][i][0] = NewSample; + y[c][i][0] = ACoef[0] * x[c][i][0]; for (n = 1; n <= NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - return y[i][0]; + return y[c][i][0]; } /* fc=56Hz */ @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[3][NCoef + 1]; /* output samples */ - static double x[3][NCoef + 1]; /* input samples */ + static double y[4][NCoef + 1]; /* output samples */ + static double x[4][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[3][SB16_NCoef]; +extern double low_fir_sb16_coef[4][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) { - static double x[3][2][SB16_NCoef + 1]; // input samples - static int pos[3] = { 0, 0 }; + static double x[4][2][SB16_NCoef + 1]; // input samples + static int pos[4] = { 0, 0, 0, 0 }; double out = 0.0; int n; diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index f433dd107..621cb4ade 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -143,7 +143,6 @@ typedef struct sb_t { emu8k_t emu8k; void *gameport; - int pos; int pnp; uint8_t pos_regs[8]; @@ -165,6 +164,7 @@ extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv); extern void sb_ct1745_mixer_reset(sb_t *sb); extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv); +extern void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv); extern void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv); extern void sb_close(void *priv); diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index ecabe426d..3e0e40e80 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -97,6 +97,8 @@ typedef struct sb_dsp_t { int sb_irqm16; int sb_irqm401; + uint8_t sb_has_real_opl; + uint8_t sb_asp_regs[256]; uint8_t sb_asp_mode; @@ -158,6 +160,8 @@ extern void sb_dsp_speed_changed(sb_dsp_t *dsp); extern void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); +extern void sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl); + extern void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); extern void sb_dsp_update(sb_dsp_t *dsp); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 60628ece8..b8f9be5b2 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -33,6 +33,9 @@ extern int sound_gain; #define SOUND_FREQ FREQ_48000 #define SOUNDBUFLEN (SOUND_FREQ / 50) +#define MUSIC_FREQ FREQ_49716 +#define MUSICBUFLEN (MUSIC_FREQ / 36) + #define CD_FREQ FREQ_44100 #define CD_BUFLEN (CD_FREQ / 10) @@ -47,12 +50,18 @@ extern int speakval; extern int speakon; extern int sound_pos_global; +extern int music_pos_global; + extern int sound_card_current[SOUND_CARD_MAX]; extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv); +extern void music_add_handler(void (*get_buffer)(int32_t *buffer, + int len, void *priv), + void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv); @@ -86,6 +95,7 @@ extern void sound_cd_thread_reset(void); extern void closeal(void); extern void inital(void); extern void givealbuffer(void *buf); +extern void givealbuffer_music(void *buf); extern void givealbuffer_cd(void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base diff --git a/src/sound/openal.c b/src/sound/openal.c index 76656c66e..98f87855e 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -38,10 +38,11 @@ #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN -ALuint buffers[4]; /* front and back buffers */ -ALuint buffers_cd[4]; /* front and back buffers */ -ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[3]; /* audio source */ +ALuint buffers[4]; /* front and back buffers */ +ALuint buffers_music[4]; /* front and back buffers */ +ALuint buffers_cd[4]; /* front and back buffers */ +ALuint buffers_midi[4]; /* front and back buffers */ +static ALuint source[4]; /* audio source */ static int midi_freq = 44100; static int midi_buf_size = 4410; @@ -99,9 +100,10 @@ closeal(void) alSourceStopv(sources, source); alDeleteSources(sources, source); - if (sources == 3) + if (sources == 4) alDeleteBuffers(4, buffers_midi); alDeleteBuffers(4, buffers_cd); + alDeleteBuffers(4, buffers_music); alDeleteBuffers(4, buffers); alutExit(); @@ -132,16 +134,18 @@ inital(void) if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the MIDI buffer and source, otherwise, do not. */ - sources = 2 + !!init_midi; + sources = 3 + !!init_midi; if (sound_is_float) { - buf = (float *) calloc((BUFLEN << 1), sizeof(float)); - cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); + buf = (float *) calloc((BUFLEN << 1), sizeof(float)); + music_buf = (float *) calloc((MUSIC_BUFLEN << 1), sizeof(float)); + cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { - buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); - cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); + buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); + music_buf_int16 = (int16_t *) calloc((MUSIC_BUFLEN << 1), sizeof(int16_t)); + cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); } @@ -189,11 +193,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSIC_BUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSIC_BUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); @@ -201,23 +207,27 @@ inital(void) } alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourceQueueBuffers(source[1], 4, buffers_music); + alSourceQueueBuffers(source[2], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[2], 4, buffers_midi); + alSourceQueueBuffers(source[3], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); + alSourcePlay(source[2]); if (init_midi) - alSourcePlay(source[2]); + alSourcePlay(source[3]); if (sound_is_float) { if (init_midi) free(midi_buf); free(cd_buf); + free(music_buf); free(buf); } else { if (init_midi) free(midi_buf_int16); free(cd_buf_int16); + free(music_buf_int16); free(buf_int16); } @@ -263,14 +273,20 @@ givealbuffer(void *buf) givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } +void +givealbuffer_music(void *buf) +{ + givealbuffer_common(buf, 1, MUSIC_BUFLEN << 1, MUSIC_FREQ); +} + void givealbuffer_cd(void *buf) { - givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); + givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); } void givealbuffer_midi(void *buf, uint32_t size) { - givealbuffer_common(buf, 2, size, midi_freq); + givealbuffer_common(buf, 3, size, midi_freq); } diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 5d0d7c7aa..f5eae9b93 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -112,7 +112,7 @@ adlib_init(UNUSED(const device_t *info)) adlib->opl.read, NULL, NULL, adlib->opl.write, NULL, NULL, adlib->opl.priv); - sound_add_handler(adlib_get_buffer, adlib); + music_add_handler(adlib_get_buffer, adlib); return adlib; } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 71cbbcaa6..488dcb8a6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -788,13 +788,10 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) int c; - const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { - adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; } @@ -857,8 +854,8 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) /*Output is deliberately halved to avoid clipping*/ temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(0, temp); - highpass = adgold_highpass_iir(0, temp); + lowpass = adgold_lowpass_iir(0, 0, temp); + highpass = adgold_highpass_iir(0, 0, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -874,8 +871,124 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) buffer[c] += temp; temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(1, temp); - highpass = adgold_highpass_iir(1, temp); + lowpass = adgold_lowpass_iir(0, 1, temp); + highpass = adgold_highpass_iir(0, 1, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c + 1] += temp; + } + + adgold->pos = 0; + + free(adgold_buffer); +} + +static void +adgold_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + adgold_t *adgold = (adgold_t *) priv; + int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2); + if (adgold_buffer == NULL) + fatal("adgold_buffer = NULL"); + + int c; + + const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); + adgold_update(adgold); + + for (c = 0; c < len * 2; c += 2) { + adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; + adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; + } + + if (adgold->surround_enabled) + ym7128_apply(&adgold->ym7128, adgold_buffer, len); + + switch (adgold->adgold_38x_regs[0x8] & 6) { + case 0: + for (c = 0; c < len * 2; c++) + adgold_buffer[c] = 0; + break; + case 2: /*Left channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c + 1] = adgold_buffer[c]; + break; + case 4: /*Right channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1]; + break; + case 6: /*Left and right channels*/ + break; + + default: + break; + } + + switch (adgold->adgold_38x_regs[0x8] & 0x18) { + case 0x00: /*Forced mono*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2; + break; + case 0x08: /*Linear stereo*/ + break; + case 0x10: /*Pseudo stereo*/ + /*Filter left channel, leave right channel unchanged*/ + /*Filter cutoff is largely a guess*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); + break; + case 0x18: /*Spatial stereo*/ + /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet + and a very vague understanding of how op-amps work to go on*/ + for (c = 0; c < len * 2; c += 2) { + int16_t l = adgold_buffer[c]; + int16_t r = adgold_buffer[c + 1]; + + adgold_buffer[c] += (r / 3) + ((l * 2) / 3); + adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3); + } + break; + + default: + break; + } + + for (c = 0; c < len * 2; c += 2) { + int32_t temp; + int32_t lowpass; + int32_t highpass; + + /*Output is deliberately halved to avoid clipping*/ + temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; + lowpass = adgold_lowpass_iir(1, 0, temp); + highpass = adgold_highpass_iir(1, 0, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c] += temp; + + temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; + lowpass = adgold_lowpass_iir(1, 1, temp); + highpass = adgold_highpass_iir(1, 1, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -892,7 +1005,6 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) } adgold->opl.reset_buffer(adgold->opl.priv); - adgold->pos = 0; free(adgold_buffer); } @@ -1054,6 +1166,8 @@ adgold_init(UNUSED(const device_t *info)) timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); sound_add_handler(adgold_get_buffer, adgold); + music_add_handler(adgold_get_music_buffer, adgold); + sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); if (device_get_config_int("receive_input")) diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 80d668599..28ab2b7ac 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -1237,6 +1237,7 @@ azt_init(const device_t *info) if (azt2316a->sb->opl_enabled) fm_driver_get(FM_YMF262, &azt2316a->sb->opl); + sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1); sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); @@ -1253,6 +1254,8 @@ azt_init(const device_t *info) azt2316a_create_config_word(azt2316a); sound_add_handler(azt2316a_get_buffer, azt2316a); + if (azt2316a->sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, azt2316a->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); if (azt2316a->cur_mpu401_enabled) { diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index fad1d76b9..90aa0b0dd 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -543,13 +543,31 @@ cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv) static void cs423x_get_buffer(int32_t *buffer, int len, void *priv) +{ + cs423x_t *dev = (cs423x_t *) priv; + + /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ + ad1848_update(&dev->ad1848); + + /* Don't output anything if the analog section is powered down. */ + if (!(dev->indirect_regs[2] & 0xa4)) { + for (int c = 0; c < len * 2; c += 2) { + buffer[c] += dev->ad1848.buffer[c] / 2; + buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; + } + } + + dev->ad1848.pos = 0; +} + +static void +cs423x_get_music_buffer(int32_t *buffer, int len, void *priv) { cs423x_t *dev = (cs423x_t *) priv; int opl_wss = dev->opl_wss; const int32_t *opl_buf = NULL; /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ - ad1848_update(&dev->ad1848); if (opl_wss) opl_buf = dev->sb->opl.update(dev->sb->opl.priv); @@ -560,13 +578,9 @@ cs423x_get_buffer(int32_t *buffer, int len, void *priv) buffer[c] += (opl_buf[c] * dev->ad1848.fm_vol_l) >> 16; buffer[c + 1] += (opl_buf[c + 1] * dev->ad1848.fm_vol_r) >> 16; } - - buffer[c] += dev->ad1848.buffer[c] / 2; - buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; } } - dev->ad1848.pos = 0; if (opl_wss) dev->sb->opl.reset_buffer(dev->sb->opl.priv); } @@ -846,6 +860,7 @@ cs423x_init(const device_t *info) /* Initialize RAM, registers and WSS codec. */ cs423x_reset(dev); sound_add_handler(cs423x_get_buffer, dev); + music_add_handler(cs423x_get_music_buffer, dev); /* Add Control/RAM backdoor handlers for CS4235. */ dev->ad1848.cram_priv = dev; diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index d8281ba1d..95b61638e 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -55,7 +55,8 @@ #define WRBUF_DELAY 1 #define RSM_FRAC 10 -#define OPL_FREQ FREQ_48000 +// #define OPL_FREQ FREQ_48000 +#define OPL_FREQ FREQ_49716 // Channel types enum { @@ -189,7 +190,7 @@ typedef struct { pc_timer_t timers[2]; int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[MUSICBUFLEN * 2]; } nuked_drv_t; enum { @@ -1381,11 +1382,20 @@ nuked_generate_resampled(nuked_t *dev, int32_t *bufp) dev->samplecnt += 1 << RSM_FRAC; } +void +nuked_generate_raw(nuked_t *dev, int32_t *bufp) +{ + nuked_generate(dev, dev->samples); + + bufp[0] = (int32_t) dev->samples[0]; + bufp[1] = (int32_t) dev->samples[1]; +} + void nuked_generate_stream(nuked_t *dev, int32_t *sndptr, uint32_t num) { for (uint32_t i = 0; i < num; i++) { - nuked_generate_resampled(dev, sndptr); + nuked_generate_raw(dev, sndptr); sndptr += 2; } } @@ -1533,14 +1543,14 @@ nuked_drv_update(void *priv) { nuked_drv_t *dev = (nuked_drv_t *) priv; - if (dev->pos >= sound_pos_global) + if (dev->pos >= music_pos_global) return dev->buffer; nuked_generate_stream(&dev->opl, &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + music_pos_global - dev->pos); - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; dev->buffer[(dev->pos * 2) + 1] /= 2; } diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 0f996f6bc..55e7f1984 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -51,10 +51,11 @@ enum { class YMFMChipBase { public: - YMFMChipBase(UNUSED(uint32_t clock), fm_type type, UNUSED(uint32_t samplerate)) + YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate) : m_buf_pos(0) , m_flags(0) , m_type(type) + , m_samplerate(samplerate) { memset(m_buffer, 0, sizeof(m_buffer)); } @@ -79,10 +80,11 @@ public: virtual void set_clock(uint32_t clock) = 0; protected: - int32_t m_buffer[SOUNDBUFLEN * 2]; - int m_buf_pos; - int8_t m_flags; - fm_type m_type; + int32_t m_buffer[MUSICBUFLEN * 2]; + int m_buf_pos; + int8_t m_flags; + fm_type m_type; + uint32_t m_samplerate; }; template @@ -170,6 +172,11 @@ public: virtual void generate_resampled(int32_t *data, uint32_t num_samples) override { + if (m_samplerate == FREQ_49716) { + generate(data, num_samples); + return; + } + for (uint32_t i = 0; i < num_samples; i++) { while (m_samplecnt >= m_rateratio) { m_oldsamples[0] = m_samples[0]; @@ -206,14 +213,26 @@ public: virtual int32_t *update() override { - if (m_buf_pos >= sound_pos_global) - return m_buffer; + if (m_samplerate == FREQ_49716) { + if (m_buf_pos >= music_pos_global) + return m_buffer; - generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); + generate(&m_buffer[m_buf_pos * 2], music_pos_global - m_buf_pos); - for (; m_buf_pos < sound_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; + for (; m_buf_pos < music_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; + } + } else { + if (m_buf_pos >= sound_pos_global) + return m_buffer; + + generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); + + for (; m_buf_pos < sound_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; + } } return m_buffer; @@ -314,11 +333,11 @@ ymfm_drv_init(const device_t *info) switch (info->local) { default: case FM_YM3812: - fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, FREQ_49716); break; case FM_YMF262: - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, FREQ_49716); break; case FM_YMF289B: diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index d7afca382..245d9590e 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -391,6 +391,9 @@ optimc_init(const device_t *info) optimc->sb = calloc(1, sizeof(sb_t)); optimc->sb->opl_enabled = 1; + optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; + + sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B); sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); @@ -400,7 +403,6 @@ optimc_init(const device_t *info) optimc->sb->opl_mixer = optimc; optimc->sb->opl_mix = optimc_filter_opl; - optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; fm_driver_get(optimc->fm_type, &optimc->sb->opl); io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); io_sethandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); @@ -411,6 +413,10 @@ optimc_init(const device_t *info) io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); sound_add_handler(optimc_get_buffer, optimc); + if (optimc->fm_type == FM_YMF278B) + sound_add_handler(sb_get_music_buffer_sbpro, optimc->sb); + else + music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ optimc->mpu = (mpu_t *) malloc(sizeof(mpu_t)); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 674acfcbb..3ce9b5c4c 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -728,20 +728,29 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c++) { - buffer[c] += opl_buf[c]; buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); } pas16->pos = 0; - pas16->opl.reset_buffer(pas16->opl.priv); pas16->dsp.pos = 0; } +void +pas16_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); + for (int c = 0; c < len * 2; c++) + buffer[c] += opl_buf[c]; + + pas16->opl.reset_buffer(pas16->opl.priv); +} + static void * pas16_init(UNUSED(const device_t *info)) { @@ -756,6 +765,7 @@ pas16_init(UNUSED(const device_t *info)) timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); sound_add_handler(pas16_get_buffer, pas16); + music_add_handler(pas16_get_music_buffer, pas16); return pas16; } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 3aa152b8f..98b17e3f0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -185,10 +185,6 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) double out_mono = 0.0; double out_l = 0.0; double out_r = 0.0; - const int32_t *opl_buf = NULL; - - if (sb->opl_enabled) - opl_buf = sb->opl.update(sb->opl.priv); sb_dsp_update(&sb->dsp); @@ -200,17 +196,12 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->opl_enabled) - out_mono = ((double) opl_buf[c]) * 0.7171630859375; - if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; out_r += sb->cms.buffer[c + 1]; } - out_l += out_mono; - out_r += out_mono; - if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) { + if (sb->cms_enabled && sb->mixer_enabled) { out_l *= mixer->fm; out_r *= mixer->fm; } @@ -234,17 +225,55 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->pos = 0; - - if (sb->opl_enabled) - sb->opl.reset_buffer(sb->opl.priv); - sb->dsp.pos = 0; if (sb->cms_enabled) sb->cms.pos = 0; } +static void +sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double out_mono = 0.0; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + + if (!sb->opl_enabled) + return; + + opl_buf = sb->opl.update(sb->opl.priv); + + for (int c = 0; c < len * 2; c += 2) { + out_mono = 0.0; + out_l = 0.0; + out_r = 0.0; + + if (sb->opl_enabled) + out_mono = ((double) opl_buf[c]) * 0.7171630859375; + + out_l += out_mono; + out_r += out_mono; + + if (sb->mixer_enabled) { + out_l *= mixer->fm; + out_r *= mixer->fm; + } + + if (sb->mixer_enabled) { + out_l *= mixer->master; + out_r *= mixer->master; + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + sb->opl.reset_buffer(sb->opl.priv); +} + static void sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) { @@ -253,10 +282,10 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) double c; if (sb->mixer_enabled) { - c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0; + c = ((sb_iir(2, 0, *buffer) / 1.3) * mixer->cd) / 3.0; *buffer = c * mixer->master; } else { - c = (((sb_iir(1, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0; + c = (((sb_iir(2, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0; *buffer = c; } } @@ -268,16 +297,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; double out_l = 0.0; double out_r = 0.0; - const int32_t *opl_buf = NULL; - const int32_t *opl2_buf = NULL; - - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - opl_buf = sb->opl.update(sb->opl.priv); - opl2_buf = sb->opl2.update(sb->opl2.priv); - } else - opl_buf = sb->opl.update(sb->opl.priv); - } sb_dsp_update(&sb->dsp); @@ -285,21 +304,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - /* Two chips for LEFT and RIGHT channels. - Each chip stores data into the LEFT channel only (no sample alternating.) */ - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; - } else { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (sb->opl_mix && sb->opl_mixer) { - sb->opl_mix(sb->opl_mixer, &out_l, &out_r); - } - } - } - /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; @@ -317,15 +321,57 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->pos = 0; + sb->dsp.pos = 0; +} - if (sb->opl_enabled) { - sb->opl.reset_buffer(sb->opl.priv); - if (sb->dsp.sb_type == SBPRO) - sb->opl2.reset_buffer(sb->opl2.priv); +void +sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + const int32_t *opl2_buf = NULL; + + if (!sb->opl_enabled) + return; + + if (sb->dsp.sb_type == SBPRO) { + opl_buf = sb->opl.update(sb->opl.priv); + opl2_buf = sb->opl2.update(sb->opl2.priv); + } else + opl_buf = sb->opl.update(sb->opl.priv); + + sb_dsp_update(&sb->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + if (sb->dsp.sb_type == SBPRO) { + /* Two chips for LEFT and RIGHT channels. + Each chip stores data into the LEFT channel only (no sample alternating.) */ + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; + } else { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (sb->opl_mix && sb->opl_mixer) + sb->opl_mix(sb->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } - sb->dsp.pos = 0; + sb->opl.reset_buffer(sb->opl.priv); + if (sb->dsp.sb_type == SBPRO) + sb->opl2.reset_buffer(sb->opl2.priv); } void @@ -338,7 +384,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) double master = channel ? mixer->master_r : mixer->master_l; if (mixer->output_filter) - c = (sb_iir(1, channel, *buffer) * cd) / 3.9; + c = (sb_iir(2, channel, *buffer) * cd) / 3.9; else c = (*buffer * cd) / 3.0; *buffer = c * master; @@ -349,21 +395,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k = 0; - int c_record; - int32_t in_l; - int32_t in_r; double out_l = 0.0; double out_r = 0.0; double bass_treble; - const int32_t *opl_buf = NULL; - - if (sb->opl_enabled) - opl_buf = sb->opl.update(sb->opl.priv); - - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); sb_dsp_update(&sb->dsp); @@ -371,25 +405,6 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); - - if (sb->opl_enabled) { - out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; - out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; - } - - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } - - /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ - in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; @@ -440,8 +455,100 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } + buffer[c] += (int32_t) (out_l * mixer->output_gain_L); + buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); + } + + sb->dsp.pos = 0; +} + +static void +sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + int dsp_rec_pos = sb->dsp.record_pos_write; + int c_emu8k = 0; + int c_record; + int32_t in_l; + int32_t in_r; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + const int32_t *opl_buf = NULL; + + if (sb->opl_enabled) + opl_buf = sb->opl.update(sb->opl.priv); + + if (sb->dsp.sb_type > SB16) + emu8k_update(&sb->emu8k); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + if (sb->dsp.sb_type > SB16) + c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + + if (sb->opl_enabled) { + out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; + out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; + } + + if (sb->dsp.sb_type > SB16) { + out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); + } + + /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ + in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; + in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_l]; + + if (mixer->bass_l > 8) + out_l += (low_iir(1, 0, out_l) * bass_treble); + else if (mixer->bass_l < 8) + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->bass_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_r]; + + if (mixer->bass_r > 8) + out_r += (low_iir(1, 1, out_r) * bass_treble); + else if (mixer->bass_r < 8) + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + + if (mixer->treble_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_l]; + + if (mixer->treble_l > 8) + out_l += (high_iir(1, 0, out_l) * bass_treble); + else if (mixer->treble_l < 8) + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->treble_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_r]; + + if (mixer->treble_r > 8) + out_r += (high_iir(1, 1, out_r) * bass_treble); + else if (mixer->treble_r < 8) + out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + if (sb->dsp.sb_enable_i) { - c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / SOUND_FREQ); + c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); in_l <<= mixer->input_gain_L; in_r <<= mixer->input_gain_R; @@ -467,13 +574,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb->dsp.record_pos_write += ((len * sb->dsp.sb_freq) / 24000); sb->dsp.record_pos_write &= 0xffff; - sb->pos = 0; - if (sb->opl_enabled) sb->opl.reset_buffer(sb->opl.priv); - sb->dsp.pos = 0; - if (sb->dsp.sb_type > SB16) sb->emu8k.pos = 0; } @@ -492,7 +595,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); if (mixer->output_filter) - c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0; + c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0; else c = ((*buffer) * cd) / 3.0; c *= master; @@ -503,18 +606,18 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) bass_treble = sb_bass_treble_4bits[bass]; if (bass > 8) - c += (low_iir(1, channel, c) * bass_treble); + c += (low_iir(2, channel, c) * bass_treble); else if (bass < 8) - c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); } if (treble != 8) { bass_treble = sb_bass_treble_4bits[treble]; if (treble > 8) - c += (high_iir(1, channel, c) * bass_treble); + c += (high_iir(2, channel, c) * bass_treble); else if (treble < 8) - c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); } *buffer = c * output_gain; @@ -534,7 +637,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); if (mixer->output_filter) - c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0; + c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; else c = ((*buffer) * spk) / 3.0; c *= master; @@ -545,18 +648,18 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) bass_treble = sb_bass_treble_4bits[bass]; if (bass > 8) - c += (low_iir(2, channel, c) * bass_treble); + c += (low_iir(3, channel, c) * bass_treble); else if (bass < 8) - c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); } if (treble != 8) { bass_treble = sb_bass_treble_4bits[treble]; if (treble > 8) - c += (high_iir(2, channel, c) * bass_treble); + c += (high_iir(3, channel, c) * bass_treble); else if (treble < 8) - c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); } *buffer = c * output_gain; @@ -1706,6 +1809,7 @@ sb_1_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1731,6 +1835,8 @@ sb_1_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1754,6 +1860,7 @@ sb_15_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1781,6 +1888,8 @@ sb_15_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1802,6 +1911,7 @@ sb_mcv_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, 0); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1809,6 +1919,8 @@ sb_mcv_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); /* I/O handlers activated in sb_mcv_write */ @@ -1847,6 +1959,7 @@ sb_2_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1890,6 +2003,8 @@ sb_2_init(UNUSED(const device_t *info)) } else sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1939,6 +2054,7 @@ sb_pro_v1_init(UNUSED(const device_t *info)) sb->opl2.set_do_cycles(sb->opl2.priv, 0); } + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1970,6 +2086,8 @@ sb_pro_v1_init(UNUSED(const device_t *info)) sb_ct1345_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1995,6 +2113,7 @@ sb_pro_v2_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2022,6 +2141,8 @@ sb_pro_v2_init(UNUSED(const device_t *info)) sb_ct1345_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -2044,11 +2165,14 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); /* I/O handlers activated in sb_pro_mcv_write */ @@ -2070,11 +2194,14 @@ sb_pro_compat_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2097,6 +2224,7 @@ sb_16_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(info->local, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B)); sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2126,6 +2254,12 @@ sb_16_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) { + if (info->local == FM_YMF289B) + sound_add_handler(sb_get_music_buffer_sb16_awe32, sb); + else + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + } sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2157,6 +2291,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); @@ -2165,6 +2300,8 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2207,6 +2344,8 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2225,6 +2364,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_setaddr(&sb->dsp, 0); sb_dsp_setirq(&sb->dsp, 0); sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); @@ -2262,6 +2402,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); @@ -2270,6 +2411,8 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2340,6 +2483,7 @@ sb_16_compat_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); @@ -2347,6 +2491,8 @@ sb_16_compat_init(const device_t *info) sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2411,6 +2557,7 @@ sb_awe32_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2440,6 +2587,8 @@ sb_awe32_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2482,9 +2631,12 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); + sb_dsp_set_real_opl(&sb->dsp, 1); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 6fc7815ab..cf4498b4b 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -115,7 +115,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -double low_fir_sb16_coef[3][SB16_NCoef]; +double low_fir_sb16_coef[4][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -1256,8 +1256,12 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); - recalc_sb16_filter(1, FREQ_44100); - recalc_sb16_filter(2, 18939); + if (dsp->sb_has_real_opl) + recalc_sb16_filter(1, FREQ_49716); + else + recalc_sb16_filter(1, FREQ_48000); + recalc_sb16_filter(2, FREQ_44100); + recalc_sb16_filter(3, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); @@ -1283,6 +1287,12 @@ sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) } } +void +sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl) +{ + dsp->sb_has_real_opl = has_real_opl; +} + void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) { diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index a69d746da..da88b29e9 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -80,21 +80,28 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; - const int32_t *opl_buf = NULL; - - if (wss->opl_enabled) - opl_buf = wss->opl.update(wss->opl.priv); ad1848_update(&wss->ad1848); + for (int c = 0; c < len * 2; c++) + buffer[c] += wss->ad1848.buffer[c] / 2; + + wss->ad1848.pos = 0; +} + +static void +wss_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + wss_t *wss = (wss_t *) priv; + const int32_t *opl_buf = NULL; + + opl_buf = wss->opl.update(wss->opl.priv); + for (int c = 0; c < len * 2; c++) { if (opl_buf) buffer[c] += opl_buf[c]; - buffer[c] += wss->ad1848.buffer[c] / 2; } - if (wss->opl_enabled) - wss->opl.reset_buffer(wss->opl.priv); - wss->ad1848.pos = 0; + wss->opl.reset_buffer(wss->opl.priv); } void * @@ -131,6 +138,9 @@ wss_init(UNUSED(const device_t *info)) sound_add_handler(wss_get_buffer, wss); + if (wss->opl_enabled) + music_add_handler(wss_get_music_buffer, wss); + return wss; } @@ -214,6 +224,9 @@ ncr_audio_init(UNUSED(const device_t *info)) sound_add_handler(wss_get_buffer, wss); + if (wss->opl_enabled) + music_add_handler(wss_get_music_buffer, wss); + return wss; } diff --git a/src/sound/sound.c b/src/sound/sound.c index ed7f821e0..81f70d921 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -53,9 +53,11 @@ typedef struct { int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 }; int sound_pos_global = 0; +int music_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; +static sound_handler_t music_handlers[8]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; @@ -63,9 +65,15 @@ static event_t *sound_cd_start_event; static int32_t *outbuffer; static float *outbuffer_ex; static int16_t *outbuffer_ex_int16; +static int32_t *outbuffer_m; +static float *outbuffer_m_ex; +static int16_t *outbuffer_m_ex_int16; static int sound_handlers_num; +static int music_handlers_num; static pc_timer_t sound_poll_timer; static uint64_t sound_poll_latch; +static pc_timer_t music_poll_timer; +static uint64_t music_poll_latch; static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; static float cd_out_buffer[CD_BUFLEN * 2]; @@ -395,6 +403,28 @@ sound_realloc_buffers(void) } } +static void +music_realloc_buffers(void) +{ + if (outbuffer_m_ex != NULL) { + free(outbuffer_m_ex); + outbuffer_m_ex = NULL; + } + + if (outbuffer_m_ex_int16 != NULL) { + free(outbuffer_m_ex_int16); + outbuffer_m_ex_int16 = NULL; + } + + if (sound_is_float) { + outbuffer_m_ex = calloc(MUSICBUFLEN * 2, sizeof(float)); + memset(outbuffer_m_ex, 0x00, MUSICBUFLEN * 2 * sizeof(float)); + } else { + outbuffer_m_ex_int16 = calloc(MUSICBUFLEN * 2, sizeof(int16_t)); + memset(outbuffer_m_ex_int16, 0x00, MUSICBUFLEN * 2 * sizeof(int16_t)); + } +} + void sound_init(void) { @@ -403,10 +433,18 @@ sound_init(void) outbuffer_ex = NULL; outbuffer_ex_int16 = NULL; + outbuffer_m_ex = NULL; + outbuffer_m_ex_int16 = NULL; + outbuffer = NULL; outbuffer = calloc(SOUNDBUFLEN * 2, sizeof(int32_t)); memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); + outbuffer_m = NULL; + outbuffer_m = calloc(MUSICBUFLEN * 2, sizeof(int32_t)); + memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + + for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type != CDROM_BUS_DISABLED) available_cdrom_drives++; @@ -438,6 +476,14 @@ sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void sound_handlers_num++; } +void +music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv) +{ + music_handlers[music_handlers_num].get_buffer = get_buffer; + music_handlers[music_handlers_num].priv = priv; + music_handlers_num++; +} + void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) { @@ -502,10 +548,48 @@ sound_poll(UNUSED(void *priv)) } } +void +music_poll(UNUSED(void *priv)) +{ + timer_advance_u64(&music_poll_timer, music_poll_latch); + + music_pos_global++; + if (music_pos_global == MUSICBUFLEN) { + int c; + + memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + + for (c = 0; c < music_handlers_num; c++) + music_handlers[c].get_buffer(outbuffer_m, MUSICBUFLEN, music_handlers[c].priv); + + for (c = 0; c < MUSICBUFLEN * 2; c++) { + if (sound_is_float) + outbuffer_m_ex[c] = ((float) outbuffer_m[c]) / (float) 32768.0; + else { + if (outbuffer_m[c] > 32767) + outbuffer_m[c] = 32767; + if (outbuffer_m[c] < -32768) + outbuffer_m[c] = -32768; + + outbuffer_m_ex_int16[c] = outbuffer_m[c]; + } + } + + if (sound_is_float) + givealbuffer_music(outbuffer_m_ex); + else + givealbuffer_music(outbuffer_m_ex_int16); + + music_pos_global = 0; + } +} + void sound_speed_changed(void) { sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); + + music_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) MUSIC_FREQ)); } void @@ -513,6 +597,8 @@ sound_reset(void) { sound_realloc_buffers(); + music_realloc_buffers(); + midi_out_device_init(); midi_in_device_init(); @@ -523,6 +609,11 @@ sound_reset(void) sound_handlers_num = 0; memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t)); + timer_add(&music_poll_timer, music_poll, NULL, 1); + + music_handlers_num = 0; + memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t)); + filter_cd_audio = NULL; filter_cd_audio_p = NULL; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 0d9e7d909..78c3e2d35 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -51,6 +51,7 @@ static int initialized = 0; static IXAudio2 *xaudio2 = NULL; static IXAudio2MasteringVoice *mastervoice = NULL; static IXAudio2SourceVoice *srcvoice = NULL; +static IXAudio2SourceVoice *srcvoicemusic = NULL; static IXAudio2SourceVoice *srcvoicemidi = NULL; static IXAudio2SourceVoice *srcvoicecd = NULL; @@ -164,6 +165,12 @@ inital(void) return; } + fmt.nSamplesPerSec = MUSIC_FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + + IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + fmt.nSamplesPerSec = CD_FREQ; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; @@ -173,6 +180,7 @@ inital(void) IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); @@ -196,6 +204,8 @@ closeal(void) initialized = 0; IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); + IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); if (srcvoicemidi) { @@ -203,8 +213,9 @@ closeal(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); } - IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2SourceVoice_DestroyVoice(srcvoicecd); + IXAudio2SourceVoice_DestroyVoice(srcvoicemusic); + IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); srcvoice = srcvoicecd = srcvoicemidi = NULL; @@ -249,6 +260,12 @@ givealbuffer(void *buf) givealbuffer_common(buf, srcvoice, BUFLEN << 1); } +void +givealbuffer_music(void *buf) +{ + givealbuffer_common(buf, srcvoicemusic, MUSICBUFLEN << 1); +} + void givealbuffer_cd(void *buf) { From c7028f1e35d12feb90ee4568db5d4c61da25253b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 07:13:29 +0100 Subject: [PATCH 180/690] Fixed some compile-breaking mistakes in sound/openal.c. --- src/sound/openal.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 98f87855e..234db5ca3 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -114,12 +114,14 @@ closeal(void) void inital(void) { - float *buf = NULL; - float *cd_buf = NULL; - float *midi_buf = NULL; - int16_t *buf_int16 = NULL; - int16_t *cd_buf_int16 = NULL; - int16_t *midi_buf_int16 = NULL; + float *buf = NULL; + float *music_buf = NULL; + float *cd_buf = NULL; + float *midi_buf = NULL; + int16_t *buf_int16 = NULL; + int16_t *music_buf_int16 = NULL; + int16_t *cd_buf_int16 = NULL; + int16_t *midi_buf_int16 = NULL; const char *mdn; int init_midi = 0; @@ -276,7 +278,7 @@ givealbuffer(void *buf) void givealbuffer_music(void *buf) { - givealbuffer_common(buf, 1, MUSIC_BUFLEN << 1, MUSIC_FREQ); + givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } void From 742b80c6b3d8b48dcbfe82e9a80b9feddd44be6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 08:01:36 +0100 Subject: [PATCH 181/690] And another one. --- src/sound/openal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 234db5ca3..1e47cccd7 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -140,13 +140,13 @@ inital(void) if (sound_is_float) { buf = (float *) calloc((BUFLEN << 1), sizeof(float)); - music_buf = (float *) calloc((MUSIC_BUFLEN << 1), sizeof(float)); + music_buf = (float *) calloc((MUSICBUFLEN << 1), sizeof(float)); cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); - music_buf_int16 = (int16_t *) calloc((MUSIC_BUFLEN << 1), sizeof(int16_t)); + music_buf_int16 = (int16_t *) calloc((MUSICBUFLEN << 1), sizeof(int16_t)); cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); @@ -195,13 +195,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSIC_BUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSIC_BUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); From 26d0079ab88d91faa7782c309e085138d8b6cac8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 08:03:10 +0100 Subject: [PATCH 182/690] Removed a pointless line from chipset/sis5581_h2p.c. --- src/chipset/sis_5581_h2p.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c index 48d61f25e..30bd70bfe 100644 --- a/src/chipset/sis_5581_h2p.c +++ b/src/chipset/sis_5581_h2p.c @@ -168,7 +168,6 @@ sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_ uint16_t addr, uint16_t size) { sis_5581_io_trap_t *trap = &dev->io_traps[trap_id]; - enable = enable; /* Set up Device I/O traps dynamically. */ if (enable && !trap->trap) { From 95f95d8481cfc106285de6a0cc407e227bea6466 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 15:55:19 +0600 Subject: [PATCH 183/690] Fix OPL audio not playing --- src/sound/openal.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 1e47cccd7..ddcbf7849 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -154,13 +154,14 @@ inital(void) alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); + alGenBuffers(4, buffers_music); if (init_midi) alGenBuffers(4, buffers_midi); if (init_midi) - alGenSources(3, source); + alGenSources(4, source); else - alGenSources(2, source); + alGenSources(3, source); alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); @@ -172,22 +173,29 @@ inital(void) alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0); alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); if (init_midi) { - alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); - alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[3], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[3], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[3], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); memset(cd_buf, 0, BUFLEN * 2 * sizeof(float)); + memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); memset(cd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); } @@ -195,13 +203,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, music_buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, music_buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); From 3f04b60e3d460266581487c08092c1930280ac96 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 16:21:30 +0600 Subject: [PATCH 184/690] memset cd_buf correctly --- src/sound/openal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index ddcbf7849..f015205f6 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -188,13 +188,13 @@ inital(void) if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); - memset(cd_buf, 0, BUFLEN * 2 * sizeof(float)); + memset(cd_buf, 0, CD_BUFLEN * 2 * sizeof(float)); memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); - memset(cd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + memset(cd_buf_int16, 0, CD_BUFLEN * 2 * sizeof(int16_t)); memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); From 046a8655b5cb8cd96411e594d2680505f16070cb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 12:34:44 +0100 Subject: [PATCH 185/690] Moved E-MU 8000 handling to the non-music handler. --- src/sound/snd_sb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 98b17e3f0..9e50f438f 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -395,6 +395,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + int c_emu8k = 0; double out_l = 0.0; double out_r = 0.0; double bass_treble; @@ -405,6 +406,14 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; + if (sb->dsp.sb_type > SB16) + c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + + if (sb->dsp.sb_type > SB16) { + out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); + } + if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; @@ -460,6 +469,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } sb->dsp.pos = 0; + + if (sb->dsp.sb_type > SB16) + sb->emu8k.pos = 0; } static void @@ -468,7 +480,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k = 0; int c_record; int32_t in_l; int32_t in_r; @@ -487,19 +498,11 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); - if (sb->opl_enabled) { out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; } - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } - /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; @@ -576,9 +579,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (sb->opl_enabled) sb->opl.reset_buffer(sb->opl.priv); - - if (sb->dsp.sb_type > SB16) - sb->emu8k.pos = 0; } void From 45d1e35a7a939ff20fd677af82e6c44acf085462 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 12:35:59 +0100 Subject: [PATCH 186/690] Fixed E-MU 8000 frequency. --- src/sound/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 9e50f438f..2b9432b4e 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -407,7 +407,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_r = 0.0; if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); if (sb->dsp.sb_type > SB16) { out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); From 3727dd9981adbd95fa7165f2f672993d916d7aac Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 13:45:23 +0100 Subject: [PATCH 187/690] SiS 496/497: Implement the reset control bits. --- src/chipset/sis_85c496.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index b9b2544c8..1e9b74f41 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -480,6 +480,8 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0xc6: /* 85C497 Post / INIT Configuration */ dev->pci_conf[addr] = val & 0x0f; + cpu_cpurst_on_sr = !(val & 0x08); + soft_reset_pci = !!(val & 0x04); break; case 0xc8: case 0xc9: @@ -614,6 +616,9 @@ sis_85c496_reset(void *priv) nvr_bank_set(0, 0, dev->nvr); sis_85c497_isa_reset(dev); + + cpu_cpurst_on_sr = 1; + soft_reset_pci = 0; } static void From d77fc474080d97920efff0486cd09f8702757cb5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 13:46:54 +0100 Subject: [PATCH 188/690] E-MU 8000: Update in the correct handler. --- src/sound/snd_sb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2b9432b4e..fb9157dfd 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -402,6 +402,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb_dsp_update(&sb->dsp); + if (sb->dsp.sb_type > SB16) + emu8k_update(&sb->emu8k); + for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; @@ -491,9 +494,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); - for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; From 4335c3e085c248147a4843546f0b9e183859e860 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:27:46 +0500 Subject: [PATCH 189/690] Fix ACPI poweroffs disabling exit confirmations Use confirm_exit_cmdl to skip the confirmation prompt without saving it in the config --- src/qt/qt_platform.cpp | 2 +- src/unix/unix.c | 2 +- src/win/win_ui.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 356334bac..46d50672e 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -413,7 +413,7 @@ void plat_power_off(void) { plat_mouse_capture(0); - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); diff --git a/src/unix/unix.c b/src/unix/unix.c index 6c21bfa45..2a9324307 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -697,7 +697,7 @@ plat_get_exe_name(char *s, int size) void plat_power_off(void) { - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 207158b29..ec4a785ab 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -383,7 +383,7 @@ win_notify_dlg_closed(void) void plat_power_off(void) { - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); From f9ae162e5d7bc6cbf62dd95cddd0d4564bf6312d Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:29:09 +0500 Subject: [PATCH 190/690] Move the EMU8000 ROM path to a macro --- src/include/86box/snd_emu8k.h | 2 ++ src/sound/snd_emu8k.c | 2 +- src/sound/snd_sb.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 090ab662a..d226ed8db 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -406,6 +406,8 @@ void emu8k_close(emu8k_t *emu8k); void emu8k_update(emu8k_t *emu8k); +#define EMU8K_ROM_PATH "roms/sound/creative/awe32.raw" + /* Section E - Introduction to the EMU8000 Chip diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 22435c065..793f8bcb7 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2172,7 +2172,7 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) int c; double out; - fp = rom_fopen("roms/sound/creative/awe32.raw", "rb"); + fp = rom_fopen(EMU8K_ROM_PATH, "rb"); if (!fp) fatal("AWE32.RAW not found\n"); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fb9157dfd..2e63e99c0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2509,7 +2509,7 @@ sb_16_compat_init(const device_t *info) static int sb_awe32_available(void) { - return rom_present("roms/sound/creative/awe32.raw"); + return rom_present(EMU8K_ROM_PATH); } static int From 9a67f05a8f494ace6c5303ec09ad0740bc696157 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:31:34 +0500 Subject: [PATCH 191/690] Move the Sound Blaster PnP ROM paths to macros --- src/sound/snd_sb.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2e63e99c0..5d59d2577 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -43,6 +43,14 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" +#define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" +#define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" +#define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" +#define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" +#define PNP_ROM_SB_AWE64 PNP_ROM_SB_AWE64_VALUE +#define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" + /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ static const double sb_bass_treble_4bits[] = { @@ -2382,13 +2390,13 @@ sb_16_pnp_init(UNUSED(const device_t *info)) static int sb_vibra16xv_available(void) { - return rom_present("roms/sound/creative/CT4170 PnP.BIN"); + return rom_present(PNP_ROM_SB_VIBRA16XV); } static int sb_vibra16c_available(void) { - return rom_present("roms/sound/creative/CT4180 PnP.BIN"); + return rom_present(PNP_ROM_SB_VIBRA16C); } static void * @@ -2430,11 +2438,11 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) const char *pnp_rom_file = NULL; switch (info->local) { case 0: - pnp_rom_file = "roms/sound/creative/CT4170 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_VIBRA16XV; break; case 1: - pnp_rom_file = "roms/sound/creative/CT4180 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_VIBRA16C; break; default: @@ -2515,31 +2523,31 @@ sb_awe32_available(void) static int sb_32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT3600 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_32_PNP); } static int sb_awe32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT3980 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE32_PNP); } static int sb_awe64_value_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_VALUE); } static int sb_awe64_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64); } static int sb_awe64_gold_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4540 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_GOLD); } static void * @@ -2659,20 +2667,23 @@ sb_awe32_pnp_init(const device_t *info) const char *pnp_rom_file = NULL; switch (info->local) { case 0: - pnp_rom_file = "roms/sound/creative/CT3600 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_32_PNP; break; case 1: - pnp_rom_file = "roms/sound/creative/CT3980 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE32_PNP; break; case 2: + pnp_rom_file = PNP_ROM_SB_AWE64_VALUE; + break; + case 3: - pnp_rom_file = "roms/sound/creative/CT4520 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE64; break; case 4: - pnp_rom_file = "roms/sound/creative/CT4540 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE64_GOLD; break; default: From 938fa5bde59616701d881437a0a70fde9e9026d7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:34:59 +0500 Subject: [PATCH 192/690] Add a correct PnP ROM for the CT4380 SB AWE64 Add a correct PnP ROM for the CT4380 "regular" Sound Blaster AWE64 and add quarternary IDE to it to match the new ROM --- src/sound/snd_sb.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 5d59d2577..a82ee21d3 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -48,7 +48,7 @@ #define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" #define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" #define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" -#define PNP_ROM_SB_AWE64 PNP_ROM_SB_AWE64_VALUE +#define PNP_ROM_SB_AWE64 "roms/sound/creative/CTL009DA.BIN" #define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. @@ -1782,6 +1782,27 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } } +static void +sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + sb_t *sb = (sb_t *) priv; + + switch (ld) { + case 0: /* Audio */ + case 2: /* WaveTable */ + sb_16_pnp_config_changed(ld, config, sb); + break; + + case 1: /* Game */ + case 3: /* IDE */ + sb_16_pnp_config_changed(ld ^ 2, config, sb); + break; + + default: + break; + } +} + static void sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -2661,7 +2682,7 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - if ((info->local != 2) && (info->local != 3) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) device_add(&ide_qua_pnp_device); const char *pnp_rom_file = NULL; @@ -2709,8 +2730,11 @@ sb_awe32_pnp_init(const device_t *info) isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb); break; - case 2: case 3: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_pnp_config_changed, NULL, NULL, NULL, sb); + break; + + case 2: case 4: isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -2725,7 +2749,7 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); mpu401_change_addr(sb->mpu, 0); - if ((info->local != 2) && (info->local != 3) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) ide_remove_handlers(3); emu8k_change_addr(&sb->emu8k, 0); From ff6964f73d2b65915866560ba0cf179aa5546d73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 19:26:32 +0100 Subject: [PATCH 193/690] ESDI/MFM AT changes: Make sure they IRQ activations are more IDE-like and correct. --- src/disk/hdc_esdi_at.c | 26 ++++++++++++++------------ src/disk/hdc_st506_at.c | 32 +++++++++++++++++--------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 65184094a..042a6020a 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -129,23 +129,24 @@ esdi_at_log(const char *fmt, ...) static __inline void irq_raise(esdi_t *esdi) { - if (!(esdi->fdisk & 2)) - picint(1 << 14); - esdi->irqstat = 1; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } static __inline void -irq_lower(UNUSED(esdi_t *esdi)) +irq_lower(esdi_t *esdi) { - picintc(1 << 14); + esdi->irqstat = 0; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } static __inline void -irq_update(UNUSED(esdi_t *esdi)) +irq_update(esdi_t *esdi) { - if (esdi->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(esdi->fdisk & 2) && esdi->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } static void @@ -263,6 +264,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) double seek_time; double xfer_time; off64_t addr; + uint8_t old; esdi_at_log("WD1007 write(%04x, %02x)\n", port, val); @@ -411,15 +413,15 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi_set_callback(esdi, 500 * HDC_TIME); esdi->reset = 1; esdi->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(esdi->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ esdi_set_callback(esdi, 0); esdi->status = STAT_BUSY; } + old = esdi->fdisk; esdi->fdisk = val; - irq_update(esdi); + if (!(val & 0x02) && (old & 0x02)) + irq_update(esdi); break; default: diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 41499591d..c8c35d7d5 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -134,26 +134,27 @@ st506_at_log(const char *fmt, ...) # define st506_at_log(fmt, ...) #endif -static inline void +static __inline void irq_raise(mfm_t *mfm) { - if (!(mfm->fdisk & 2)) - picint(1 << 14); - mfm->irqstat = 1; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } -static inline void -irq_lower(UNUSED(mfm_t *mfm)) +static __inline void +irq_lower(mfm_t *mfm) { - picintc(1 << 14); + mfm->irqstat = 0; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } -static void +static __inline void irq_update(mfm_t *mfm) { - if (mfm->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(mfm->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(mfm->fdisk & 2) && mfm->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } /* @@ -378,6 +379,7 @@ static void mfm_write(uint16_t port, uint8_t val, void *priv) { mfm_t *mfm = (mfm_t *) priv; + uint8_t old; st506_at_log("WD1003 write(%04x, %02x)\n", port, val); @@ -408,7 +410,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv) case 0x01f6: /* drive/head */ mfm->head = val & 0xF; - mfm->drvsel = (val & 0x10) ? 1 : 0; + mfm->drvsel = !!(val & 0x10); if (mfm->drives[mfm->drvsel].present) mfm->status = STAT_READY | STAT_DSC; else @@ -425,15 +427,15 @@ mfm_write(uint16_t port, uint8_t val, void *priv) timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); mfm->reset = 1; mfm->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(mfm->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ timer_disable(&mfm->callback_timer); mfm->status = STAT_BUSY; } + old = mfm->fdisk; mfm->fdisk = val; - irq_update(mfm); + if (!(val & 0x02) && (old & 0x02)) + irq_update(mfm); break; default: From 929fa7328d59d1085787c71e91f29cc6461617d9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 19:50:23 +0100 Subject: [PATCH 194/690] Mach8/32 horizontal display changes. Make sure for the 9001st time to display correctly the horizontal side of the display (looking at you, ATI 1992 set for win3.1x and Mach8/32 drivers for OS/2 1.2x). --- src/video/vid_ati_mach8.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 3888e9c26..2613de767 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2596,15 +2596,16 @@ mach_recalctimings(svga_t *svga) mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); - dev->h_disp = dev->hdisp; dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; dev->v_total = dev->vtotal; dev->v_syncstart = dev->vsyncstart; - dev->dispend = dev->vdisp; dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + if (dev->dispend == 766) dev->dispend += 2; @@ -2636,6 +2637,7 @@ mach_recalctimings(svga_t *svga) dev->v_total >>= 1; } + mach_log("HDISP=%d.\n", dev->h_disp); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { @@ -3626,9 +3628,21 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hdisped = val; dev->hdisp = (dev->hdisped + 1) << 3; + if ((dev->hdisp == 640) && ((mach->shadow_set & 0x03) == 0x02) && (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) + svga_recalctimings(svga); + else if ((dev->hdisp == 1024) && !(mach->accel.clock_sel & 0x01) && ((dev->disp_cntl & 0x60) == 0x40)) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->hdisp = 1024; + dev->vdisp = 768; + } else { + dev->hdisp = 640; + dev->vdisp = 480; + } + svga_recalctimings(svga); + } } } - mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc=%x, dispcntl=%02x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 4, dev->disp_cntl & 0x60); + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); break; case 0xae8: @@ -3733,7 +3747,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4, dev->hdisp); svga_recalctimings(svga); break; From af786bec0a597b9b6e893f7aa3eee496bb588fa3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 22:54:31 +0100 Subject: [PATCH 195/690] IDE changes (now for MCA). Added McIDE (MCA IDE) controller for MCA machines that don't have it (PS/2 models 50+). --- src/disk/hdc.c | 1 + src/disk/hdc_ide.c | 298 ++++++++++++++++++++++++++++++++++++++-- src/include/86box/hdc.h | 2 + 3 files changed, 292 insertions(+), 9 deletions(-) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 7bfb7e05a..034b8890e 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -109,6 +109,7 @@ static const struct { { &ide_pci_2ch_device }, { &ide_vlb_device }, { &ide_vlb_2ch_device }, + { &mcide_device }, { NULL } // clang-format on }; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 39031138f..dbb283407 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -30,8 +30,10 @@ #include "cpu.h" #include <86box/machine.h> #include <86box/io.h> +#include <86box/mca.h> #include <86box/mem.h> #include <86box/pic.h> +#include <86box/rom.h> #include <86box/pci.h> #include <86box/rom.h> #include <86box/timer.h> @@ -112,6 +114,8 @@ #define IDE_ATAPI_IS_EARLY ide->sc->pad0 +#define ROM_PATH_MCIDE "roms/hdd/xtide/ide_ps2 R1.1.bin" + typedef struct ide_bm_t { int (*dma)(uint8_t *data, int transfer_length, int out, void *priv); void (*set_irq)(uint8_t status, void *priv); @@ -135,6 +139,12 @@ typedef struct ide_board_t { ide_bm_t *bm; } ide_board_t; +typedef struct mcide_t { + uint8_t pos_regs[8]; + uint32_t bios_addr; + rom_t bios_rom; +} mcide_t; + ide_board_t *ide_boards[IDE_BUS_MAX]; static uint8_t ide_ter_pnp_rom[] = { @@ -2764,9 +2774,9 @@ ide_board_setup(int board) } static void -ide_board_init(int board, int irq, int base_main, int side_main, int type) +ide_board_init(int board, int irq, int base_main, int side_main, int type, int bus) { - ide_log("ide_board_init(%i, %i, %04X, %04X, %i)\n", board, irq, base_main, side_main, type); + ide_log("ide_board_init(%i, %i, %04X, %04X, %i, %i)\n", board, irq, base_main, side_main, type, bus); if ((ide_boards[board] != NULL) && ide_boards[board]->inited) return; @@ -2782,6 +2792,7 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_boards[board]->bit32 = 1; ide_boards[board]->base[0] = base_main; ide_boards[board]->base[1] = side_main; + ide_set_handlers(board); timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); @@ -2834,12 +2845,12 @@ ide_ter_init(const device_t *info) irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(2, -1, 0, 0, 0); + ide_board_init(2, -1, 0, 0, 0, 0); if (irq == -1) isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); } else { - ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0); + ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0, 0); } return (ide_boards[2]); @@ -2866,12 +2877,12 @@ ide_qua_init(const device_t *info) irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(3, -1, 0, 0, 0); + ide_board_init(3, -1, 0, 0, 0, 0); if (irq == -1) isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); } else - ide_board_init(3, irq, HDC_QUATERNARY_BASE, HDC_QUATERNARY_SIDE, 0); + ide_board_init(3, irq, HDC_QUATERNARY_BASE, HDC_QUATERNARY_SIDE, 0, 0); return (ide_boards[3]); } @@ -2886,7 +2897,7 @@ ide_qua_close(UNUSED(void *priv)) void * ide_xtide_init(void) { - ide_board_init(0, -1, 0, 0, 0); + ide_board_init(0, -1, 0, 0, 0, 0); return ide_boards[0]; } @@ -2922,10 +2933,10 @@ ide_init(const device_t *info) switch (info->local) { case 0 ... 5: - ide_board_init(0, 14, 0x1f0, 0x3f6, info->local); + ide_board_init(0, 14, 0x1f0, 0x3f6, info->local, info->flags); if (info->local & 1) - ide_board_init(1, 15, 0x170, 0x376, info->local); + ide_board_init(1, 15, 0x170, 0x376, info->local, info->flags); break; default: @@ -3026,6 +3037,260 @@ ide_close(UNUSED(void *priv)) } } +static uint8_t +mcide_mca_read(int port, void *priv) +{ + const mcide_t *dev = (mcide_t *) priv; + + ide_log("IDE: mcard(%04x)\n", port); + + return (dev->pos_regs[port & 7]); +} + +static void +mcide_mca_write(int port, uint8_t val, void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", + port, val, dev->pos_regs[2], dev->pos_regs[3]); + + if (port < 0x102) + return; + + /* Save the new value. */ + dev->pos_regs[port & 7] = val; + + io_handler(0, ide_boards[0]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[0]); + io_handler(0, ide_boards[1]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[1]); + mem_mapping_disable(&dev->bios_rom.mapping); + + if (dev->pos_regs[2] & 0x80) { + switch ((dev->pos_regs[2] >> 4) & 7) { + case 0: + dev->bios_addr = 0xc0000; + break; + case 1: + dev->bios_addr = 0xc4000; + break; + case 2: + dev->bios_addr = 0xc8000; + break; + case 3: + dev->bios_addr = 0xcc000; + break; + case 4: + dev->bios_addr = 0xd0000; + break; + case 5: + dev->bios_addr = 0xd4000; + break; + case 6: + dev->bios_addr = 0xd8000; + break; + case 7: + dev->bios_addr = 0xd8000; + break; + default: + break; + } + } else { + dev->bios_addr = 0; + } + + if (dev->pos_regs[3] & 0x08) { + switch ((dev->pos_regs[3] & 3)) { + case 0: + ide_boards[0]->base[0] = 0x1f0; + break; + case 1: + ide_boards[0]->base[0] = 0x170; + break; + case 2: + ide_boards[0]->base[0] = 0x1e8; + break; + case 3: + ide_boards[0]->base[0] = 0x168; + break; + default: + break; + } + } else + ide_boards[0]->base[0] = 0; + + if (dev->pos_regs[3] & 0x80) { + switch ((dev->pos_regs[3] >> 5) & 3) { + case 0: + ide_boards[0]->irq = 10; + break; + case 1: + ide_boards[0]->irq = 11; + break; + case 2: + ide_boards[0]->irq = 14; + break; + case 3: + ide_boards[0]->irq = 15; + break; + + default: + break; + } + } else + ide_boards[0]->irq = -1; + + if (dev->pos_regs[4] & 0x08) { + switch ((dev->pos_regs[4] & 3)) { + case 0: + ide_boards[1]->base[0] = 0x1f0; + break; + case 1: + ide_boards[1]->base[0] = 0x170; + break; + case 2: + ide_boards[1]->base[0] = 0x1e8; + break; + case 3: + ide_boards[1]->base[0] = 0x168; + break; + default: + break; + } + } else + ide_boards[1]->base[0] = 0; + + if (dev->pos_regs[4] & 0x80) { + switch ((dev->pos_regs[4] >> 5) & 3) { + case 0: + ide_boards[1]->irq = 10; + break; + case 1: + ide_boards[1]->irq = 11; + break; + case 2: + ide_boards[1]->irq = 14; + break; + case 3: + ide_boards[1]->irq = 15; + break; + + default: + break; + } + } else + ide_boards[1]->irq = -1; + + if (dev->pos_regs[2] & 1) { + if ((dev->pos_regs[3] & 0x88) == 0x88) + io_handler(1, ide_boards[0]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[0]); + + if ((dev->pos_regs[4] & 0x88) == 0x88) + io_handler(1, ide_boards[1]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[1]); + + if (dev->pos_regs[2] & 0x80) { + mem_mapping_enable(&dev->bios_rom.mapping); + mem_mapping_set_addr(&dev->bios_rom.mapping, + dev->bios_addr, 0x2000); + } + + /* Say hello. */ + ide_log("McIDE: Primary I/O=%03x, Primary IRQ=%i, Secondary I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", + ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); + } +} + +static uint8_t +mcide_mca_feedb(void *priv) +{ + const mcide_t *dev = (mcide_t *) priv; + + return (dev->pos_regs[2] & 1); +} + +static void +mcide_mca_reset(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) + ide_board_reset(i); + } + + ide_log("McIDE: MCA Reset.\n"); + mem_mapping_disable(&dev->bios_rom.mapping); + mcide_mca_write(0x102, 0, dev); +} + +static void +mcide_reset(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) + ide_board_reset(i); + } + + ide_log("McIDE: Reset.\n"); +} + +static void * +mcide_init(const device_t *info) +{ + ide_log("Initializing McIDE...\n"); + mcide_t *dev = (mcide_t *) calloc(1, sizeof(mcide_t)); + + ide_board_init(0, -1, 0, 0, info->local, info->flags); + ide_board_init(1, -1, 0, 0, info->local, info->flags); + + rom_init(&dev->bios_rom, ROM_PATH_MCIDE, + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&dev->bios_rom.mapping); + + /* Set the MCA ID for this controller, 0xF171. */ + dev->pos_regs[0] = 0xf1; + dev->pos_regs[1] = 0x71; + + /* Enable the device. */ + mca_add(mcide_mca_read, mcide_mca_write, mcide_mca_feedb, mcide_mca_reset, dev); + + return dev; +} + +static int +mcide_available(void) +{ + return (rom_present(ROM_PATH_MCIDE)); +} + +static void +mcide_close(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) { + ide_board_close(i); + ide_boards[i] = NULL; + } + } + + free(dev); +} + const device_t ide_isa_device = { .name = "ISA PC/AT IDE Controller", .internal_name = "ide_isa", @@ -3110,6 +3375,21 @@ const device_t ide_pci_2ch_device = { .config = NULL }; +const device_t mcide_device = { + .name = "MCA McIDE Controller", + .internal_name = "mcide", + .flags = DEVICE_MCA, + .local = 0, + .init = mcide_init, + .close = mcide_close, + .reset = mcide_reset, + { .available = mcide_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + + // clang-format off static const device_config_t ide_ter_config[] = { { diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index a3d562b62..4f65399bb 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -93,6 +93,8 @@ extern const device_t ide_ter_pnp_device; extern const device_t ide_qua_device; extern const device_t ide_qua_pnp_device; +extern const device_t mcide_device; + extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ extern const device_t xta_hd20_device; /* EuroPC internal */ From 98fa92557063a047c7d8c842ceaf81b2a006cc0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 05:25:27 +0100 Subject: [PATCH 196/690] SB PRO and 16: Do not use the low FIR output filter for CD Audio. --- src/sound/snd_sb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fb9157dfd..466e96a54 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -383,10 +383,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; - if (mixer->output_filter) - c = (sb_iir(2, channel, *buffer) * cd) / 3.9; - else - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } @@ -594,10 +591,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) double bass_treble; double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); - if (mixer->output_filter) - c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0; - else - c = ((*buffer) * cd) / 3.0; + c = ((*buffer) * cd) / 3.0; c *= master; /* This is not exactly how one does bass/treble controls, but the end result is like it. From 1d5a2aaa0f5be5398fad0862a1f44921bc288e91 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 12:50:06 +0100 Subject: [PATCH 197/690] QT UI: Recognize the MCA McIDE as an IDE controller. --- src/qt/qt_machinestatus.cpp | 42 +++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index d7b115a64..59ea960f8 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -297,9 +297,14 @@ MachineStatus::iterateCDROM(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < CDROM_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI) && (cdrom_interface_current == 0)) continue; @@ -315,9 +320,14 @@ MachineStatus::iterateZIP(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < ZIP_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (zip_drives[i].bus_type != 0) { cb(i); @@ -331,9 +341,14 @@ MachineStatus::iterateMO(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < MO_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (mo_drives[i].bus_type != 0) { cb(i); @@ -577,28 +592,30 @@ MachineStatus::refresh(QStatusBar *sbar) }); auto hdc_name = QString(hdc_get_internal_name(hdc_current)); - if ((has_mfm || hdc_name.left(5) == QStringLiteral("st506")) && c_mfm > 0) { + if ((has_mfm || (hdc_name.left(5) == QStringLiteral("st506"))) && (c_mfm > 0)) { d->hdds[HDD_BUS_MFM].label = std::make_unique(); d->hdds[HDD_BUS_MFM].setActive(false); d->hdds[HDD_BUS_MFM].refresh(); d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%s)").replace("%s", "MFM/RLL")); sbar->addWidget(d->hdds[HDD_BUS_MFM].label.get()); } - if ((has_esdi || hdc_name.left(4) == QStringLiteral("esdi")) && c_esdi > 0) { + if ((has_esdi || (hdc_name.left(4) == QStringLiteral("esdi"))) && (c_esdi > 0)) { d->hdds[HDD_BUS_ESDI].label = std::make_unique(); d->hdds[HDD_BUS_ESDI].setActive(false); d->hdds[HDD_BUS_ESDI].refresh(); d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ESDI")); sbar->addWidget(d->hdds[HDD_BUS_ESDI].label.get()); } - if ((has_xta || hdc_name.left(3) == QStringLiteral("xta")) && c_xta > 0) { + if ((has_xta || (hdc_name.left(3) == QStringLiteral("xta"))) && (c_xta > 0)) { d->hdds[HDD_BUS_XTA].label = std::make_unique(); d->hdds[HDD_BUS_XTA].setActive(false); d->hdds[HDD_BUS_XTA].refresh(); d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); } - if (hasIDE() || hdc_name.left(5) == QStringLiteral("xtide") || hdc_name.left(3) == QStringLiteral("ide")) { + if (hasIDE() || (hdc_name.left(5) == QStringLiteral("xtide")) || + (hdc_name.left(5) == QStringLiteral("mcide")) || + (hdc_name.left(3) == QStringLiteral("ide"))) { if (c_ide > 0) { d->hdds[HDD_BUS_IDE].label = std::make_unique(); d->hdds[HDD_BUS_IDE].setActive(false); @@ -614,7 +631,10 @@ MachineStatus::refresh(QStatusBar *sbar) sbar->addWidget(d->hdds[HDD_BUS_ATAPI].label.get()); } } - if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { + if ((hasSCSI() || + (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || + (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && + (c_scsi > 0)) { d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); From 12e367fac6ec4d5547c4492d7d2dacd47619ebd2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 12:51:50 +0100 Subject: [PATCH 198/690] Fixed a warning in disk/hdc_ide.c. --- src/disk/hdc_ide.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index dbb283407..d8df384f1 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -3237,8 +3237,6 @@ mcide_mca_reset(void *priv) static void mcide_reset(void *priv) { - mcide_t *dev = (mcide_t *) priv; - for (uint8_t i = 0; i < 2; i++) { if (ide_boards[i] != NULL) ide_board_reset(i); From 8c6d544d5de7c4a91007ed9dbad136071b477e6f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 2 Mar 2024 15:46:12 +0100 Subject: [PATCH 199/690] IDE/ATAPI port/irq changes for MCA: The ADF is a bit misleading, for pos3 and pos4, the right bits are bits 5-4, not 6-5. Fixes IRQ and added the secondary addresses without conflicting with the FDC, now ATAPI drives work fine. --- src/disk/hdc_ide.c | 73 +++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index dbb283407..833ef4f39 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -2793,7 +2793,8 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type, int b ide_boards[board]->base[0] = base_main; ide_boards[board]->base[1] = side_main; - ide_set_handlers(board); + if (!(bus & DEVICE_MCA)) + ide_set_handlers(board); timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); @@ -3065,10 +3066,18 @@ mcide_mca_write(int port, uint8_t val, void *priv) ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[0]); + io_handler(0, ide_boards[0]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[0]); io_handler(0, ide_boards[1]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[1]); + io_handler(0, ide_boards[1]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[1]); mem_mapping_disable(&dev->bios_rom.mapping); if (dev->pos_regs[2] & 0x80) { @@ -3105,37 +3114,43 @@ mcide_mca_write(int port, uint8_t val, void *priv) } if (dev->pos_regs[3] & 0x08) { - switch ((dev->pos_regs[3] & 3)) { + switch (dev->pos_regs[3] & 3) { case 0: ide_boards[0]->base[0] = 0x1f0; + ide_boards[0]->base[1] = 0x3f6; break; case 1: ide_boards[0]->base[0] = 0x170; + ide_boards[0]->base[1] = 0x376; break; case 2: ide_boards[0]->base[0] = 0x1e8; + ide_boards[0]->base[1] = 0x3ee; break; case 3: ide_boards[0]->base[0] = 0x168; + ide_boards[0]->base[1] = 0x36e; break; default: break; } - } else + } else { ide_boards[0]->base[0] = 0; + ide_boards[0]->base[1] = 0; + } if (dev->pos_regs[3] & 0x80) { - switch ((dev->pos_regs[3] >> 5) & 3) { - case 0: + switch (dev->pos_regs[3] & 0x30) { + case 0x00: ide_boards[0]->irq = 10; break; - case 1: + case 0x10: ide_boards[0]->irq = 11; break; - case 2: + case 0x20: ide_boards[0]->irq = 14; break; - case 3: + case 0x30: ide_boards[0]->irq = 15; break; @@ -3149,34 +3164,40 @@ mcide_mca_write(int port, uint8_t val, void *priv) switch ((dev->pos_regs[4] & 3)) { case 0: ide_boards[1]->base[0] = 0x1f0; + ide_boards[1]->base[1] = 0x3f6; break; case 1: ide_boards[1]->base[0] = 0x170; + ide_boards[1]->base[1] = 0x376; break; case 2: ide_boards[1]->base[0] = 0x1e8; + ide_boards[1]->base[1] = 0x3ee; break; case 3: ide_boards[1]->base[0] = 0x168; + ide_boards[1]->base[1] = 0x36e; break; default: break; } - } else + } else { ide_boards[1]->base[0] = 0; + ide_boards[1]->base[1] = 0; + } if (dev->pos_regs[4] & 0x80) { - switch ((dev->pos_regs[4] >> 5) & 3) { - case 0: + switch (dev->pos_regs[4] & 0x30) { + case 0x00: ide_boards[1]->irq = 10; break; - case 1: + case 0x10: ide_boards[1]->irq = 11; break; - case 2: + case 0x20: ide_boards[1]->irq = 14; break; - case 3: + case 0x30: ide_boards[1]->irq = 15; break; @@ -3187,26 +3208,36 @@ mcide_mca_write(int port, uint8_t val, void *priv) ide_boards[1]->irq = -1; if (dev->pos_regs[2] & 1) { - if ((dev->pos_regs[3] & 0x88) == 0x88) + if (ide_boards[0]->base[0] && ide_boards[0]->base[1]) { io_handler(1, ide_boards[0]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[0]); + io_handler(1, ide_boards[0]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[0]); + } - if ((dev->pos_regs[4] & 0x88) == 0x88) + if (ide_boards[1]->base[0] && ide_boards[1]->base[1]) { io_handler(1, ide_boards[1]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[1]); + io_handler(1, ide_boards[1]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[1]); + } - if (dev->pos_regs[2] & 0x80) { + if (dev->bios_addr) { mem_mapping_enable(&dev->bios_rom.mapping); mem_mapping_set_addr(&dev->bios_rom.mapping, - dev->bios_addr, 0x2000); + dev->bios_addr, 0x4000); } /* Say hello. */ - ide_log("McIDE: Primary I/O=%03x, Primary IRQ=%i, Secondary I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", + ide_log("McIDE: Primary Master I/O=%03x, Primary IRQ=%i, Secondary Master I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); } } @@ -3257,7 +3288,7 @@ mcide_init(const device_t *info) ide_board_init(1, -1, 0, 0, info->local, info->flags); rom_init(&dev->bios_rom, ROM_PATH_MCIDE, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&dev->bios_rom.mapping); /* Set the MCA ID for this controller, 0xF171. */ @@ -3377,7 +3408,7 @@ const device_t ide_pci_2ch_device = { const device_t mcide_device = { .name = "MCA McIDE Controller", - .internal_name = "mcide", + .internal_name = "ide_mcide", .flags = DEVICE_MCA, .local = 0, .init = mcide_init, From e2018775d530b600ad4bacaf19c5aa6bc3a2f9b0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 18:19:00 +0100 Subject: [PATCH 200/690] Implement correct DSR behavior, fixes #3715. --- src/floppy/fdc.c | 27 ++++++++++++++++++++++----- src/include/86box/fdc.h | 3 ++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 8f8fd404e..e16da138d 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -79,7 +79,6 @@ int floppyrate[4]; int fdc_type = 0; -// #define ENABLE_FDC_LOG 1 #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -781,12 +780,27 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (val & 0x80) { + if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - fdc->perp &= 0xfc; - fdc_ctrl_reset(fdc); + fdc->interrupt = -6; } + if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; + + fdc->perp &= 0xfc; + + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + } + } + fdc->dsr = val; return; case 5: /*Command register*/ if ((fdc->stat & 0xf0) == 0xb0) { @@ -1532,6 +1546,9 @@ fdc_callback(void *priv) memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); fdc->reset_stat = 4; return; + case -6: /*DSR Reset clear*/ + fdc->dsr |= 0x80; + return; case 0x01: /* Mode */ fdc->stat = 0x80; fdc->densel_force = (fdc->params[2] & 0xC0) >> 6; diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 37c992a1b..00de511f3 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -115,12 +115,13 @@ typedef struct fdc_t { uint8_t rw_drive; uint8_t lock; + uint8_t dsr; + uint8_t params[15]; uint8_t specify[2]; uint8_t res[11]; uint8_t eot[4]; uint8_t rwc[4]; - uint8_t params[8]; uint16_t pcn[4]; From dc7a105ef2c57cd81da6956db2fd54ff894e0af8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 20:14:24 +0100 Subject: [PATCH 201/690] Give the Compaq Portable III 386 the Compaq 386 chipset and keyboard controller. --- src/machine/m_at_compaq.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 428199de7..cd8c68764 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -795,7 +795,6 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_PORTABLEIII: - case COMPAQ_PORTABLEIII386: if (hdc_current == 1) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) @@ -803,6 +802,16 @@ machine_at_compaq_init(const machine_t *model, int type) machine_at_init(model); break; + case COMPAQ_PORTABLEIII386: + if (hdc_current == 1) + device_add(&ide_isa_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&compaq_plasma_device); + device_add(&compaq_386_device); + machine_at_common_init(model); + device_add(&keyboard_at_compaq_device); + break; + case COMPAQ_DESKPRO386: case COMPAQ_DESKPRO386_05_1988: device_add(&compaq_386_device); From 244038b84cf8ebd38814b53cf15f3461c6d0c34f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 21:24:00 +0100 Subject: [PATCH 202/690] LOCK: It is sometimes legal when cpu_mod == 3, fixes hangs with Compaq Portable III 386 TEST. --- src/cpu/386_common.c | 2 +- src/cpu/x86_ops_misc.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 5c1b95e0f..f3926f170 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -433,7 +433,7 @@ is_lock_legal(uint32_t fetchdat) legal = lock_legal[fetch_dat.b[0]]; if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ else if (legal == 2) { legal = lock_legal_0f[fetch_dat.b[1]]; if (legal == 1) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 519bdbe3c..073327c9c 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -738,9 +738,6 @@ opLOCK(uint32_t fetchdat) legal = is_lock_legal(fetchdat); - if (legal == 4) - pclog("PREFIX: F0 %08X\n", fetchdat); - ILLEGAL_ON(legal == 0); CLOCK_CYCLES(4); From 2fff98423beb9619bff643cac7f70297409db38d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 5 Mar 2024 20:36:33 +0100 Subject: [PATCH 203/690] Added the Everex Maxi Magic EV-165A, closes #2956. --- src/device/isamem.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index 5b880d6eb..8eb4b55f6 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -97,6 +97,7 @@ #define ISAMEM_RAMPAGEXT_CARD 11 #define ISAMEM_ABOVEBOARD_CARD 12 #define ISAMEM_BRAT_CARD 13 +#define ISAMEM_EV165A_CARD 14 #define ISAMEM_DEBUG 0 @@ -452,6 +453,18 @@ isamem_init(const device_t *info) dev->frame_addr = 0xE0000; break; + case ISAMEM_EV165A_CARD: /* Everex Maxi Magic EV-165A */ + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = device_get_config_int("length"); + if (!!device_get_config_int("speed")) + dev->flags |= FLAG_FAST; + if (!!device_get_config_int("ems")) + dev->flags |= FLAG_EMS; + dev->frame_addr = 0xE0000; + break; + case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */ case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */ case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ @@ -1238,6 +1251,115 @@ static const device_t ev159_device = { .config = ev159_config }; +static const device_config_t ev165a_config[] = { + // clang-format off + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 512, + .file_filter = "", + .spinner = { + .min = 0, + .max = 2048, + .step = 512 + }, + .selection = { { 0 } } + }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { + .min = 0, + .max = 896, + .step = 128 + }, + .selection = { { 0 } } + }, + { + .name = "length", + .description = "Contiguous Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { + .min = 0, + .max = 16384, + .step = 128 + }, + .selection = { { 0 } } + }, + { + .name = "speed", + .description = "Transfer Speed", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Standard (150ns)", .value = 0 }, + { .description = "High-Speed (120ns)", .value = 1 }, + { .description = "" } + } + }, + { + .name = "ems", + .description = "EMS mode", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "Enabled", .value = 1 }, + { .description = "" } + }, + }, + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0258, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "208H", .value = 0x0208 }, + { .description = "218H", .value = 0x0218 }, + { .description = "258H", .value = 0x0258 }, + { .description = "268H", .value = 0x0268 }, + { .description = "2A8H", .value = 0x02A8 }, + { .description = "2B8H", .value = 0x02B8 }, + { .description = "2E8H", .value = 0x02E8 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t ev165a_device = { + .name = "Everex Magi Magic EV-165A", + .internal_name = "ev159", + .flags = DEVICE_ISA, + .local = ISAMEM_EV165A_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ev165a_config +}; + #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) static const device_config_t brat_config[] = { // clang-format off @@ -1560,6 +1682,7 @@ static const struct { { &a6pak_device }, { &ems5150_device }, { &ev159_device }, + { &ev165a_device }, #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) { &brat_device }, #endif From 1bfe1bbf7a5dbcc3434ef3b6343139c23f1d101b Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 01:27:25 +0100 Subject: [PATCH 204/690] Removed the speed setting from the Everex 165A. --- src/device/isamem.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 8eb4b55f6..1237a9891 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -458,8 +458,6 @@ isamem_init(const device_t *info) dev->total_size = device_get_config_int("size"); dev->start_addr = device_get_config_int("start"); tot = device_get_config_int("length"); - if (!!device_get_config_int("speed")) - dev->flags |= FLAG_FAST; if (!!device_get_config_int("ems")) dev->flags |= FLAG_EMS; dev->frame_addr = 0xE0000; @@ -1295,20 +1293,6 @@ static const device_config_t ev165a_config[] = { }, .selection = { { 0 } } }, - { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Standard (150ns)", .value = 0 }, - { .description = "High-Speed (120ns)", .value = 1 }, - { .description = "" } - } - }, { .name = "ems", .description = "EMS mode", From 5d486f5faa2f6ab17df6c49271b2ef391fb4f563 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 06:46:53 +0100 Subject: [PATCH 205/690] EV-165A: Fix internal name. --- src/device/isamem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 1237a9891..70f51ce8d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1332,7 +1332,7 @@ static const device_config_t ev165a_config[] = { static const device_t ev165a_device = { .name = "Everex Magi Magic EV-165A", - .internal_name = "ev159", + .internal_name = "ev165a", .flags = DEVICE_ISA, .local = ISAMEM_EV165A_CARD, .init = isamem_init, From 6d1c91c8cefc9a7e85f75f1616ab35e8c5548d20 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 6 Mar 2024 15:10:51 +0600 Subject: [PATCH 206/690] Add Vision Systems LBA Enhancer --- src/86box.c | 4 + src/config.c | 7 ++ src/disk/CMakeLists.txt | 2 +- src/disk/lba_enhancer.c | 97 ++++++++++++++++++++++++ src/include/86box/86box.h | 1 + src/include/86box/hdc.h | 3 + src/qt/qt_settingsstoragecontrollers.cpp | 16 ++++ src/qt/qt_settingsstoragecontrollers.hpp | 4 + src/qt/qt_settingsstoragecontrollers.ui | 85 +++++++++++++++------ 9 files changed, 194 insertions(+), 25 deletions(-) create mode 100644 src/disk/lba_enhancer.c diff --git a/src/86box.c b/src/86box.c index 8218c208c..ca0f8b0ff 100644 --- a/src/86box.c +++ b/src/86box.c @@ -181,6 +181,7 @@ int gfxcard[2] = { 0, 0 }; /* (C) graphic int show_second_monitors = 1; /* (C) show non-primary monitors */ int sound_is_float = 1; /* (C) sound uses FP values */ int voodoo_enabled = 0; /* (C) video option */ +int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */ int ibm8514_standalone_enabled = 0; /* (C) video option */ int xga_standalone_enabled = 0; /* (C) video option */ uint32_t mem_size = 0; /* (C) memory size (Installed on @@ -1226,6 +1227,9 @@ pc_reset_hard_init(void) device_add(&postcard_device); if (unittester_enabled) device_add(&unittester_device); + + if (lba_enhancer_enabled) + device_add(&lba_enhancer_device); if (IS_ARCH(machine, MACHINE_BUS_PCI)) { pci_register_cards(); diff --git a/src/config.c b/src/config.c index 3e4fd7222..9ca148289 100644 --- a/src/config.c +++ b/src/config.c @@ -876,6 +876,8 @@ load_storage_controllers(void) path_normalize(cart_fns[c]); } } + + lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0); } /* Load "Hard Disks" section. */ @@ -2341,6 +2343,11 @@ save_storage_controllers(void) else ini_section_set_string(cat, temp, cart_fns[c]); } + + if (lba_enhancer_enabled == 0) + ini_section_delete_var(cat, "lba_enhancer_enabled"); + else + ini_section_set_int(cat, "lba_enhancer_enabled", 1); } /* Save "Other Peripherals" section. */ diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 310354ccf..87b9593fa 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c - hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c) + hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c lba_enhancer.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c new file mode 100644 index 000000000..07b958b2e --- /dev/null +++ b/src/disk/lba_enhancer.c @@ -0,0 +1,97 @@ +/* + * 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. + * + * Vision Systems LBA Enhancer emulation. + * + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345 + */ + +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/plat_unused.h> + +typedef struct lba_enhancer_t +{ + rom_t rom; +} lba_enhancer_t; + +#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" + +void* lba_enhancer_init(const device_t* info) +{ + lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + return lba_enhancer; +} + +void lba_enhancer_close(void* priv) +{ + lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)priv; + + free(lba_enhancer->rom.rom); + free(priv); + return; +} + +static int +lba_enhancer_available(void) +{ + return rom_present(BIOS_LBA_ENHANCER); +} + +// clang-format off +static const device_config_t lba_enhancer_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xc8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t lba_enhancer_device = { + .name = "Vision Systems LBA Enhancer", + .internal_name = "lba_enhancer", + .flags = DEVICE_AT, + .local = 0, + .init = lba_enhancer_init, + .close = lba_enhancer_close, + .reset = NULL, + { .available = lba_enhancer_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lba_enhancer_config +}; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 20f3fffcc..d44e3b007 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -140,6 +140,7 @@ extern int fpu_type; /* (C) fpu type */ extern int fpu_softfloat; /* (C) fpu uses softfloat */ extern int time_sync; /* (C) enable time sync */ extern int hdd_format_type; /* (C) hard disk file format */ +extern int lba_enhancer_enabled; /* (C) enable Vision Systems LBA Enhancer */ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 4f65399bb..38c0a6e9a 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -103,6 +103,9 @@ extern const device_t xtide_at_device; /* xtide_at */ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ +/* Miscellaneous */ +extern const device_t lba_enhancer_device; + extern void hdc_init(void); extern void hdc_reset(void); diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 30949de3a..0f19d46fc 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -62,6 +62,7 @@ SettingsStorageControllers::save() ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; + lba_enhancer_enabled = ui->checkBoxLbaEnhancer->isChecked() ? 1 : 0; } void @@ -204,6 +205,9 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setChecked(false); ui->checkBoxCassette->setEnabled(false); } + + ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); + ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } void @@ -333,3 +337,15 @@ SettingsStorageControllers::on_pushButtonSCSI4_clicked() { DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } + +void SettingsStorageControllers::on_checkBoxLbaEnhancer_stateChanged(int arg1) +{ + ui->pushButtonConfigureLbaEnhancer->setEnabled(arg1 != 0); +} + + +void SettingsStorageControllers::on_pushButtonConfigureLbaEnhancer_clicked() +{ + DeviceConfig::ConfigureDevice(&lba_enhancer_device); +} + diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index 5641889e4..c50a94574 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -39,6 +39,10 @@ private slots: void on_comboBoxHD_currentIndexChanged(int index); void on_comboBoxCDInterface_currentIndexChanged(int index); + void on_checkBoxLbaEnhancer_stateChanged(int arg1); + + void on_pushButtonConfigureLbaEnhancer_clicked(); + private: Ui::SettingsStorageControllers *ui; int machineId = 0; diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index d67127e2d..16d6e2494 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -51,45 +51,45 @@ - - CD-ROM Controller: - false + + CD-ROM Controller: + - - 30 - false + + 30 + - - Configure - false + + Configure + - - 30 - 0 0 + + 30 + @@ -171,15 +171,15 @@ - - 30 - 0 0 + + 30 + @@ -191,41 +191,41 @@ - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + @@ -266,6 +266,43 @@ + + + + 0 + + + 0 + + + + + Vision Systems LBA Enhancer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Configure + + + + + From 7c241ec64adb10fb346bed58fd6b33648c90ddef Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 22:49:58 +0100 Subject: [PATCH 207/690] Hyundai SUPER-16T: Increase maximum CPU speed to 8 MHz. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index da3dc01e4..d620357d6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -807,7 +807,7 @@ const machine_t machines[] = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, .min_bus = 4772728, - .max_bus = 7159092, + .max_bus = 8000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From 3e6b4aa9e198dbca29fa5437a66e97e4fc0258e2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 22:51:24 +0100 Subject: [PATCH 208/690] S3 Trio64V+ VLB: Limit to a maximum of 2 MB video memory. --- src/video/vid_s3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fe06f05f5..a971c2f65 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -11093,7 +11093,7 @@ const device_t s3_stb_powergraph_64_video_vlb_device = { { .available = s3_stb_powergraph_64_video_available }, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, - .config = s3_standard_config + .config = s3_phoenix_trio32_config }; const device_t s3_phoenix_trio64vplus_onboard_pci_device = { From 2e10c5a870b6c3221b40c7b43d20aecffde128bf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Mar 2024 18:20:55 +0500 Subject: [PATCH 209/690] CMake: Move DirectInput backend option to Win32 UI --- CMakeLists.txt | 1 - src/qt/CMakeLists.txt | 8 +------- src/win/CMakeLists.txt | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cacf1aaa4..ae39fbccf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,6 @@ option(RTMIDI "RtMidi" option(FLUIDSYNTH "FluidSynth" ON) option(MUNT "MUNT" ON) option(VNC "VNC renderer" OFF) -option(DINPUT "DirectInput" OFF) option(CPPTHREADS "C++11 threads" ON) option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4f073cf4a..23c5964b3 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -190,13 +190,7 @@ endif() if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) - target_sources(plat PRIVATE win_dynld.c) - if(DINPUT) - target_sources(plat PRIVATE win_joystick.cpp) - target_link_libraries(86Box dinput8) - else() - target_sources(plat PRIVATE win_joystick_rawinput.c) - endif() + target_sources(plat PRIVATE win_dynld.c win_joystick_rawinput.c) target_link_libraries(86Box hid) # CMake 3.22 messed this up for clang/clang++ diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 604ba9bb0..dc8c53e45 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -51,6 +51,7 @@ if(NOT MINGW) target_sources(plat PRIVATE win_opendir.c) endif() +option(DINPUT "Use DirectInput joystick backend instead of raw input" OFF) if(DINPUT) target_sources(plat PRIVATE win_joystick.cpp) target_link_libraries(86Box dinput8) From 1019953ba5907255d3b314d99602c15d4410a430 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Mar 2024 23:10:38 +0500 Subject: [PATCH 210/690] Add an option to build with SDL joystick backend on Windows --- src/qt/CMakeLists.txt | 12 +++- src/qt/{sdl_joystick.cpp => sdl_joystick.c} | 62 ++++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-) rename src/qt/{sdl_joystick.cpp => sdl_joystick.c} (76%) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 23c5964b3..5dc6f8a07 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -190,8 +190,7 @@ endif() if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) - target_sources(plat PRIVATE win_dynld.c win_joystick_rawinput.c) - target_link_libraries(86Box hid) + target_sources(plat PRIVATE win_dynld.c) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 @@ -206,8 +205,15 @@ if(WIN32) if (MINGW) add_compile_definitions(NTDDI_VERSION=0x06010000) endif() + + option(SDL_JOYSTICK "Use SDL2 joystick backend instead of raw input" OFF) +endif() + +if(WIN32 AND NOT SDL_JOYSTICK) + target_sources(plat PRIVATE win_joystick_rawinput.c) + target_link_libraries(86Box hid) else() - target_sources(plat PRIVATE sdl_joystick.cpp) + target_sources(plat PRIVATE sdl_joystick.c) endif() if(WIN32 AND NOT MINGW) diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.c similarity index 76% rename from src/qt/sdl_joystick.cpp rename to src/qt/sdl_joystick.c index 4437bb696..d56612872 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.c @@ -1,28 +1,53 @@ -// Lifted from wx-sdl2-joystick.c in PCem - +/* + * 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. + * + * SDL2 joystick interface. + * + * + * + * Authors: Sarah Walker, + * Joakim L. Gilje + * + * Copyright 2017-2021 Sarah Walker + * Copyright 2021 Joakim L. Gilje + */ #include -#include - -extern "C" { +#include +#include +#include +#include +#include +#define _USE_MATH_DEFINES +#include +/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ +#undef HAVE_STDARG_H +#define HAVE_STDARG_H +#include <86box/86box.h> #include <86box/device.h> #include <86box/gameport.h> +#include <86box/plat_unused.h> int joysticks_present; joystick_t joystick_state[MAX_JOYSTICKS]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; -} - -#include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif void -joystick_init() +joystick_init(void) { + /* This is needed for SDL's Windows raw input backend to work properly without SDL video. */ + SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; } @@ -36,9 +61,9 @@ joystick_init() int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); - plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); - plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); + plat_joystick_state[c].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); + plat_joystick_state[c].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); + plat_joystick_state[c].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); @@ -57,7 +82,7 @@ joystick_init() } void -joystick_close() +joystick_close(void) { int c; @@ -103,8 +128,9 @@ joystick_get_axis(int joystick_nr, int mapping) } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } + void -joystick_process() +joystick_process(void) { int c; int d; @@ -160,3 +186,11 @@ joystick_process() } } } + +#ifdef _WIN32 +void +win_joystick_handle(UNUSED(void *raw)) +{ + /* Nothing to be done here, atleast currently */ +} +#endif From 9488078c5ab8c3c76878809fcb49698f7a08212b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 8 Mar 2024 16:45:17 +0600 Subject: [PATCH 211/690] Work-In-Progress modem emulation --- src/86box.c | 7 +- src/device/serial.c | 40 +++ src/include/86box/serial.h | 8 + src/network/CMakeLists.txt | 2 +- src/network/net_modem.c | 706 +++++++++++++++++++++++++++++++++++++ 5 files changed, 759 insertions(+), 4 deletions(-) create mode 100644 src/network/net_modem.c diff --git a/src/86box.c b/src/86box.c index ca0f8b0ff..9cdb5f4e5 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1168,13 +1168,14 @@ pc_reset_hard_init(void) /* note: PLIP LPT side has to be initialized before the network side */ lpt_devices_init(); - /* Reset and reconfigure the Network Card layer. */ - network_reset(); - /* Reset and reconfigure the serial ports. */ + /* note: SLIP COM side has to be initialized before the network side */ serial_standalone_init(); serial_passthrough_init(); + /* Reset and reconfigure the Network Card layer. */ + network_reset(); + /* * Reset the mouse, this will attach it to any port needed. */ diff --git a/src/device/serial.c b/src/device/serial.c index dcdffb71c..0ef959cdd 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -432,6 +432,25 @@ serial_set_dcd(serial_t *dev, uint8_t enabled) } } +void +serial_set_ri(serial_t *dev, uint8_t enabled) +{ + uint8_t prev_state = !!(dev->msr & 0x40); + if (dev->mctrl & 0x10) + return; + + dev->msr &= ~0x40; + dev->msr |= (!!enabled) << 6; + dev->msr_set &= ~0x40; + dev->msr_set |= (!!enabled) << 6; + + if (prev_state == 0 && (!!enabled) == 1) { + dev->msr |= 0x4; + dev->int_status |= SERIAL_INT_MSR; + serial_update_ints(dev); + } +} + void serial_set_clock_src(serial_t *dev, double clock_src) { @@ -570,6 +589,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) serial_do_irq(dev, 0); if ((val ^ dev->mctrl) & 0x10) serial_reset_fifo(dev); + if (dev->sd && dev->sd->dtr_callback) + dev->sd->dtr_callback(dev, val, dev->sd->priv); dev->mctrl = val; if (val & 0x10) { new_msr = (val & 0x0c) << 4; @@ -797,6 +818,25 @@ serial_attach_ex(int port, return sd->serial; } +serial_t * +serial_attach_ex_2(int port, + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*dtr_callback)(struct serial_s *serial, int status, void *priv), + void *priv) +{ + serial_device_t *sd = &serial_devices[port]; + + sd->rcr_callback = rcr_callback; + sd->dtr_callback = dtr_callback; + sd->dev_write = dev_write; + sd->transmit_period_callback = NULL; + sd->lcr_callback = NULL; + sd->priv = priv; + + return sd->serial; +} + static void serial_speed_changed(void *priv) { diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 08f77ea13..99b39f56b 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -92,6 +92,7 @@ typedef struct serial_s { typedef struct serial_device_s { void (*rcr_callback)(struct serial_s *serial, void *priv); + void (*dtr_callback)(struct serial_s *serial, int status, void *priv); void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data); void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t lcr); void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period); @@ -112,6 +113,12 @@ extern serial_t *serial_attach_ex(int port, void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t data_bits), void *priv); +extern serial_t *serial_attach_ex_2(int port, + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*dtr_callback)(struct serial_s *serial, int status, void *priv), + void *priv); + #define serial_attach(port, rcr_callback, dev_write, priv) \ serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv); @@ -129,6 +136,7 @@ extern void serial_device_timeout(void *priv); extern void serial_set_cts(serial_t *dev, uint8_t enabled); extern void serial_set_dsr(serial_t *dev, uint8_t enabled); extern void serial_set_dcd(serial_t *dev, uint8_t enabled); +extern void serial_set_ri(serial_t *dev, uint8_t enabled); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index b0ba913d5..5eb091d58 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -15,7 +15,7 @@ set(net_sources) list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c) + net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) diff --git a/src/network/net_modem.c b/src/network/net_modem.c new file mode 100644 index 000000000..0137aa9bb --- /dev/null +++ b/src/network/net_modem.c @@ -0,0 +1,706 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/fifo.h> +#include <86box/fifo8.h> +#include <86box/timer.h> +#include <86box/serial.h> +#include <86box/network.h> +#include <86box/plat_unused.h> + +/* From RFC 1055. */ +#define END 0300 /* indicates end of packet */ +#define ESC 0333 /* indicates byte stuffing */ +#define ESC_END 0334 /* ESC ESC_END means END data byte */ +#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ + +typedef enum ResTypes { + ResNONE, + ResOK, + ResERROR, + ResCONNECT, + ResRING, + ResBUSY, + ResNODIALTONE, + ResNOCARRIER, + ResNOANSWER +} ResTypes; + +enum modem_types +{ + MODEM_TYPE_SLIP = 1, + MODEM_TYPE_PPP = 2, + MODEM_TYPE_TCPIP = 3 +}; + +typedef enum modem_mode_t +{ + MODEM_MODE_COMMAND = 0, + MODEM_MODE_DATA = 1 +} modem_mode_t; + +typedef struct modem_t +{ + uint8_t mac[6]; + serial_t *serial; + double baudrate; + + modem_mode_t mode; + + uint8_t esc_character_expected; + pc_timer_t host_to_serial_timer; + pc_timer_t dtr_timer; + + uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ + uint32_t tx_count; + + Fifo8 rx_data; /* Data received from the network. */ + uint8_t reg[100]; + + Fifo8 data_pending; /* Data yet to be sent to the host. */ + + char cmdbuf[512]; + uint32_t cmdpos; + int plusinc, flowcontrol; + int in_warmup; + + bool connected, ringing; + bool echo, numericresponse; + + int doresponse; + + netcard_t *card; +} modem_t; + +static modem_t *instance; + +#define MREG_AUTOANSWER_COUNT 0 +#define MREG_RING_COUNT 1 +#define MREG_ESCAPE_CHAR 2 +#define MREG_CR_CHAR 3 +#define MREG_LF_CHAR 4 +#define MREG_BACKSPACE_CHAR 5 +#define MREG_GUARD_TIME 12 +#define MREG_DTR_DELAY 25 + +static uint32_t +modem_scan_number(char **scan) +{ + char c = 0; + uint32_t ret = 0; + while (1) { + c = **scan; + if (c == 0) + break; + if (c >= '0' && c <= '9') { + ret*=10; + ret+=c-'0'; + *scan = *scan + 1; + } else + break; + } + return ret; +} + +static uint8_t +modem_fetch_character(char **scan) +{ + uint8_t c = **scan; + *scan = *scan + 1; + return c; +} + +static void +modem_speed_changed(void *priv) +{ + modem_t *dev = (modem_t *) priv; + if (!dev) + return; + + timer_stop(&dev->host_to_serial_timer); + /* FIXME: do something to dev->baudrate */ + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * 9); +#if 0 + serial_clear_fifo(dev->serial); +#endif +} + +static void +modem_send_line(modem_t* modem, const char* line) +{ + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push_all(&modem->data_pending, (uint8_t*)line, strlen(line)); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); +} + + +static void +modem_send_number(modem_t* modem, uint32_t val) +{ + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + + fifo8_push(&modem->data_pending, val / 100 + '0'); + val = val%100; + fifo8_push(&modem->data_pending, val / 10 + '0'); + val = val%10; + fifo8_push(&modem->data_pending, val + '0'); + + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); +} + +static void +process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) +{ + int received = 0; + uint32_t pos = 0; + uint8_t *processed_tx_packet = calloc(len, 1); + uint8_t c = 0; + + while (pos < len) { + c = p[pos]; + pos++; + switch (c) { + case END: + if (received) + goto send_tx_packet; + else + break; + + case ESC: + { + c = p[pos]; + pos++; + + switch (c) { + case ESC_END: + c = END; + break; + case ESC_ESC: + c = ESC; + break; + } + } + + default: + if (received < len) + processed_tx_packet[received++] = c; + break; + } + } + +send_tx_packet: + network_tx(modem->card, processed_tx_packet, received); + return; +} + +static void +modem_data_mode_process_byte(modem_t* modem, uint8_t data) +{ + if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { + if (modem->reg[MREG_ESCAPE_CHAR] == data) { + return; + } + } + + if (data == END) { + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count + 1ul); + } + else if (modem->tx_count < 0x10000) + modem->tx_pkt_ser_line[modem->tx_count++] = data; +} + +static void +host_to_modem_cb(void *priv) +{ + modem_t* modem = (modem_t*)priv; + + if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { + if (fifo_get_full(modem->serial->rcvr_fifo)) { + goto no_write_to_machine; + } + } else { + if (modem->serial->lsr & 1) { + goto no_write_to_machine; + } + } + + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { + serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); + } else if (fifo8_num_used(&modem->data_pending)) { + serial_write_fifo(modem->serial, fifo8_pop(&modem->data_pending)); + } + +no_write_to_machine: + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / modem->baudrate) * (double)9); +} + +static void +modem_write(UNUSED(serial_t *s), void *priv, uint8_t val) +{ + modem_t* modem = (modem_t*)priv; +} + +void modem_send_res(modem_t* modem, const ResTypes response) { + const char* response_str = NULL; + uint32_t code = -1; + switch (response) { + case ResOK: code = 0; response_str = "OK"; break; + case ResCONNECT: code = 1; response_str = "CONNECT 33600"; break; + case ResRING: code = 2; response_str = "RING"; break; + case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; + case ResERROR: code = 4; response_str = "ERROR"; break; + case ResNODIALTONE: code = 6; response_str = "NO DIALTONE"; break; + case ResBUSY: code = 7; response_str = "BUSY"; break; + case ResNOANSWER: code = 8; response_str = "NO ANSWER"; break; + case ResNONE: return; + } + + if (modem->doresponse != 1) { + if (modem->doresponse == 2 && (response == ResRING || + response == ResCONNECT || response == ResNOCARRIER)) { + return; + } + if (modem->numericresponse && code != ~0) { + modem_send_number(modem, code); + } else if (response_str != NULL) { + modem_send_line(modem, response_str); + } + + // if(CSerial::CanReceiveByte()) // very fast response + // if(rqueue->inuse() && CSerial::getRTS()) + // { uint8_t rbyte =rqueue->getb(); + // CSerial::receiveByte(rbyte); + // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", + // GetPortNumber(), rbyte); + // } + } +} + +void +modem_enter_idle_state(modem_t* modem) +{ + timer_disable(&modem->dtr_timer); + modem->connected = false; + modem->ringing = false; + modem->mode = MODEM_MODE_COMMAND; + modem->in_warmup = 0; + serial_set_cts(modem->serial, 1); + serial_set_dsr(modem->serial, 1); + serial_set_dcd(modem->serial, 0); + serial_set_ri(modem->serial, 0); +} + +void +modem_enter_connected_state(modem_t* modem) +{ + modem_send_res(modem, ResCONNECT); + modem->mode = MODEM_MODE_DATA; + modem->ringing = false; + modem->connected = true; + serial_set_dcd(modem->serial, 1); + serial_set_ri(modem->serial, 0); +} + +void +modem_reset(modem_t* modem) +{ + modem_enter_idle_state(modem); + modem->cmdpos = 0; + modem->cmdbuf[0] = 0; + modem->flowcontrol = 0; + modem->plusinc = 0; + + memset(&modem->reg,0,sizeof(modem->reg)); + modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer + modem->reg[MREG_RING_COUNT] = 1; + modem->reg[MREG_ESCAPE_CHAR] = '+'; + modem->reg[MREG_CR_CHAR] = '\r'; + modem->reg[MREG_LF_CHAR] = '\n'; + modem->reg[MREG_BACKSPACE_CHAR] = '\b'; + modem->reg[MREG_GUARD_TIME] = 50; + modem->reg[MREG_DTR_DELAY] = 5; + + modem->echo = true; + modem->doresponse = 0; + modem->numericresponse = false; +} + +void +modem_dial(modem_t* modem, const char* str) +{ + /* TODO: Port TCP/IP support from DOSBox. */ + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { + modem_enter_connected_state(modem); + } else { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + } +} + +static bool +is_next_token(const char* a, size_t N, const char *b) +{ + // Is 'b' at least as long as 'a'? + size_t N_without_null = N - 1; + if (strnlen(b, N) < N_without_null) + return false; + return (strncmp(a, b, N_without_null) == 0); +} + +// https://stackoverflow.com/a/122974 +char *trim(char *str) +{ + size_t len = 0; + char *frontp = str; + char *endp = NULL; + + if( str == NULL ) { return NULL; } + if( str[0] == '\0' ) { return str; } + + len = strlen(str); + endp = str + len; + + /* Move the front and back pointers to address the first non-whitespace + * characters from each end. + */ + while( isspace((unsigned char) *frontp) ) { ++frontp; } + if( endp != frontp ) + { + while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + } + + if( frontp != str && endp == frontp ) + *str = '\0'; + else if( str + len - 1 != endp ) + *(endp + 1) = '\0'; + + /* Shift the string so that it starts at str so that if it's dynamically + * allocated, we can still free it on the returned pointer. Note the reuse + * of endp to mean the front of the string buffer now. + */ + endp = str; + if( frontp != str ) + { + while( *frontp ) { *endp++ = *frontp++; } + *endp = '\0'; + } + + return str; +} + +static void +modem_do_command(modem_t* modem) +{ + int i = 0; + char *scanbuf = NULL; + modem->cmdbuf[modem->cmdpos] = 0; + modem->cmdpos = 0; + for (i = 0; i < sizeof(modem->cmdbuf); i++) { + modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); + } + + /* AT command set interpretation */ + if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { + modem_send_res(modem, ResERROR); + return; + } + + scanbuf = &modem->cmdbuf[2]; + + while (1) { + char chr = modem_fetch_character(&scanbuf); + switch (chr) { + case '+': + /* None supported yet. */ + modem_send_res(modem, ResERROR); + return; + case 'D': { // Dial. + char buffer[128]; + char obuffer[128]; + char * foundstr = &scanbuf[0]; + size_t i = 0; + if (*foundstr == 'T' || *foundstr == 'P') + foundstr++; + + if ((!foundstr[0]) || (strlen(foundstr) > 253)) { + modem_send_res(modem, ResERROR); + return; + } + + foundstr = trim(foundstr); + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + size_t fl = strlen(foundstr); + for (i = 0; i < fl; i++) + if (foundstr[i] < '0' || foundstr[i] > '9') + isNum = false; + if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + size_t j = 0; + const size_t foundlen = strlen(foundstr); + for (i = 0; i < foundlen; i++) { + buffer[j++] = foundstr[i]; + // Add a dot after the third, sixth and ninth number + if (i == 2 || i == 5 || i == 8) + buffer[j++] = '.'; + // If the string is longer than 12 digits, + // interpret the rest as port + if (i == 11 && foundlen > 12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + + // Remove Zeros from beginning of octets + size_t k = 0; + size_t foundlen2 = strlen(foundstr); + for (i = 0; i < foundlen2; i++) { + if (i == 0 && foundstr[0] == '0') continue; + if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') continue; + if (foundstr[i] == '0' && foundstr[i-1] == '.') continue; + if (foundstr[i] == '0' && foundstr[i-1] == '0' && foundstr[i-2] == '.') continue; + obuffer[k++] = foundstr[i]; + } + obuffer[k] = 0; + foundstr = obuffer; + } + } + modem_dial(modem, foundstr); + } + case 'I': // Some strings about firmware + switch (modem_scan_number(&scanbuf)) { + case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; + case 4: modem_send_line(modem, "Modem compiled for 86Box"); break; + } + break; + case 'E': // Echo on/off + switch (modem_scan_number(&scanbuf)) { + case 0: modem->echo = false; break; + case 1: modem->echo = true; break; + } + break; + case 'V': + switch (modem_scan_number(&scanbuf)) { + case 0: modem->numericresponse = true; break; + case 1: modem->numericresponse = false; break; + } + break; + case 'H': // Hang up + switch (modem_scan_number(&scanbuf)) { + case 0: + if (modem->connected) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + // else return ok + } + break; + case 'O': // Return to data mode + switch (modem_scan_number(&scanbuf)) { + case 0: + if (modem->connected) { + modem->mode = MODEM_MODE_DATA; + return; + } else { + modem_send_res(modem, ResERROR); + return; + } + } + break; + case 'T': // Tone Dial + case 'P': // Pulse Dial + break; + case 'M': // Monitor + case 'L': // Volume + modem_scan_number(&scanbuf); + break; + case 'A': // Answer call + { + modem_send_res(modem, ResERROR); + return; + } + return; + case 'Z': { // Reset and load profiles + // scan the number away, if any + modem_scan_number(&scanbuf); + if (modem->connected) + modem_send_res(modem, ResNOCARRIER); + modem_reset(modem); + break; + } + case ' ': // skip space + break; + case 'Q': { + // Response options + // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + const uint32_t val = modem_scan_number(&scanbuf); + if (!(val > 2)) { + modem->doresponse = val; + break; + } else { + modem_send_res(modem, ResERROR); + return; + } + } + } + } +} + +void +modem_dtr_callback(serial_t* serial, int status, void *priv) +{ + modem_t *dev = (modem_t *) priv; + if (status == 1) + timer_disable(&dev->dtr_timer); + else if (!timer_is_enabled(&dev->dtr_timer)) + timer_enable(&dev->dtr_timer); +} + +static void +fifo8_resize_2x(Fifo8* fifo) +{ + uint32_t pos = 0; + uint32_t size = fifo->capacity * 2; + uint32_t used = fifo8_num_used(fifo); + if (!used) + return; + + uint8_t* temp_buf = calloc(fifo->capacity * 2, 1); + if (!temp_buf) { + fatal("net_modem: Out Of Memory!\n"); + } + while (!fifo8_is_empty(fifo)) { + temp_buf[pos] = fifo8_pop(fifo); + pos++; + } + pos = 0; + fifo8_destroy(fifo); + fifo8_create(fifo, size); + fifo8_push_all(fifo, temp_buf, used); + free(temp_buf); +} + + +static int +modem_rx(void *priv, uint8_t *buf, int io_len) +{ + modem_t* modem = (modem_t*)priv; + uint8_t c = 0; + uint32_t i = 0; + + if ((io_len) < (fifo8_num_free(&modem->rx_data) / 2)) { + fifo8_resize_2x(&modem->rx_data); + } + + fifo8_push(&modem->rx_data, END); + for (i = 0; i < io_len; i++) { + switch (buf[i]) { + case END: + fifo8_push(&modem->rx_data, ESC); + fifo8_push(&modem->rx_data, ESC_END); + break; + case ESC: + fifo8_push(&modem->rx_data, ESC); + fifo8_push(&modem->rx_data, ESC_ESC); + break; + default: + fifo8_push(&modem->rx_data, buf[i]); + break; + } + } + fifo8_push(&modem->rx_data, END); + return 1; +} + +static void +modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) +{ + modem_t *dev = (modem_t *) priv; + + timer_stop(&dev->host_to_serial_timer); + /* FIXME: do something to dev->baudrate */ + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) 9); +#if 0 + serial_clear_fifo(dev->serial); +#endif +} + +/* Initialize the device for use by the user. */ +static void * +modem_init(const device_t *info) +{ + modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); + memset(modem->mac, 0xfc, 6); + + modem->card = network_attach(instance, instance->mac, modem_rx, NULL); + return modem; +} + +void modem_close(void *priv) +{ + free(priv); +} + +static const device_config_t modem_config[] = { + { + .name = "baudrate", + .description = "Baud Rate", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 115200, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { +#if 0 + { .description = "256000", .value = 256000 }, + { .description = "128000", .value = 128000 }, +#endif + { .description = "115200", .value = 115200 }, + { .description = "57600", .value = 57600 }, + { .description = "56000", .value = 56000 }, + { .description = "38400", .value = 38400 }, + { .description = "19200", .value = 19200 }, + { .description = "14400", .value = 14400 }, + { .description = "9600", .value = 9600 }, + { .description = "7200", .value = 7200 }, + { .description = "4800", .value = 4800 }, + { .description = "2400", .value = 2400 }, + { .description = "1800", .value = 1800 }, + { .description = "1200", .value = 1200 }, + { .description = "600", .value = 600 }, + { .description = "300", .value = 300 }, + } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t modem_device = { + .name = "Standard Hayes-compliant Modem", + .flags = 0, + .local = 0, + .init = modem_init, + .close = modem_close, + .reset = NULL, + { .poll = NULL }, + .speed_changed = modem_speed_changed, + .force_redraw = NULL, + .config = modem_config +}; From ec8b8f2a920657e2fe9490a6d0bd148057c1b3fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 01:37:13 +0600 Subject: [PATCH 212/690] Somewhat finish initial modem emulation --- src/device/serial.c | 4 +- src/include/86box/network.h | 3 + src/network/net_modem.c | 265 +++++++++++++++++++++++++++++++++--- src/network/network.c | 1 + 4 files changed, 252 insertions(+), 21 deletions(-) diff --git a/src/device/serial.c b/src/device/serial.c index 0ef959cdd..b61c8304a 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -589,8 +589,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) serial_do_irq(dev, 0); if ((val ^ dev->mctrl) & 0x10) serial_reset_fifo(dev); - if (dev->sd && dev->sd->dtr_callback) - dev->sd->dtr_callback(dev, val, dev->sd->priv); + if (dev->sd && dev->sd->dtr_callback && (val ^ dev->mctrl) & 1) + dev->sd->dtr_callback(dev, val & 1, dev->sd->priv); dev->mctrl = val; if (val & 0x10) { new_msr = (val & 0x0c) << 4; diff --git a/src/include/86box/network.h b/src/include/86box/network.h index d0af3f09b..9588de86a 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -225,6 +225,9 @@ extern const device_t pcnet_am79c970a_device; extern const device_t pcnet_am79c973_device; extern const device_t pcnet_am79c973_onboard_device; +/* Modem */ +extern const device_t modem_device; + /* PLIP */ #ifdef EMU_LPT_H extern const lpt_device_t lpt_plip_device; diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 0137aa9bb..4127158bd 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -52,13 +52,14 @@ typedef struct modem_t { uint8_t mac[6]; serial_t *serial; - double baudrate; + uint32_t baudrate; modem_mode_t mode; uint8_t esc_character_expected; pc_timer_t host_to_serial_timer; pc_timer_t dtr_timer; + pc_timer_t cmdpause_timer; uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ uint32_t tx_count; @@ -70,13 +71,25 @@ typedef struct modem_t char cmdbuf[512]; uint32_t cmdpos; + uint32_t port; int plusinc, flowcontrol; - int in_warmup; + int in_warmup, dtrmode; bool connected, ringing; bool echo, numericresponse; int doresponse; + int cmdpause; + + struct { + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + bool inIAC; + bool recCommand; + uint8_t command; + } telClient; netcard_t *card; } modem_t; @@ -92,6 +105,14 @@ static modem_t *instance; #define MREG_GUARD_TIME 12 #define MREG_DTR_DELAY 25 +static void modem_do_command(modem_t* modem); + +static void +modem_echo(modem_t* modem, uint8_t c) +{ + if (modem->echo && fifo8_num_free(&modem->data_pending)) fifo8_push(&modem->data_pending, c); +} + static uint32_t modem_scan_number(char **scan) { @@ -128,7 +149,7 @@ modem_speed_changed(void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * 9); #if 0 serial_clear_fifo(dev->serial); #endif @@ -210,16 +231,20 @@ static void modem_data_mode_process_byte(modem_t* modem, uint8_t data) { if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { - if (modem->reg[MREG_ESCAPE_CHAR] == data) { - return; + if (modem->plusinc >= 1 && modem->plusinc <= 3 && modem->reg[MREG_ESCAPE_CHAR] == data) { + modem->plusinc++; + } else { + modem->plusinc = 0; } } - if (data == END) { - process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count + 1ul); - } - else if (modem->tx_count < 0x10000) + if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; + if (data == END) { + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); + modem->tx_count = 0; + } + } } static void @@ -237,6 +262,9 @@ host_to_modem_cb(void *priv) } } + if (!((modem->serial->mctrl & 2) || modem->flowcontrol != 3)) + goto no_write_to_machine; + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { @@ -244,13 +272,55 @@ host_to_modem_cb(void *priv) } no_write_to_machine: - timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / modem->baudrate) * (double)9); + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); } static void -modem_write(UNUSED(serial_t *s), void *priv, uint8_t val) +modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) { modem_t* modem = (modem_t*)priv; + + if (modem->mode == MODEM_MODE_COMMAND) { + if (modem->cmdpos < 2) { + // Ignore everything until we see "AT" sequence. + if (modem->cmdpos == 0 && toupper(txval) != 'A') { + return; + } + + if (modem->cmdpos == 1 && toupper(txval) != 'T') { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + return; + } + } else { + // Now entering command. + if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { + if (modem->cmdpos > 2) { + modem_echo(modem, txval); + modem->cmdpos--; + } + return; + } + + if (txval == modem->reg[MREG_LF_CHAR]) { + return; // Real modem doesn't seem to skip this? + } + + if (txval == modem->reg[MREG_CR_CHAR]) { + modem_echo(modem, txval); + modem_do_command(modem); + return; + } + + if (modem->cmdpos < 99) { + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; + } + } + } else { + modem_data_mode_process_byte(modem, txval); + } } void modem_send_res(modem_t* modem, const ResTypes response) { @@ -310,6 +380,7 @@ modem_enter_connected_state(modem_t* modem) modem->mode = MODEM_MODE_DATA; modem->ringing = false; modem->connected = true; + memset(&modem->telClient, 0, sizeof(modem->telClient)); serial_set_dcd(modem->serial, 1); serial_set_ri(modem->serial, 0); } @@ -322,6 +393,7 @@ modem_reset(modem_t* modem) modem->cmdbuf[0] = 0; modem->flowcontrol = 0; modem->plusinc = 0; + modem->dtrmode = 2; memset(&modem->reg,0,sizeof(modem->reg)); modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer @@ -560,6 +632,107 @@ modem_do_command(modem_t* modem) return; } } + + case 'S': { // Registers + const uint32_t index = modem_scan_number(&scanbuf); + if (index >= 100) { + modem_send_res(modem, ResERROR); + return; //goto ret_none; + } + + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + + if (scanbuf[0] == '=') { // set register + scanbuf++; + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + const uint32_t val = modem_scan_number(&scanbuf); + modem->reg[index] = val; + break; + } + else if (scanbuf[0] == '?') { // get register + modem_send_number(modem, modem->reg[index]); + scanbuf++; + break; + } + // else + // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 + // " with %" PRIu8 ".", + // GetPortNumber(), index, reg[index]); + } + break; + case '&': { // & escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch(cmdchar) { + case 'K': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 5) + modem->flowcontrol = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'D': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 4) + modem->dtrmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\\': { // \ escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'N': + // error correction stuff - not emulated + if (modem_scan_number(&scanbuf) > 5) { + modem_send_res(modem, ResERROR); + return; + } + break; + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + modem_send_res(modem, ResOK); + return; + } + } +} + +void +modem_dtr_callback_timer(void* priv) +{ + modem_t *dev = (modem_t *) priv; + if (dev->connected) { + switch (dev->dtrmode) { + case 1: + dev->mode = MODEM_MODE_COMMAND; + break; + case 2: + modem_send_res(dev, ResNOCARRIER); + modem_enter_idle_state(dev); + break; + case 3: + modem_send_res(dev, ResNOCARRIER); + modem_reset(dev); + break; } } } @@ -571,7 +744,7 @@ modem_dtr_callback(serial_t* serial, int status, void *priv) if (status == 1) timer_disable(&dev->dtr_timer); else if (!timer_is_enabled(&dev->dtr_timer)) - timer_enable(&dev->dtr_timer); + timer_on_auto(&dev->dtr_timer, 1000000); } static void @@ -606,7 +779,12 @@ modem_rx(void *priv, uint8_t *buf, int io_len) uint8_t c = 0; uint32_t i = 0; - if ((io_len) < (fifo8_num_free(&modem->rx_data) / 2)) { + if (!modem->connected) { + /* Drop packet. */ + return 0; + } + + if ((io_len) <= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } @@ -637,12 +815,31 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * (double) 9); #if 0 serial_clear_fifo(dev->serial); #endif } +static void +modem_cmdpause_timer_callback(void *priv) +{ + modem_t *dev = (modem_t *) priv; + uint32_t guard_threashold = 0; + + dev->cmdpause++; + guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); + if (dev->cmdpause > guard_threashold) { + if (dev->plusinc == 0) { + dev->plusinc = 1; + } else if (dev->plusinc == 4) { + dev->mode = MODEM_MODE_COMMAND; + modem_send_res(dev, ResOK); + dev->plusinc = 0; + } + } +} + /* Initialize the device for use by the user. */ static void * modem_init(const device_t *info) @@ -650,16 +847,50 @@ modem_init(const device_t *info) modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); memset(modem->mac, 0xfc, 6); + + modem->port = device_get_config_int("port"); + modem->baudrate = device_get_config_int("baudrate"); + + fifo8_create(&modem->data_pending, 0x10000); + fifo8_create(&modem->rx_data, 0x10000); + + timer_add(&modem->dtr_timer, modem_dtr_callback_timer, modem, 0); + timer_add(&modem->host_to_serial_timer, host_to_modem_cb, modem, 0); + timer_add(&modem->cmdpause_timer, modem_cmdpause_timer_callback, modem, 0); + timer_on_auto(&modem->cmdpause_timer, 1000); + modem->serial = serial_attach_ex_2(modem->port, modem_rcr_cb, modem_write, modem_dtr_callback, modem); + + modem_reset(modem); modem->card = network_attach(instance, instance->mac, modem_rx, NULL); return modem; } void modem_close(void *priv) { + modem_t* modem = (modem_t*)priv; + fifo8_destroy(&modem->data_pending); + fifo8_destroy(&modem->rx_data); + netcard_close(modem->card); free(priv); } static const device_config_t modem_config[] = { + { + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "COM1", .value = 0 }, + { .description = "COM2", .value = 1 }, + { .description = "COM3", .value = 2 }, + { .description = "COM4", .value = 3 }, + { .description = "" } + } + }, { .name = "baudrate", .description = "Baud Rate", @@ -669,10 +900,6 @@ static const device_config_t modem_config[] = { .file_filter = NULL, .spinner = { 0 }, .selection = { -#if 0 - { .description = "256000", .value = 256000 }, - { .description = "128000", .value = 128000 }, -#endif { .description = "115200", .value = 115200 }, { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, @@ -694,7 +921,7 @@ static const device_config_t modem_config[] = { const device_t modem_device = { .name = "Standard Hayes-compliant Modem", - .flags = 0, + .flags = DEVICE_COM, .local = 0, .init = modem_init, .close = modem_close, diff --git a/src/network/network.c b/src/network/network.c index 9eb537e3a..94403c2f4 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -136,6 +136,7 @@ static const device_t *net_cards[] = { &dec_tulip_21140_vpc_device, &dec_tulip_21040_device, &pcnet_am79c960_vlb_device, + &modem_device, NULL }; From a45d26807001c208b0d44c01867645a3ce5a4dda Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 22:36:48 +0100 Subject: [PATCH 213/690] LBA Enhancer: Coding style. --- src/disk/lba_enhancer.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c index 07b958b2e..f0ce6b700 100644 --- a/src/disk/lba_enhancer.c +++ b/src/disk/lba_enhancer.c @@ -30,25 +30,29 @@ typedef struct lba_enhancer_t { - rom_t rom; + rom_t rom; } lba_enhancer_t; #define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" -void* lba_enhancer_init(const device_t* info) +void * +lba_enhancer_init(const device_t *info) { - lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)calloc(1, sizeof(lba_enhancer_t)); + lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, + device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); return lba_enhancer; } -void lba_enhancer_close(void* priv) +void +lba_enhancer_close(void* priv) { - lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)priv; + lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) priv; - free(lba_enhancer->rom.rom); free(priv); + return; } From 01d066ce4c48173e03009d5f917495993240d2b6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 22:37:18 +0100 Subject: [PATCH 214/690] MiniVHD: Some initialization sanitizations. --- src/disk/hdd_image.c | 4 +- src/disk/minivhd/create.c | 2 +- src/disk/minivhd/manage.c | 39 ++++------ src/disk/minivhd/minivhd_io.c | 133 ++++++++++++++++---------------- src/disk/minivhd/minivhd_util.c | 4 +- 5 files changed, 85 insertions(+), 97 deletions(-) diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index df473d7d9..db56d5b78 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -327,7 +327,7 @@ hdd_image_load(int id) hdd_images[id].type = HDD_IMAGE_HDX; } else if (is_vhd[0]) { fclose(hdd_images[id].file); - MVHDGeom geometry; + MVHDGeom geometry = { 0 }; geometry.cyl = hdd[id].tracks; geometry.heads = hdd[id].hpc; geometry.spt = hdd[id].spt; @@ -335,7 +335,7 @@ hdd_image_load(int id) hdd_images[id].last_sector = (full_size >> 9LL) - 1; if (hdd[id].vhd_blocksize || hdd[id].vhd_parent[0]) { - MVHDCreationOptions options; + MVHDCreationOptions options = { 0 }; retry_vhd: options.block_size_in_sectors = hdd[id].vhd_blocksize; options.path = fn; diff --git a/src/disk/minivhd/create.c b/src/disk/minivhd/create.c index d06382ef9..1fcfc8682 100644 --- a/src/disk/minivhd/create.c +++ b/src/disk/minivhd/create.c @@ -315,7 +315,7 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte { uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; - uint8_t bat_sect[MVHD_SECTOR_SIZE]; + uint8_t bat_sect[MVHD_SECTOR_SIZE] = {0}; MVHDGeom par_geom = {0}; memset(bat_sect, 0xffffffff, sizeof bat_sect); MVHDMeta* vhdm = NULL; diff --git a/src/disk/minivhd/manage.c b/src/disk/minivhd/manage.c index 7ac3989e6..fdf3d8e79 100644 --- a/src/disk/minivhd/manage.c +++ b/src/disk/minivhd/manage.c @@ -92,7 +92,7 @@ read_footer(MVHDMeta* vhdm) static void read_sparse_header(MVHDMeta* vhdm) { - uint8_t buffer[MVHD_SPARSE_SIZE]; + uint8_t buffer[MVHD_SPARSE_SIZE] = { 0 }; mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); (void) !fread(buffer, sizeof buffer, 1, vhdm->f); @@ -438,17 +438,15 @@ mvhd_version_id(void) MVHDAPI int mvhd_file_is_vhd(FILE* f) { - uint8_t con_str[8]; + uint8_t con_str[8] = { 0 }; - if (f == NULL) { + if (f == NULL) return 0; - } mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); (void) !fread(con_str, sizeof con_str, 1, f); - if (mvhd_is_conectix_str(con_str)) { + if (mvhd_is_conectix_str(con_str)) return 1; - } return 0; } @@ -457,13 +455,12 @@ mvhd_file_is_vhd(FILE* f) MVHDAPI MVHDGeom mvhd_calculate_geometry(uint64_t size) { - MVHDGeom chs; + MVHDGeom chs = { 0 }; uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); uint32_t spt, heads, cyl, cth; - if (ts > 65535 * 16 * 255) { + if (ts > 65535 * 16 * 255) ts = 65535 * 16 * 255; - } if (ts >= 65535 * 16 * 63) { spt = 255; @@ -473,9 +470,8 @@ mvhd_calculate_geometry(uint64_t size) spt = 17; cth = ts / spt; heads = (cth + 1023) / 1024; - if (heads < 4) { + if (heads < 4) heads = 4; - } if (cth >= (heads * 1024) || heads > 16) { spt = 31; heads = 16; @@ -500,7 +496,7 @@ mvhd_calculate_geometry(uint64_t size) MVHDAPI MVHDMeta* mvhd_open(const char* path, int readonly, int* err) { - MVHDError open_err; + MVHDError open_err = { 0 }; MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); if (vhdm == NULL) { @@ -516,11 +512,10 @@ mvhd_open(const char* path, int readonly, int* err) //This is safe, as we've just checked for potential overflow above strcpy(vhdm->filename, path); - if (readonly) { + if (readonly) vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb", err); - } else { + else vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb+", err); - } if (vhdm->f == NULL) { /* note, mvhd_fopen sets err for us */ goto cleanup_vhdm; @@ -567,14 +562,12 @@ mvhd_open(const char* path, int readonly, int* err) vhdm->format_buffer.sector_count = 64; if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { char* par_path = get_diff_parent_path(vhdm, err); - if (par_path == NULL) { + if (par_path == NULL) goto cleanup_format_buff; - } uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); - if (*err != 0) { + if (*err != 0) goto cleanup_format_buff; - } if (vhdm->sparse.par_timestamp != par_mod_ts) { /* The last-modified timestamp is to fragile to make this a fatal error. @@ -582,9 +575,8 @@ mvhd_open(const char* path, int readonly, int* err) *err = MVHD_ERR_TIMESTAMP; } vhdm->parent = mvhd_open(par_path, true, err); - if (vhdm->parent == NULL) { + if (vhdm->parent == NULL) goto cleanup_format_buff; - } if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { *err = MVHD_ERR_INVALID_PAR_UUID; @@ -629,9 +621,8 @@ mvhd_close(MVHDMeta* vhdm) if (vhdm == NULL) return; - if (vhdm->parent != NULL) { + if (vhdm->parent != NULL) mvhd_close(vhdm->parent); - } fclose(vhdm->f); @@ -655,7 +646,7 @@ mvhd_close(MVHDMeta* vhdm) MVHDAPI int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { - uint8_t sparse_buff[1024]; + uint8_t sparse_buff[1024] = { 0 }; if (vhdm == NULL || err == NULL) { *err = MVHD_ERR_INVALID_PARAMS; diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index ff86a8337..2912cf5b2 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -46,7 +46,6 @@ #include "minivhd.h" #include "internal.h" - /* * The following bit array macros adapted from: * @@ -56,7 +55,6 @@ #define VHD_CLEARBIT(A,k) ( A[(k>>3)] &= ~(0x80 >> (k&7)) ) #define VHD_TESTBIT(A,k) ( A[(k>>3)] & (0x80 >> (k&7)) ) - /** * \brief Check that we will not be overflowing buffers * @@ -68,29 +66,26 @@ * \param [out] trunc_sectors The number of sectors truncated if transfer_sectors < num_sectors */ static inline void -check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect) +check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, int *trunc_sect) { *transfer_sect = num_sectors; *trunc_sect = 0; - if ((total_sectors - offset) < (uint32_t)*transfer_sect) { + if ((total_sectors - offset) < ((uint32_t) *transfer_sect)) { *transfer_sect = total_sectors - offset; *trunc_sect = num_sectors - *transfer_sect; } } - void -mvhd_write_empty_sectors(FILE* f, int sector_count) +mvhd_write_empty_sectors(FILE *f, int sector_count) { uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; - for (int i = 0; i < sector_count; i++) { + for (int i = 0; i < sector_count; i++) fwrite(zero_bytes, sizeof zero_bytes, 1, f); - } } - /** * \brief Read the sector bitmap for a block. * @@ -101,19 +96,17 @@ mvhd_write_empty_sectors(FILE* f, int sector_count) * \param [in] blk The block for which to read the sector bitmap from */ static void -read_sect_bitmap(MVHDMeta* vhdm, int blk) +read_sect_bitmap(MVHDMeta *vhdm, int blk) { if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); (void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { + } else memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); - } vhdm->bitmap.curr_block = blk; } - /** * \brief Write the current sector bitmap in memory to file * @@ -129,7 +122,6 @@ write_curr_sect_bitmap(MVHDMeta* vhdm) } } - /** * \brief Write block offset from memory into file * @@ -137,7 +129,7 @@ write_curr_sect_bitmap(MVHDMeta* vhdm) * \param [in] blk The block for which to write the offset for */ static void -write_bat_entry(MVHDMeta* vhdm, int blk) +write_bat_entry(MVHDMeta *vhdm, int blk) { uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); @@ -146,7 +138,6 @@ write_bat_entry(MVHDMeta* vhdm, int blk) fwrite(&offset, sizeof offset, 1, vhdm->f); } - /** * \brief Create an empty block in a sparse or differencing VHD image * @@ -162,9 +153,9 @@ write_bat_entry(MVHDMeta* vhdm, int blk) * \param [in] blk The block number to create */ static void -create_block(MVHDMeta* vhdm, int blk) +create_block(MVHDMeta *vhdm, int blk) { - uint8_t footer[MVHD_FOOTER_SIZE]; + uint8_t footer[MVHD_FOOTER_SIZE] = { 0 }; /* Seek to where the footer SHOULD be */ mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); @@ -179,13 +170,12 @@ create_block(MVHDMeta* vhdm, int blk) } int64_t abs_offset = mvhd_ftello64(vhdm->f); - if (abs_offset % MVHD_SECTOR_SIZE != 0) { + if ((abs_offset % MVHD_SECTOR_SIZE) != 0) { /* Yikes! We're supposed to be on a sector boundary. Add some padding */ - int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); + int64_t padding_amount = ((int64_t) MVHD_SECTOR_SIZE) - (abs_offset % MVHD_SECTOR_SIZE); uint8_t zero_byte = 0; - for (int i = 0; i < padding_amount; i++) { + for (int i = 0; i < padding_amount; i++) fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); - } abs_offset += padding_amount; } @@ -204,37 +194,39 @@ create_block(MVHDMeta* vhdm, int blk) write_bat_entry(vhdm, blk); } - int -mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; +mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { + int64_t addr = 0ULL; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - addr = (int64_t)offset * MVHD_SECTOR_SIZE; + addr = ((int64_t) offset) * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - (void) !fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + (void) !fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); return truncated_sectors; } - int -mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); uint8_t* buff = (uint8_t*)out_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; + int64_t addr = 0ULL; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int prev_blk = -1; + int sib = 0; ls = offset + transfer_sectors; - prev_blk = -1; for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; @@ -245,14 +237,15 @@ mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buf read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); } } - if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) (void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { + else { memset(buff, 0, MVHD_SECTOR_SIZE); mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); } @@ -262,19 +255,21 @@ mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buf return truncated_sectors; } - int -mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t* buff = (uint8_t*)out_buff; - MVHDMeta* curr_vhdm = vhdm; - uint32_t s, ls; - int blk, sib; + uint8_t *buff = (uint8_t*)out_buff; + MVHDMeta *curr_vhdm = vhdm; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int sib = 0; ls = offset + transfer_sectors; for (s = offset; s < ls; s++) { @@ -291,11 +286,11 @@ mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) /* We handle actual sector reading using the fixed or sparse functions, as a differencing VHD is also a sparse VHD */ - if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + if ((curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) || + (curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC)) mvhd_sparse_read(curr_vhdm, s, 1, buff); - } else { + else mvhd_fixed_read(curr_vhdm, s, 1, buff); - } curr_vhdm = vhdm; buff += MVHD_SECTOR_SIZE; @@ -304,38 +299,40 @@ mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) return truncated_sectors; } - int -mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; + int64_t addr = 0ULL; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); addr = (int64_t)offset * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - fwrite(in_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); return truncated_sectors; } - int -mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t* buff = (uint8_t*)in_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; + uint8_t* buff = (uint8_t *) in_buff; + int64_t addr = 0ULL; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int prev_blk = -1; + int sib = 0; ls = offset + transfer_sectors; - prev_blk = -1; for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; @@ -357,7 +354,8 @@ mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); } prev_blk = blk; @@ -374,14 +372,13 @@ mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i return truncated_sectors; } - int -mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_noop_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - (void)vhdm; - (void)offset; - (void)num_sectors; - (void)in_buff; + (void) vhdm; + (void) offset; + (void) num_sectors; + (void) in_buff; return 0; } diff --git a/src/disk/minivhd/minivhd_util.c b/src/disk/minivhd/minivhd_util.c index dd3244322..4901e5841 100644 --- a/src/disk/minivhd/minivhd_util.c +++ b/src/disk/minivhd/minivhd_util.c @@ -462,7 +462,7 @@ mvhd_file_mod_timestamp(const char* path, int *err) { *err = 0; #ifdef _WIN32 - struct _stat file_stat; + struct _stat file_stat = { 0 }; size_t path_len = strlen(path); mvhd_utf16 new_path[260] = {0}; int new_path_len = (sizeof new_path) - 2; @@ -485,7 +485,7 @@ mvhd_file_mod_timestamp(const char* path, int *err) return 0; } #else - struct stat file_stat; + struct stat file_stat = { 0 }; int stat_res = stat(path, &file_stat); if (stat_res != 0) { From 50d7340d01d664df8a38706e1f654eb35ed24f3a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 23:11:35 +0100 Subject: [PATCH 215/690] Added the 1.02 German and 1.03 English versions of the AHA-1542CP BIOS. --- src/scsi/scsi_aha154x.c | 62 +++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 05b8b2726..8ff0aaa32 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -70,6 +70,9 @@ uint16_t aha_ports[] = { static uint8_t *aha1542cp_pnp_rom = NULL; +// static char *aha1542cp_rev = "F001"; +static char aha1542cp_rev[16] = { 0 }; + #pragma pack(push, 1) typedef struct aha_setup_t { uint8_t CustomerSignature[20]; @@ -851,6 +854,9 @@ aha_setmcode(x54x_t *dev) return; } + fseek(fp, 0x3136, SEEK_SET); + (void) !fread(dev->fw_rev, 4, 1, fp); + /* Allocate the buffer and then read the real PnP ROM into it. */ if (aha1542cp_pnp_rom != NULL) { free(aha1542cp_pnp_rom); @@ -892,7 +898,7 @@ aha_initnvr(x54x_t *dev) EE2_EXT1G | EE2_RMVOK); /* Imm return on seek */ dev->nvr[3] = SPEED_50; /* speed 5.0 MB/s */ dev->nvr[6] = (EE6_TERM | /* host term enable */ - EE6_RSTBUS); /* reset SCSI bus on boot*/ + EE6_RSTBUS); /* reset SCSI bus on boot */ } /* Initialize the board's EEPROM (NVR.) */ @@ -942,6 +948,7 @@ static void * aha_init(const device_t *info) { x54x_t *dev; + const char *bios_rev = NULL; /* Call common initializer. */ dev = x54x_init(info); @@ -987,7 +994,8 @@ aha_init(const device_t *info) strcpy(dev->name, "AHA-154xA"); dev->fw_rev = "A003"; /* The 3.07 microcode says A006. */ dev->bios_path = "roms/scsi/adaptec/aha1540a307.bin"; /*Only for port 0x330*/ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read + it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1009,7 +1017,8 @@ aha_init(const device_t *info) break; } dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read + it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1053,10 +1062,11 @@ aha_init(const device_t *info) case AHA_154xCP: strcpy(dev->name, "AHA-154xCP"); - dev->bios_path = "roms/scsi/adaptec/aha1542cp102.bin"; - dev->mcode_path = "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12"; + bios_rev = (char *) device_get_config_bios("bios_rev"); + dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); + dev->mcode_path = (char *) device_get_bios_file(info, bios_rev, 1); dev->nvr_path = "aha1542cp.nvr"; - dev->fw_rev = "F001"; + dev->fw_rev = aha1542cp_rev; dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ @@ -1069,11 +1079,14 @@ aha_init(const device_t *info) dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ dev->ha_bps = 10000000.0; /* fast SCSI */ dev->pnp_len = 0x00be; /* length of the PnP ROM */ - dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ - dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine returned by - SCSI controller command 0x33 */ - dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine in the - microcode ROM */ + if (!strcmp(bios_rev, "v1_02_en")) + dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ + else + dev->pnp_offset = 0x5345; /* offset of the PnP ROM in the microcode ROM */ + dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine + returned by SCSI controller command 0x33 */ + dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine + in the microcode ROM */ aha_setmcode(dev); if (aha1542cp_pnp_rom) isapnp_add_card(aha1542cp_pnp_rom, dev->pnp_len + 7, aha_pnp_config_changed, NULL, NULL, NULL, dev); @@ -1384,6 +1397,31 @@ static const device_config_t aha_154xcf_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; + +static const device_config_t aha_154xcp_config[] = { + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v1_02_en", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 1.02 (English)", .internal_name = "v1_02_en", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp102.bin", + "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12", "" } }, + { .name = "Version 1.02 (German)", .internal_name = "v1_02_de", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/buff_1-0_bios.bin", + "roms/scsi/adaptec/buff_1-0_mcode.bin", "" } }, + { .name = "Version 1.03 (English)", .internal_name = "v1_03_en", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp103.bin", + "roms/scsi/adaptec/908301-00_g_mcode_144c.u12.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; // clang-format on const device_t aha154xa_device = { @@ -1453,7 +1491,7 @@ const device_t aha154xcp_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = aha_154xcp_config }; const device_t aha1640_device = { From 27734a872873739113b40e4d582cece686f74686 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 00:42:13 +0100 Subject: [PATCH 216/690] AHA-1542CP: Return the correct firmware checksum. --- src/scsi/scsi_aha154x.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 8ff0aaa32..2927d797c 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -73,6 +73,8 @@ static uint8_t *aha1542cp_pnp_rom = NULL; // static char *aha1542cp_rev = "F001"; static char aha1542cp_rev[16] = { 0 }; +static uint16_t fw_chksum = 0x0000; + #pragma pack(push, 1) typedef struct aha_setup_t { uint8_t CustomerSignature[20]; @@ -469,8 +471,10 @@ aha_setup_data(void *priv) ReplyISI->fParityCheckingEnabled = dev->parity & 1; U32_TO_ADDR(aha_setup->BIOSMailboxAddress, dev->BIOSMailboxOutAddr); - aha_setup->uChecksum = 0xA3; - aha_setup->uUnknown = 0xC2; + // aha_setup->uChecksum = 0xA3; + // aha_setup->uUnknown = 0xC2; + aha_setup->uChecksum = fw_chksum >> 8; + aha_setup->uUnknown = fw_chksum & 0xff; } static void @@ -825,6 +829,7 @@ aha_setmcode(x54x_t *dev) { uint32_t temp; FILE *fp; + uint16_t tempb = 0x00; /* Only if this device has a BIOS ROM. */ if (dev->mcode_path == NULL) @@ -880,6 +885,14 @@ aha_setmcode(x54x_t *dev) fseek(fp, dev->cmd_33_offset, SEEK_SET); (void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, fp); + fw_chksum = 0x0000; + + for (uint16_t i = 0; i < 32768; i++) { + (void) fseek(fp, i, SEEK_SET); + (void) !fread(&tempb, 1, 1, fp); + fw_chksum += tempb; + } + (void) fclose(fp); } @@ -988,6 +1001,8 @@ aha_init(const device_t *info) strcpy(dev->vendor, "Adaptec"); + fw_chksum = 0xa3c2; + /* Perform per-board initialization. */ switch (dev->type) { case AHA_154xA: From b5db53368ff71b6ea4bfeeaf4180baa70b99f505 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 14:58:12 +0600 Subject: [PATCH 217/690] Logging and crash fixes --- src/network/net_modem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4127158bd..b845896d3 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -268,7 +268,9 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { - serial_write_fifo(modem->serial, fifo8_pop(&modem->data_pending)); + uint8_t val = fifo8_pop(&modem->data_pending); + fprintf(stderr, "%c", val); + serial_write_fifo(modem->serial, val); } no_write_to_machine: @@ -281,6 +283,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_t* modem = (modem_t*)priv; if (modem->mode == MODEM_MODE_COMMAND) { + fprintf(stderr, "%c", txval); if (modem->cmdpos < 2) { // Ignore everything until we see "AT" sequence. if (modem->cmdpos == 0 && toupper(txval) != 'A') { @@ -861,7 +864,7 @@ modem_init(const device_t *info) modem->serial = serial_attach_ex_2(modem->port, modem_rcr_cb, modem_write, modem_dtr_callback, modem); modem_reset(modem); - modem->card = network_attach(instance, instance->mac, modem_rx, NULL); + modem->card = network_attach(modem, modem->mac, modem_rx, NULL); return modem; } @@ -921,6 +924,7 @@ static const device_config_t modem_config[] = { const device_t modem_device = { .name = "Standard Hayes-compliant Modem", + .internal_name = "modem", .flags = DEVICE_COM, .local = 0, .init = modem_init, From af30550d946b097116143f440253410a71b3c601 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 15:49:08 +0600 Subject: [PATCH 218/690] Fix command mode --- src/network/net_modem.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b845896d3..97f038157 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -267,9 +267,9 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); + fprintf(stderr, "(data)\n"); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); - fprintf(stderr, "%c", val); serial_write_fifo(modem->serial, val); } @@ -283,7 +283,6 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_t* modem = (modem_t*)priv; if (modem->mode == MODEM_MODE_COMMAND) { - fprintf(stderr, "%c", txval); if (modem->cmdpos < 2) { // Ignore everything until we see "AT" sequence. if (modem->cmdpos == 0 && toupper(txval) != 'A') { @@ -314,12 +313,12 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_do_command(modem); return; } + } - if (modem->cmdpos < 99) { - modem_echo(modem, txval); - modem->cmdbuf[modem->cmdpos] = txval; - modem->cmdpos++; - } + if (modem->cmdpos < 99) { + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; } } else { modem_data_mode_process_byte(modem, txval); @@ -493,6 +492,8 @@ modem_do_command(modem_t* modem) return; } + pclog("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); + scanbuf = &modem->cmdbuf[2]; while (1) { From 10c7ee2aeff940b7b19cf5c41b9fed7bd70d7788 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 11:38:18 +0100 Subject: [PATCH 219/690] Fixed some warnings. --- src/codegen/codegen_ops_fpu.h | 3 ++- src/disk/lba_enhancer.c | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 1021cc742..242743dee 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -671,9 +671,10 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ static double fp_imm = v; \ + static uint64_t *fptr = (uint64_t *) &fp_imm; \ \ FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ + FP_LOAD_IMM_Q(*fptr); \ \ return op_pc; \ } diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c index f0ce6b700..35c845c16 100644 --- a/src/disk/lba_enhancer.c +++ b/src/disk/lba_enhancer.c @@ -35,27 +35,25 @@ typedef struct lba_enhancer_t #define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" -void * -lba_enhancer_init(const device_t *info) -{ - lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); - - rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, - device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - return lba_enhancer; -} - void lba_enhancer_close(void* priv) { - lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) priv; - free(priv); return; } +void * +lba_enhancer_init(const device_t *info) +{ + lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&dev->rom, BIOS_LBA_ENHANCER, + device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + return dev; +} + static int lba_enhancer_available(void) { From ca2492e893423f171982e769d97f8bdf88fee34b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:18:31 +0100 Subject: [PATCH 220/690] Added the Trident TVGA 8900 D-R. --- src/include/86box/video.h | 1 + src/video/vid_table.c | 1 + src/video/vid_tvga.c | 26 +++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 65d96a4b6..e56498807 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -550,6 +550,7 @@ extern const device_t ibm_ps1_2121_device; /* Trident TVGA 8900 */ extern const device_t tvga8900b_device; extern const device_t tvga8900d_device; +extern const device_t tvga8900dr_device; extern const device_t tvga9000b_device; extern const device_t nec_sv9000_device; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 5b9c3f8f3..9992eff45 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -144,6 +144,7 @@ video_cards[] = { { &sigma_device }, { &tvga8900b_device }, { &tvga8900d_device }, + { &tvga8900dr_device }, { &tvga9000b_device }, { &nec_sv9000_device }, { &et4000k_isa_device }, diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 591851016..babd909be 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -37,6 +37,7 @@ #define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" #define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" +#define ROM_TVGA_8900DR "roms/video/tvga/8900DR.VBI" #define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin" #define ROM_TVGA_9000B_NEC_SV9000 "roms/video/tvga/SV9000.VBI" @@ -428,7 +429,10 @@ tvga_init(const device_t *info) bios_fn = ROM_TVGA_8900B; break; case TVGA8900CLD_ID: - bios_fn = ROM_TVGA_8900CLD; + if (info->local & 0x0100) + bios_fn = ROM_TVGA_8900DR; + else + bios_fn = ROM_TVGA_8900CLD; break; case TVGA9000B_ID: bios_fn = (info->local & 0x100) ? ROM_TVGA_9000B_NEC_SV9000 : ROM_TVGA_9000B; @@ -466,6 +470,12 @@ tvga8900d_available(void) return rom_present(ROM_TVGA_8900CLD); } +static int +tvga8900dr_available(void) +{ + return rom_present(ROM_TVGA_8900DR); +} + static int tvga9000b_available(void) { @@ -564,6 +574,20 @@ const device_t tvga8900d_device = { .config = tvga_config }; +const device_t tvga8900dr_device = { + .name = "Trident TVGA 8900D-R", + .internal_name = "tvga8900dr", + .flags = DEVICE_ISA, + .local = TVGA8900CLD_ID | 0x0100, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + { .available = tvga8900dr_available }, + .speed_changed = tvga_speed_changed, + .force_redraw = tvga_force_redraw, + .config = tvga_config +}; + const device_t tvga9000b_device = { .name = "Trident TVGA 9000B", .internal_name = "tvga9000b", From 3061e9343c768272860ad3a9810aae3dc686df60 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:30:13 +0100 Subject: [PATCH 221/690] Give the TVGA 8900D-R faster timings. --- src/video/vid_tvga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index babd909be..e97805beb 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -418,7 +418,10 @@ tvga_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); tvga->vram_size = 512 << 10; } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); + if (info->local & 0x0100) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); tvga->vram_size = device_get_config_int("memory") << 10; } From cb8b6b68a749496b44fbf488cf7d4ae5ce1935cb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:31:42 +0100 Subject: [PATCH 222/690] And made them on par with the Tseng ET4000AX, as the available data suggests. --- src/video/vid_tvga.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index e97805beb..cd5714d04 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -60,6 +60,7 @@ typedef struct tvga_t { } tvga_t; video_timings_t timing_tvga8900 = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; +video_timings_t timing_tvga8900dr = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; video_timings_t timing_tvga9000 = { .type = VIDEO_ISA, .write_b = 7, .write_w = 7, .write_l = 12, .read_b = 7, .read_w = 7, .read_l = 12 }; static uint8_t crtc_mask[0x40] = { @@ -419,7 +420,7 @@ tvga_init(const device_t *info) tvga->vram_size = 512 << 10; } else { if (info->local & 0x0100) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900dr); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); tvga->vram_size = device_get_config_int("memory") << 10; From 567d66b788355e903fba2a3f9c780ce5da5f0e55 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:43:59 +0100 Subject: [PATCH 223/690] Added the IBM Aptiva CM (Japanese PC 330). --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 44 +++++++++++++++++++++++++++--------- src/machine/machine_table.c | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index e27a70d79..765279257 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,6 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); +extern int machine_at_aptiva_cm_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1dd63ce32..7d843aece 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -693,17 +693,9 @@ machine_at_pb450_init(const machine_t *model) return ret; } -int -machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse */ +static void +machine_at_pc330_6573_common_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - machine_at_common_init_ex(model, 2); device_add(&ide_vlb_2ch_device); @@ -718,7 +710,7 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth pci_register_slot(0x0E, PCI_CARD_VIDEO, 13, 14, 15, 16); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5430_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); device_add(&opti602_device); device_add(&opti802g_device); @@ -727,6 +719,36 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); +} + +int +machine_at_aptiva_cm_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/aptiva_cm/$IMAGES.USF", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_pc330_6573_common_init(model); + + return ret; +} + +int +machine_at_pc330_6573_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_pc330_6573_common_init(model); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d620357d6..1426dbcb3 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7185,6 +7185,46 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[OPTi 802G] IBM Aptiva CM", + .internal_name = "aptiva_cm", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_aptiva_cm_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3_PC330, + .block = CPU_BLOCK_NONE, + .min_bus = 25000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[OPTi 802G] IBM PC 330 (type 6573)", .internal_name = "pc330_6573", From 9006f31f45de2c40d8d73b009a23b1d73e656b32 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 14:46:33 +0100 Subject: [PATCH 224/690] Added the NEC Mate NX MA23C. --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 31 ++++++++++++++++++++++++++ src/machine/machine_table.c | 43 ++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 765279257..c13b423b0 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -706,6 +706,7 @@ extern int machine_at_pb810_init(const machine_t *); extern int machine_at_mb520n_init(const machine_t *); extern int machine_at_i430vx_init(const machine_t *); +extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_AN430TX) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 9ab24b7c2..ce21c6437 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -798,6 +798,37 @@ machine_at_i430vx_init(const machine_t *model) return ret; } +int +machine_at_ma23c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ma23c/BIOS.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_VIDEO, 3, 4, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&nec_mate_unk_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + int machine_at_nupro592_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1426dbcb3..810597899 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11997,6 +11997,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i430TX] NEC Mate NX MA23C", + .internal_name = "ma23c", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ma23c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { @@ -13683,7 +13724,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or AMIKey-2 KBC firmware. */ { .name = "[i440LX] NEC Mate NX MA30D/23D", From d4fa99648e9a0f6adbcb943a85312df4bb074cf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 18:56:42 +0100 Subject: [PATCH 225/690] SiS 5595 fixes, added the PC Chips M747, and corrected the name of the Aptiva. --- src/acpi.c | 3 +++ src/chipset/sis_5513_p2i.c | 32 +++++++++++++++++++++++-- src/include/86box/machine.h | 3 ++- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/m_at_slot1.c | 27 +++++++++++++++++++++ src/machine/machine_table.c | 46 +++++++++++++++++++++++++++++++++--- 6 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 93cb71542..339ea7dcf 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1733,6 +1733,9 @@ acpi_reg_write_sis_5595(int size, uint16_t addr, uint8_t val, void *priv) break; case 0x1c: dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0xff << shift32)) | ((val & 0xff) << shift32)); + if (!strcmp(machine_get_internal_name(), "m747") && (val & 0x10) && + !(dev->regs.gpe_io & 0x00000010)) + resetx86(); break; case 0x1d: dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index df18cc4b3..d0c423a8e 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -86,6 +86,7 @@ typedef struct sis_5513_pci_to_isa_t { port_92_t *port_92; void *pit; nvr_t *nvr; + char *fn; ddma_t *ddma; acpi_t *acpi; void *smbus; @@ -1077,7 +1078,6 @@ sis_5513_11_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) dev->sis->ide_bits_1_3_writable = 0; dev->sis->usb_enabled = 0; - sis_5513_apc_reset(dev); sis_5513_apc_recalc(dev, 0); } @@ -1132,7 +1132,6 @@ sis_5513_b0_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) dev->sis->usb_enabled = 0; - sis_5513_apc_reset(dev); sis_5513_apc_recalc(dev, 0); if (dev->rev == 0x81) @@ -1196,6 +1195,17 @@ static void sis_5513_pci_to_isa_close(void *priv) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + FILE *fp = NULL; + + fp = nvr_fopen(dev->fn, "wb"); + + if (fp != NULL) { + (void) fwrite(dev->apc_regs, 256, 1, fp); + fclose(fp); + } + + if (dev->fn != NULL) + free(dev->fn); free(dev); } @@ -1205,6 +1215,8 @@ sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) calloc(1, sizeof(sis_5513_pci_to_isa_t)); uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + FILE *fp = NULL; + int c; dev->rev = info->local; @@ -1272,6 +1284,22 @@ sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) dev->sis->acpi->priv = dev->sis; acpi_set_slot(dev->sis->acpi, dev->sis->sb_pci_slot); acpi_set_nvr(dev->sis->acpi, dev->nvr); + + /* Set up the NVR file's name. */ + c = strlen(machine_get_internal_name()) + 9; + dev->fn = (char *) malloc(c + 1); + sprintf(dev->fn, "%s_apc.nvr", machine_get_internal_name()); + + fp = nvr_fopen(dev->fn, "rb"); + + memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); + sis_5513_apc_reset(dev); + if (fp != NULL) { + if (fread(dev->apc_regs, 1, 256, fp) != 256) + fatal("sis_5513_pci_to_isa_init(): Error reading APC data\n"); + fclose(fp); + } + acpi_set_irq_mode(dev->sis->acpi, 2); break; } diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c13b423b0..18abf9ea9 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,7 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); -extern int machine_at_aptiva_cm_init(const machine_t *); +extern int machine_at_aptiva_510_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); @@ -801,6 +801,7 @@ extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); extern int machine_at_p6f99_init(const machine_t *); +extern int machine_at_m747_init(const machine_t *); /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 7d843aece..4cfa7447e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -722,11 +722,11 @@ machine_at_pc330_6573_common_init(const machine_t *model) } int -machine_at_aptiva_cm_init(const machine_t *model) +machine_at_aptiva_510_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/aptiva_cm/$IMAGES.USF", + ret = bios_load_linear("roms/machines/aptiva_510/$IMAGES.USF", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index d31d763d4..a3c25d12b 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -841,3 +841,30 @@ machine_at_p6f99_init(const machine_t *model) return ret; } +int +machine_at_m747_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m747/990521.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5600_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&winbond_flash_w29c020_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 810597899..04cc59043 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7186,11 +7186,11 @@ const machine_t machines[] = { }, /* Has IBM PS/2 Type 1 KBC firmware. */ { - .name = "[OPTi 802G] IBM Aptiva CM", - .internal_name = "aptiva_cm", + .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", + .internal_name = "aptiva_510", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_aptiva_cm_init, + .init = machine_at_aptiva_510_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -14513,6 +14513,46 @@ const machine_t machines[] = { .snd_device = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ .net_device = NULL }, + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] PC Chips M747", + .internal_name = "m747", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_m747_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Slot 1/2 machines */ /* 440GX */ From f4a7fd7190122f121ea00cfe2dbed2d04d969d41 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 19:07:54 +0100 Subject: [PATCH 226/690] Added two more ET4000AX BIOS'es. --- src/video/vid_et4000.c | 82 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 5fe524fd8..7ceacb823 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -63,7 +63,9 @@ #define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */ #define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" +#define V8_06_BIOS_ROM_PATH "roms/video/et4000/ET4000_V8_06.BIN" #define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin" +#define V1_21_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.21.bin" #define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" #define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" #define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" @@ -783,6 +785,7 @@ et4000_mca_feedb(UNUSED(void *priv)) static void * et4000_init(const device_t *info) { + const char *bios_ver = NULL; const char *fn; et4000_t *dev; int i; @@ -803,8 +806,8 @@ et4000_init(const device_t *info) NULL, NULL); io_sethandler(0x03c0, 32, et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); - if (dev->type == ET4000_TYPE_TC6058AF) - fn = TC6058AF_BIOS_ROM_PATH; + bios_ver = (char *) device_get_config_bios("bios_ver"); + fn = (char *) device_get_bios_file(info, bios_ver, 0); break; case ET4000_TYPE_MCA: /* MCA ET4000AX */ @@ -925,12 +928,6 @@ et4000_force_redraw(void *priv) dev->svga.fullchange = changeframecount; } -static int -et4000_tc6058af_available(void) -{ - return rom_present(TC6058AF_BIOS_ROM_PATH); -} - static int et4000_available(void) { @@ -970,12 +967,75 @@ static const device_config_t et4000_tc6058af_config[] = { } } }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v1_10", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 1.10", .internal_name = "v1_10", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { TC6058AF_BIOS_ROM_PATH, "" } }, + { .name = "Version 1.21", .internal_name = "v1_21", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { V1_21_BIOS_ROM_PATH, "" } }, + { .files_no = 0 } + }, + }, { .type = CONFIG_END } // clang-format on }; +static const device_config_t et4000_bios_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 1024, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "" + } + } + }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v8_01", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 8.01", .internal_name = "v8_01", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { BIOS_ROM_PATH, "" } }, + { .name = "Version 8.06", .internal_name = "v8_06", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { V8_06_BIOS_ROM_PATH, "" } }, + { .files_no = 0 } + }, + }, + { + .type = CONFIG_END + } + // clang-format on +}; + static const device_config_t et4000_config[] = { // clang-format off { @@ -1015,7 +1075,7 @@ const device_t et4000_tc6058af_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_tc6058af_available }, + { .available = NULL }, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_tc6058af_config @@ -1029,10 +1089,10 @@ const device_t et4000_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_available }, + { .available = NULL }, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, - .config = et4000_config + .config = et4000_bios_config }; const device_t et4000_mca_device = { From bc6b659e02b976430321c053f9d78a5c64759bc3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 01:49:58 +0600 Subject: [PATCH 227/690] SLIP works properly now Preparation for modem phonebook files --- src/network/CMakeLists.txt | 2 +- src/network/net_modem.c | 101 +++++++++++++++++++++++++++++++++--- src/network/net_slirp.c | 50 ++++++++++++++++++ src/network/network.c | 8 ++- src/network/utils/getline.c | 81 +++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 8 deletions(-) create mode 100644 src/network/utils/getline.c diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 5eb091d58..e407d4364 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -15,7 +15,7 @@ set(net_sources) list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c) + net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c utils/getline.c) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 97f038157..2396863bd 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,3 +1,6 @@ + +/* TODO: SLIP support. */ + #include #include #include @@ -14,6 +17,7 @@ #include <86box/fifo8.h> #include <86box/timer.h> #include <86box/serial.h> +#include <86box/plat.h> #include <86box/network.h> #include <86box/plat_unused.h> @@ -48,6 +52,18 @@ typedef enum modem_mode_t MODEM_MODE_DATA = 1 } modem_mode_t; +typedef enum modem_slip_stage_t +{ + MODEM_SLIP_STAGE_USERNAME, + MODEM_SLIP_STAGE_PASSWORD +} modem_slip_stage_t; + +typedef struct modem_phonebook_entry_t +{ + char phone[1024]; + char address[1024]; +} modem_phonebook_entry_t; + typedef struct modem_t { uint8_t mac[6]; @@ -90,6 +106,9 @@ typedef struct modem_t bool recCommand; uint8_t command; } telClient; + + modem_phonebook_entry_t entries[20]; + uint32_t entries_num; netcard_t *card; } modem_t; @@ -107,6 +126,43 @@ static modem_t *instance; static void modem_do_command(modem_t* modem); +extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); + +static void +modem_read_phonebook_file(modem_t* modem, const char* path) +{ + FILE* file = plat_fopen(path, "r"); + char* buf = NULL; + size_t size = 0; + if (!file) + return; + + modem->entries_num = 0; + + while (local_getline(&buf, &size, file) != -1) { + modem_phonebook_entry_t entry = { { 0 }, { 0 } }; + int res = 0; + buf[strcspn(buf, "\r\n")] = 0; + + res = sscanf(buf, "%s %s", entry.phone, entry.address); + + if (res == 0 || res == 1) { + /* Appears to be a bad line. */ + continue; + } + + if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { + /* Invalid characters. */ + continue; + } + + modem->entries[modem->entries_num++] = entry; + if (modem->entries_num >= 20) + break; + } + fclose(file); +} + static void modem_echo(modem_t* modem, uint8_t c) { @@ -190,6 +246,8 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) uint8_t *processed_tx_packet = calloc(len, 1); uint8_t c = 0; + pclog("Processing SLIP packet of %u bytes\n", len); + while (pos < len) { c = p[pos]; pos++; @@ -223,7 +281,18 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) } send_tx_packet: - network_tx(modem->card, processed_tx_packet, received); + if (received) + { + uint8_t* buf = calloc(received + 14, 1); + buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = 0xFF; + buf[6] = buf[7] = buf[8] = buf[9] = buf[10] = buf[11] = 0xFC; + buf[12] = 0x08; + buf[13] = 0x00; + memcpy(buf + 14, processed_tx_packet, received); + network_tx(modem->card, buf, received + 14); + free(processed_tx_packet); + free(buf); + } return; } @@ -267,7 +336,6 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); - fprintf(stderr, "(data)\n"); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); serial_write_fifo(modem->serial, val); @@ -326,11 +394,15 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) } void modem_send_res(modem_t* modem, const ResTypes response) { + char response_str_connect[256] = { 0 }; const char* response_str = NULL; uint32_t code = -1; + + snprintf(response_str_connect, sizeof(response_str_connect), "CONNECT %u", modem->baudrate); + switch (response) { case ResOK: code = 0; response_str = "OK"; break; - case ResCONNECT: code = 1; response_str = "CONNECT 33600"; break; + case ResCONNECT: code = 1; response_str = response_str_connect; break; case ResRING: code = 2; response_str = "RING"; break; case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; case ResERROR: code = 4; response_str = "ERROR"; break; @@ -416,9 +488,13 @@ void modem_dial(modem_t* modem, const char* str) { /* TODO: Port TCP/IP support from DOSBox. */ - if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) + { + pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); - } else { + } + else + { modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); } @@ -779,19 +855,31 @@ fifo8_resize_2x(Fifo8* fifo) static int modem_rx(void *priv, uint8_t *buf, int io_len) { +#if 1 modem_t* modem = (modem_t*)priv; uint8_t c = 0; uint32_t i = 0; if (!modem->connected) { /* Drop packet. */ + pclog("Dropping %d bytes\n", io_len - 14); return 0; } - if ((io_len) <= (fifo8_num_free(&modem->rx_data) / 2)) { + if ((io_len) >= (fifo8_num_free(&modem->rx_data))) { fifo8_resize_2x(&modem->rx_data); } + if (!(buf[12] == 0x08 && buf[13] == 0x00)) { + pclog("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); + return 0; + } + + pclog("Receiving %d bytes\n", io_len - 14); + /* Strip the Ethernet header. */ + io_len -= 14; + buf += 14; + fifo8_push(&modem->rx_data, END); for (i = 0; i < io_len; i++) { switch (buf[i]) { @@ -810,6 +898,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } fifo8_push(&modem->rx_data, END); return 1; +#endif } static void diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 6aff76a90..599ee896d 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -37,6 +37,7 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/video.h> +#include <86box/bswap.h> #define _SSIZE_T_DEFINED #include @@ -76,6 +77,29 @@ typedef struct net_slirp_t { #endif } net_slirp_t; +/* Pulled off from libslirp code. This is only needed for modem. */ +#pragma pack(push, 1) +struct arphdr_local { + unsigned char h_dest[6]; /* destination eth addr */ + unsigned char h_source[6]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ + + unsigned short ar_hrd; /* format of hardware address */ + unsigned short ar_pro; /* format of protocol address */ + unsigned char ar_hln; /* length of hardware address */ + unsigned char ar_pln; /* length of protocol address */ + unsigned short ar_op; /* ARP opcode (command) */ + + /* + * Ethernet looks like this : This bit is variable sized however... + */ + uint8_t ar_sha[6]; /* sender hardware address */ + uint32_t ar_sip; /* sender IP address */ + uint8_t ar_tha[6]; /* target hardware address */ + uint32_t ar_tip; /* target IP address */ +}; +#pragma pack(pop) + #ifdef ENABLE_SLIRP_LOG int slirp_do_log = ENABLE_SLIRP_LOG; @@ -455,6 +479,32 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv #ifdef _WIN32 slirp->sock_event = CreateEvent(NULL, FALSE, FALSE, NULL); #endif + + if (!strcmp(network_card_get_internal_name(net_cards_conf[net_card_current].device_num), "modem")) { + /* Send a gratuitous ARP here to make SLiRP work properly with SLIP connections. */ + struct arphdr_local arphdr; + /* ARP part. */ + arphdr.ar_hrd = bswap16(1); + arphdr.ar_pro = bswap16(0x0800); + arphdr.ar_hln = 6; + arphdr.ar_pln = 4; + arphdr.ar_op = bswap16(1); + memcpy(&arphdr.ar_sha, mac_addr, 6); + memcpy(&arphdr.ar_tha, mac_addr, 6); + arphdr.ar_sip = dhcp.s_addr; + arphdr.ar_tip = dhcp.s_addr; + + /* Ethernet header part. */ + arphdr.h_proto = bswap16(0x0806); + memset(arphdr.h_dest, 0xff, 6); + memset(arphdr.h_source, 0x52, 6); + arphdr.h_source[2] = 0x0a; + arphdr.h_source[3] = 0x00; + arphdr.h_source[4] = slirp_card_num; + arphdr.h_source[5] = 2; + slirp_input(slirp->slirp, (const uint8_t *)&arphdr, sizeof(struct arphdr_local)); + } + slirp_log("SLiRP: creating thread...\n"); slirp->poll_tid = thread_create(net_slirp_thread, slirp); diff --git a/src/network/network.c b/src/network/network.c index 94403c2f4..fe3bf8489 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -454,6 +454,7 @@ netcard_t * network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state) { netcard_t *card = calloc(1, sizeof(netcard_t)); + int net_type = net_cards_conf[net_card_current].net_type; card->queued_pkt.data = calloc(1, NET_MAX_FRAME); card->card_drv = card_drv; card->rx = rx; @@ -470,7 +471,12 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin network_queue_init(&card->queues[i]); } - switch (net_cards_conf[net_card_current].net_type) { + if (!strcmp(network_card_get_internal_name(net_cards_conf[net_card_current].device_num), "modem") && net_type >= NET_TYPE_PCAP) { + /* Force SLiRP here. Modem only operates on non-Ethernet frames. */ + net_type = NET_TYPE_SLIRP; + } + + switch (net_type) { case NET_TYPE_SLIRP: card->host_drv = net_slirp_drv; card->host_drv.priv = card->host_drv.init(card, mac, NULL, net_drv_error); diff --git a/src/network/utils/getline.c b/src/network/utils/getline.c new file mode 100644 index 000000000..69ee258fd --- /dev/null +++ b/src/network/utils/getline.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +ssize_t +local_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + + if (*buf == NULL || *bufsiz == 0) { + *bufsiz = BUFSIZ; + if ((*buf = malloc(*bufsiz)) == NULL) + return -1; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc(fp); + if (c == -1) { + if (feof(fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = realloc(*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} + +ssize_t +local_getline(char **buf, size_t *bufsiz, FILE *fp) +{ + return local_getdelim(buf, bufsiz, '\n', fp); +} From 8fd35fccb8316328ca8a3a11408812cf19456584 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 02:02:49 +0600 Subject: [PATCH 228/690] Make fifo8 resizing code more reliable --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 2396863bd..131b87653 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -866,7 +866,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) return 0; } - if ((io_len) >= (fifo8_num_free(&modem->rx_data))) { + if ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } From e0c5eb49f1f5a186d83e5903f3f551f633aeb393 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 10 Mar 2024 18:01:09 -0300 Subject: [PATCH 229/690] DDC: EDID data improvements, hopefully fixes 1600x1200 on older OSes --- src/qt/languages/ca-ES.po | 6 ++++++ 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 | 6 ++++++ src/qt/languages/fi-FI.po | 6 ++++++ src/qt/languages/fr-FR.po | 5 +++++ 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 | 6 ++++++ 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 | 5 +++++ src/qt/languages/zh-TW.po | 6 ++++++ src/qt/qt_main.cpp | 23 +++++++++++++++++++++++ src/video/vid_ddc.c | 14 +++++++------- 25 files changed, 166 insertions(+), 7 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 483e6ee53..cba27b839 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -1224,3 +1224,9 @@ msgstr "Ràpid" msgid "&Auto-pause on focus loss" msgstr "&Pausa automàtica en la pèrdua del focus" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 84c795092..31388ca54 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1224,3 +1224,9 @@ msgstr "Rychlý" msgid "&Auto-pause on focus loss" msgstr "&Automatická pauza při ztrátě zaměření okna" + +msgid "WinBox is no longer supported" +msgstr "WinBox již není podporován" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Vývoj správce WinBox byl zastaven v roce 2022 z důvodu nedostatku správců. Vzhledem k tomu, že naše úsilí směřujeme k tomu, abychom 86Box ještě vylepšili, rozhodli jsme se WinBox jako správce již nepodporovat.\n\nProstřednictvím WinBoxu nebudou poskytovány žádné další aktualizace a pokud jej budete nadále používat s novějšími verzemi 86Boxu, můžete se setkat s nesprávným chováním. Veškerá hlášení o chybách souvisejících s chováním WinBoxu budou uzavřena jako neplatná.\n\nSeznam dalších správců, které můžete používat, najdete na webu 86box.net." diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 4a4fde3c2..86289507c 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1224,3 +1224,9 @@ msgstr "Schnell" msgid "&Auto-pause on focus loss" msgstr "&Auto-Pause bei Fokusverlust" + +msgid "WinBox is no longer supported" +msgstr "WinBox wird nicht mehr unterstützt" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Die Entwicklung des WinBox-Managers wurde im Jahr 2022 eingestellt, da es an Betreuern mangelte. Da wir unsere Bemühungen darauf richten, 86Box noch besser zu machen, haben wir uns entschlossen, WinBox nicht mehr als Manager zu unterstützen.\n\nEs werden keine weiteren Updates für WinBox zur Verfügung gestellt, und es kann zu fehlerhaftem Verhalten kommen, wenn Sie WinBox weiterhin mit neueren Versionen von 86Box verwenden. Alle Fehlerberichte, die sich auf das Verhalten von WinBox beziehen, werden als ungültig geschlossen.\n\nAuf 86box.net finden Sie eine Liste anderer Manager, die Sie verwenden können." diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 031a365c0..cff4be3ef 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -1224,3 +1224,9 @@ msgstr "Fast" msgid "&Auto-pause on focus loss" msgstr "&Auto-pause on focus loss" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 06a4b60f1..f3bca870f 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -1224,3 +1224,9 @@ msgstr "Fast" msgid "&Auto-pause on focus loss" msgstr "&Auto-pause on focus loss" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 60ac5fb5c..e41a94947 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1224,3 +1224,9 @@ msgstr "Rápida" msgid "&Auto-pause on focus loss" msgstr "&Pausa automática al perder el foco" + +msgid "WinBox is no longer supported" +msgstr "WinBox ya no recibe soporte" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "El desarrollo del gestor WinBox se detuvo en 2022 debido a la falta de mantenedores. Como dirigimos nuestros esfuerzos a hacer 86Box aún mejor, hemos tomado la decisión de dejar de dar soporte a WinBox como gestor.\n\nNo se proporcionarán más actualizaciones a través de WinBox, y puede encontrar un comportamiento incorrecto si continúa usándolo con versiones más nuevas de 86Box. Cualquier informe de error relacionado con el comportamiento de WinBox será cerrado como inválido.\n\nVaya a 86box.net para una lista de otros gestores que puede utilizar." diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 50ebffccb..ddf6a0683 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1224,3 +1224,9 @@ msgstr "Nopea" msgid "&Auto-pause on focus loss" msgstr "&Automaattinen tauko tarkennuksen hävitessä" + +msgid "WinBox is no longer supported" +msgstr "WinBoxia ei enää tueta" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox-managerin kehitys lopetettiin vuonna 2022, koska ylläpitäjiä ei ollut riittävästi. Koska suuntaamme ponnistuksemme 86Boxin parantamiseen entisestään, olemme päättäneet olla enää tukematta WinBoxia managerina.\n\nWinBoxin kautta ei enää toimiteta päivityksiä, ja saatat kohdata virheellistä käyttäytymistä, jos jatkat sen käyttöä 86Boxin uudemmissa versioissa. Kaikki WinBoxin käyttäytymiseen liittyvät vikailmoitukset suljetaan virheellisinä.\n\nSiirry osoitteeseen 86box.net saadaksesi luettelon muista käyttämistäsi hallintaohjelmista." diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 52bccebd2..c443a881d 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1225,3 +1225,8 @@ msgstr "Rapide" msgid "&Auto-pause on focus loss" msgstr "&Pause automatique à perte de mise au point" +msgid "WinBox is no longer supported" +msgstr "WinBox n'est plus pris en charge" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Le développement du gestionnaire WinBox s'est arrêté en 2022 en raison d'un manque de mainteneurs. Comme nous concentrons nos efforts sur l'amélioration de 86Box, nous avons pris la décision de ne plus supporter WinBox en tant que gestionnaire.\n\nAucune mise à jour ne sera fournie par WinBox, et vous pourriez rencontrer des comportements incorrects si vous continuez à l'utiliser avec des versions plus récentes de 86Box. Tous les rapports de bogues relatifs au comportement de WinBox seront classés comme non valides.\n\nAllez sur 86box.net pour une liste d'autres gestionnaires que vous pouvez utiliser." diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 19b6a6e85..28db9e32d 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1224,3 +1224,9 @@ msgstr "Brzi" msgid "&Auto-pause on focus loss" msgstr "&Automatska pauza pri gubitku fokusa" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 338d2ff5e..07770c077 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -1224,3 +1224,9 @@ msgstr "Gyors" msgid "&Auto-pause on focus loss" msgstr "&Automatikus szünet fókuszvesztéskor" + +msgid "WinBox is no longer supported" +msgstr "A WinBox már nem támogatott" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "A WinBox menedzser fejlesztése 2022-ben leállt karbantartók hiányában. Mivel erőfeszítéseinket a 86Box még jobbá tételére irányítjuk, úgy döntöttünk, hogy a WinBox-ot mint menedzsert nem támogatjuk tovább.\n\nA WinBoxon keresztül nem lesznek további frissítések, és hibás viselkedéssel találkozhat, ha továbbra is a 86Box újabb verzióival használja. A WinBox viselkedésével kapcsolatos hibajelentéseket érvénytelennek nyilvánítjuk.\n\nA 86box.net oldalon talál egy listát más kezelőkről, amelyeket használhat." diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 20c15c656..39ecd7e89 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1224,3 +1224,9 @@ msgstr "Veloce" msgid "&Auto-pause on focus loss" msgstr "&Pausa automatica alla perdita della messa a fuoco" + +msgid "WinBox is no longer supported" +msgstr "WinBox non è più supportato" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Lo sviluppo del gestore WinBox si è interrotto nel 2022 per mancanza di manutentori. Poiché i nostri sforzi sono rivolti a rendere 86Box ancora migliore, abbiamo deciso di non supportare più WinBox come gestore.\n\nNon saranno forniti ulteriori aggiornamenti tramite WinBox e si potrebbe riscontrare un comportamento non corretto se si continua a utilizzarlo con versioni più recenti di 86Box. Tutte le segnalazioni di bug relative al comportamento di WinBox saranno chiuse in quanto non valide.\n\nPer un elenco di altri gestori utilizzabili, visitare 86box.net." diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index ebcaf9cfb..5eb5d23c1 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1224,3 +1224,9 @@ msgstr "速い" msgid "&Auto-pause on focus loss" msgstr "フォーカスが奪われると自動停止(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBoxはサポート終了" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBoxマネージャーの開発は、メンテナ不足のため2022年に停止しました。86Boxをより良いものにするため、WinBoxをマネージャーとしてサポートしないことを決定しました。\n\nWinBoxを使ったアップデートは今後提供されませんし、86Boxの新しいバージョンでWinBoxを使い続けると、正しくない動作に遭遇するかもしれません。WinBoxの動作に関連するバグレポートは無効としてクローズされます。\n\n86box.netに他のマネージャのリストがあります。" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 949548ed1..2eaf53b2e 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -1224,3 +1224,9 @@ msgstr "빠른" msgid "&Auto-pause on focus loss" msgstr "집중력 저하 시 자동 일시 중지(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBox는 더 이상 지원되지 않습니다" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox 매니저의 개발은 유지 관리자의 부족으로 인해 2022년에 중단되었습니다. 86Box를 더욱 개선하기 위한 노력의 일환으로 WinBox 매니저를 더 이상 지원하지 않기로 결정했습니다.\n\nWinBox를 통해 더 이상의 업데이트는 제공되지 않으며, 최신 버전의 86Box를 계속 사용할 경우 잘못된 동작이 발생할 수 있습니다. WinBox 동작과 관련된 모든 버그 보고는 유효하지 않은 것으로 종료됩니다.\n\n사용할 수 있는 다른 관리자 목록을 보려면 86box.net으로 이동하세요." diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index eb7a13e4e..583774ab4 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -1224,3 +1224,9 @@ msgstr "Szybki" msgid "&Auto-pause on focus loss" msgstr "&Automatyczna pauza po utracie fokusu" + +msgid "WinBox is no longer supported" +msgstr "WinBox nie jest już wspierany" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Rozwój menedżera WinBox został zatrzymany w 2022 roku z powodu braku opiekunów. Ponieważ kierujemy nasze wysiłki na uczynienie 86Box jeszcze lepszym, podjęliśmy decyzję o zaprzestaniu wspierania WinBox jako menedżera.\n\nŻadne dalsze aktualizacje nie będą dostarczane za pośrednictwem WinBox i możesz napotkać nieprawidłowe zachowanie, jeśli będziesz go nadal używać z nowszymi wersjami 86Box. Wszelkie zgłoszenia błędów związane z działaniem WinBox zostaną zamknięte jako nieważne.\n\nLista innych menedżerów, z których można korzystać, znajduje się na stronie 86box.net." diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 148ca716c..8ee668a1d 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -1224,3 +1224,9 @@ msgstr "Rápido" msgid "&Auto-pause on focus loss" msgstr "Pausa &automática ao perder o foco" + +msgid "WinBox is no longer supported" +msgstr "O WinBox não é mais suportado" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. Conforme direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nAtualizações não serão mais fornecidas através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de bugs relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar." diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index e309d91bf..6ae146eaf 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1224,3 +1224,9 @@ msgstr "Rápido" msgid "&Auto-pause on focus loss" msgstr "Pausa &automática na perda de focagem" + +msgid "WinBox is no longer supported" +msgstr "O WinBox não é mais suportado" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "O desenvolvimento do gerenciador WinBox parou em 2022 devido à falta de mantenedores. Como direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não mais suportar o WinBox como um gerenciador.\n\nNão serão fornecidas mais actualizações através do WinBox, e poderá encontrar um comportamento incorreto se continuar a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de erros relacionados com o comportamento do WinBox serão fechados como inválidos.\n\nVá a 86box.net para uma lista de outros gestores que pode utilizar." diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 4aa99eb87..cbeeafdd5 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -1314,3 +1314,9 @@ msgstr "Быстрый" msgid "&Auto-pause on focus loss" msgstr "&Автопауза при потере фокуса" + +msgid "WinBox is no longer supported" +msgstr "WinBox больше не поддерживается" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Разработка менеджера WinBox прекратилась в 2022 году из-за отсутствия сопровождающих. Поскольку мы направляем наши усилия на то, чтобы сделать 86Box еще лучше, мы приняли решение больше не поддерживать WinBox в качестве менеджера.\n\nWinBox больше не будет обновляться, и вы можете столкнуться с некорректным поведением, если продолжите использовать его с новыми версиями 86Box. Любые сообщения об ошибках, связанных с поведением WinBox, будут закрыты как недействительные.\n\nПерейдите на сайт 86box.net для получения списка других менеджеров, которые вы можете использовать." diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 376723efa..cdcfcbfe8 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1224,3 +1224,9 @@ msgstr "Rýchly" msgid "&Auto-pause on focus loss" msgstr "&Automatická pauza pri strate fokusu okna" + +msgid "WinBox is no longer supported" +msgstr "WinBox už nie je podporovaný" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Vývoj správcu WinBox sa zastavil v roku 2022 z dôvodu nedostatku správcov. Keďže naše úsilie smerujeme k ešte lepšiemu systému 86Box, rozhodli sme sa, že správca WinBox už nebude podporovaný.\n\nProstredníctvom WinBoxu nebudú poskytované žiadne ďalšie aktualizácie a v prípade, že ho budete naďalej používať s novšími verziami programu 86Box, môžete sa stretnúť s nesprávnym správaním. Všetky hlásenia o chybách týkajúce sa správania WinBoxu budú uzavreté ako neplatné.\n\nNa stránke 86box.net nájdete zoznam iných správcov, ktoré môžete používať." diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index cde1011d1..d56318aed 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1224,3 +1224,9 @@ msgstr "Hitri" msgid "&Auto-pause on focus loss" msgstr "&Samodejni premor ob izgubi fokusa" + +msgid "WinBox is no longer supported" +msgstr "WinBox ni več podprt" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Razvoj upravitelja WinBox se je leta 2022 ustavil zaradi pomanjkanja vzdrževalcev. Ker svoja prizadevanja usmerjamo v še boljše delovanje programa 86Box, smo se odločili, da programa WinBox kot upravitelja ne bomo več podpirali.\n\nWinBox ne bo več zagotavljal posodobitev, če ga boste še naprej uporabljali z novejšimi različicami programa 86Box, pa lahko naletite na nepravilno obnašanje. Vsa poročila o napakah, povezana z obnašanjem programa WinBox, bodo zaprta kot neveljavna.\n\nZa seznam drugih upraviteljev, ki jih lahko uporabite, obiščite spletno stran 86box.net." diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 0989218e5..1af206659 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1224,3 +1224,9 @@ msgstr "Hızlı" msgid "&Auto-pause on focus loss" msgstr "&Odak kaybında otomatik duraklatma" + +msgid "WinBox is no longer supported" +msgstr "WinBox artık desteklenmiyor" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox yöneticisinin geliştirilmesi, bakımcı eksikliği nedeniyle 2022 yılında durduruldu. Çabalarımızı 86Box'ı daha da iyi hale getirmeye yönlendirdiğimiz için, WinBox'ı artık bir yönetici olarak desteklememe kararı aldık.\n\nWinBox aracılığıyla daha fazla güncelleme sağlanmayacak ve 86Box'ın daha yeni sürümleriyle kullanmaya devam ederseniz hatalı davranışlarla karşılaşabilirsiniz. WinBox davranışıyla ilgili tüm hata raporları geçersiz olarak kapatılacaktır.\n\nKullanabileceğiniz diğer yöneticilerin bir listesi için 86box.net adresine gidin." diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 76796a57a..860116fe8 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1224,3 +1224,9 @@ msgstr "Швидкий" msgid "&Auto-pause on focus loss" msgstr "&Автопауза при втраті фокусу" + +msgid "WinBox is no longer supported" +msgstr "WinBox більше не підтримується" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Розробку менеджера WinBox було припинено у 2022 році через брак супровідників. Оскільки ми спрямовуємо наші зусилля на те, щоб зробити 86Box ще кращим, ми прийняли рішення більше не підтримувати WinBox як менеджер.\n\nБільше ніяких оновлень не буде надаватися через WinBox, і ви можете зіткнутися з некоректною поведінкою, якщо продовжите використовувати його з новими версіями 86Box. Будь-які повідомлення про помилки, пов'язані з поведінкою WinBox, будуть закриті як недійсні.\n\nПерейдіть на 86box.net для отримання списку інших менеджерів, які ви можете використовувати." diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index dd819deb0..eade3f77e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1225,3 +1225,8 @@ msgstr "快" msgid "&Auto-pause on focus loss" msgstr "失去焦点时自动暂停(&A)" +msgid "WinBox is no longer supported" +msgstr "WinBox 不再受支持" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "由于缺乏维护者,WinBox 管理器的开发工作于 2022 年停止。由于我们正努力将 86Box 做得更好,因此决定不再支持 WinBox 作为管理器。\n\nWinBox将不再提供更新,如果你继续在86Box的新版本中使用WinBox,可能会遇到不正确的行为。任何与 WinBox 行为相关的错误报告都将被视为无效而关闭。\n\n请访问 86box.net,查看你可以使用的其他管理器列表。" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index aef164704..0e61363f4 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1224,3 +1224,9 @@ msgstr "快" msgid "&Auto-pause on focus loss" msgstr "失去焦點時自動暫停(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index cafd4fd8e..197ca980c 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -58,6 +58,7 @@ extern "C" { # include <86box/discord.h> #endif #include <86box/gdbstub.h> +#include <86box/version.h> } #include @@ -217,6 +218,28 @@ main(int argc, char *argv[]) return 6; } +#ifdef Q_OS_WINDOWS +# if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) + HWND winbox = FindWindow("TWinBoxMain", NULL); + if (winbox && + FindWindowEx(winbox, NULL, "TToolBar", NULL) && + FindWindowEx(winbox, NULL, "TListBox", NULL) && + FindWindowEx(winbox, NULL, "TStatusBar", NULL) && + (winbox = FindWindowEx(winbox, NULL, "TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ + FindWindowEx(winbox, NULL, "TTabSheet", NULL)) +# endif + { + QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("WinBox is no longer supported"), + QObject::tr("Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use."), + QMessageBox::NoButton); + warningbox.addButton(QObject::tr("Continue"), QMessageBox::AcceptRole); + warningbox.addButton(QObject::tr("Exit"), QMessageBox::RejectRole); + warningbox.exec(); + if (warningbox.result() == QDialog::Accepted) + return 0; + } +#endif + if (settings_only) { Settings settings; if (settings.exec() == QDialog::Accepted) { diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 387edaeb8..c51093319 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -169,7 +169,7 @@ ddc_init(void *i2c) STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */ STANDARD_TIMING(standard_timings[3], 1440, STD_ASPECT_16_10, 60); /* 1440x900 */ STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */ - STANDARD_TIMING(standard_timings[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 */ + STANDARD_TIMING(standard_timings[5], 1600, STD_ASPECT_4_3, 60); /* 1600x1200 */ STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */ STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */ @@ -210,12 +210,12 @@ ddc_init(void *i2c) /* High refresh rate timings (VGA is limited to 85 Hz) */ edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ #define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings - STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 85); /* 640x480 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[1], 800, STD_ASPECT_4_3, 85); /* 800x600 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[2], 1024, STD_ASPECT_4_3, 85); /* 1024x768 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[3], 1280, STD_ASPECT_5_4, 85); /* 1280x1024 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[4], 1600, STD_ASPECT_4_3, 85); /* 1600x1200 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 @ 60 Hz (previously in standard timings) */ edid->ext_descriptors[1].ext_standard_timings.padding = 0x0a; for (uint8_t c = 128; c < 255; c++) From a3b8e0f1b2dfaf4d9815780a1d75ff53ecb8a9c7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 10 Mar 2024 18:17:32 -0300 Subject: [PATCH 230/690] DDC: Clarify some comments --- src/video/vid_ddc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index c51093319..787e7560e 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -138,12 +138,12 @@ ddc_init(void *i2c) memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); - edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */ + edid->mfg[0] = 0x09; /* manufacturer "BOX" (currently unassigned by UEFI) */ edid->mfg[1] = 0xf8; edid->mfg_week = 48; edid->mfg_year = 2020 - 1990; edid->edid_version = 0x01; - edid->edid_rev = 0x04; /* EDID 1.4, required for Xorg on Linux to use the preferred mode timing */ + edid->edid_rev = 0x04; /* EDID 1.4, required for Xorg on newer Linux to use the preferred mode timing instead of maxing out */ edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */ edid->horiz_size = round(horiz_mm / 10.0); @@ -207,7 +207,7 @@ ddc_init(void *i2c) /* Detailed timing for 1366x768 */ DETAILED_TIMING(ext_detailed_timings[0], 85500, 1366, 768, 426, 30, 70, 143, 3, 3); - /* High refresh rate timings (VGA is limited to 85 Hz) */ + /* High refresh rate timings (within the standard 85 Hz VGA limit) */ edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ #define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 85); /* 640x480 @ 85 Hz */ From 9f5d2a46bdb21a1ed5ee5a8e692f199b6d1a9742 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 16:35:57 +0600 Subject: [PATCH 231/690] Platform-specific netwok sockets --- src/include/86box/plat_netsocket.h | 24 +++++ src/qt/CMakeLists.txt | 2 +- src/win/win_netsocket.c | 148 +++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/include/86box/plat_netsocket.h create mode 100644 src/win/win_netsocket.c diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h new file mode 100644 index 000000000..269f399ff --- /dev/null +++ b/src/include/86box/plat_netsocket.h @@ -0,0 +1,24 @@ +#ifndef _WIN32 +#define SOCKET int +#else +#include +#include +#endif + +enum net_socket_types +{ + /* Only TCP is supported for now. */ + NET_SOCKET_TCP +}; + +SOCKET plat_netsocket_create(int type); +SOCKET plat_netsocket_create_server(int type, unsigned short port); +void plat_netsocket_close(SOCKET socket); + +SOCKET plat_netsocket_accept(SOCKET socket); +int plat_netsocket_connected(SOCKET socket); +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); + +/* Returns 0 in case of inability to send. -1 in case of errors. */ +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock); +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock); \ No newline at end of file diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4f073cf4a..48b377044 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -221,7 +221,7 @@ if(WIN32 AND NOT MINGW) endif() if(WIN32) - target_sources(plat PRIVATE ../win/win_serial_passthrough.c) + target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) else() target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c) endif() diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c new file mode 100644 index 000000000..45ca1f760 --- /dev/null +++ b/src/win/win_netsocket.c @@ -0,0 +1,148 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/log.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/device.h> +#include <86box/plat_netsocket.h> +#include <86box/ui.h> + +#include +#include +#include + +SOCKET plat_netsocket_create(int type) +{ + SOCKET socket = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + if (socket == INVALID_SOCKET) + return -1; + + ioctlsocket(socket, FIONBIO, &yes); + + return socket; +} + +SOCKET plat_netsocket_create_server(int type, unsigned short port) +{ + struct sockaddr_in sock_addr; + SOCKET socket = plat_netsocket_create(type); + if (socket == INVALID_SOCKET) + return (SOCKET)-1; + + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = port; + + if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { + plat_netsocket_close(socket); + return (SOCKET)-1; + } + + if (listen(socket, 5) == SOCKET_ERROR) { + plat_netsocket_close(socket); + return (SOCKET)-1; + } + + return socket; +} + +void plat_netsocket_close(SOCKET socket) +{ + closesocket((SOCKET)socket); +} + +SOCKET plat_netsocket_accept(SOCKET socket) +{ + SOCKET clientsocket = accept(socket, NULL, NULL); + + if (clientsocket == INVALID_SOCKET) + return -1; + + return clientsocket; +} + +int plat_netsocket_connected(SOCKET socket) +{ + struct sockaddr addr; + socklen_t len = sizeof(struct sockaddr); + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + return 0; + + return 1; +} + +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +{ + struct sockaddr_in sock_addr; + int res = -1; + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = inet_addr(hostname); + sock_addr.sin_port = htons(port); + + if (sock_addr.sin_addr.s_addr == -1 || sock_addr.sin_addr.s_addr == 0) { + struct hostent *hp; + + hp = gethostbyname(hostname); + + if (hp) + memcpy(&sock_addr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); + else + return -1; + } + + res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (error == WSAEISCONN) + return 0; + } + return res; +} + +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = send(socket, (const char*)data, size, 0); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (wouldblock) + *wouldblock = !!(error == WSAEWOULDBLOCK); + + return -1; + } + return res; +} + +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = recv(socket, (char*)data, size, 0); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (wouldblock) + *wouldblock = !!(error == WSAEWOULDBLOCK); + + return -1; + } + return res; +} From 45e76af96fc298e9f1695dd33d9ffb6d2d24d1ba Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 11 Mar 2024 19:25:13 +0500 Subject: [PATCH 232/690] Disable the LBA Enhancer checkbox when the ROM isn't available --- src/qt/qt_settingsstoragecontrollers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 0f19d46fc..bc2be70cd 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -206,6 +206,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setEnabled(false); } + ui->checkBoxLbaEnhancer->setEnabled(device_available(&lba_enhancer_device)); ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } From 8f9f5b2efbb56255ef28d256d17040403e932c44 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 11 Mar 2024 19:25:45 +0500 Subject: [PATCH 233/690] Disable the XGA checkbox when ROMs aren't available --- src/qt/qt_settingsdisplay.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index fcb70f8c5..4d8919a73 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -159,15 +159,16 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool videoCardHas8514 = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_8514A) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_8514)); bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); - ui->checkBox8514->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHas8514); - if (machineHasIsa16 || machineHasMca) - ui->checkBox8514->setChecked(ibm8514_standalone_enabled && !videoCardHas8514); + bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514); + bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga); - ui->checkBoxXga->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHasXga); - if (machineHasIsa16 || machineHasMca) - ui->checkBoxXga->setChecked(xga_standalone_enabled && !videoCardHasXga); + ui->checkBox8514->setEnabled(machineSupports8514); + ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514); - ui->pushButtonConfigureXga->setEnabled((machineHasIsa16 || machineHasMca) && ui->checkBoxXga->isChecked() && !videoCardHasXga); + ui->checkBoxXga->setEnabled(machineSupportsXga); + ui->checkBoxXga->setChecked(xga_standalone_enabled && machineSupportsXga); + + ui->pushButtonConfigureXga->setEnabled(ui->checkBoxXga->isEnabled() && ui->checkBoxXga->isChecked()); int c = 2; From 10e0dbaafa4e735ca48f2fff33be4f934ccd683d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 01:55:17 +0600 Subject: [PATCH 234/690] Netsocket changes --- src/include/86box/plat_netsocket.h | 2 +- src/win/win_netsocket.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h index 269f399ff..9a2181ae1 100644 --- a/src/include/86box/plat_netsocket.h +++ b/src/include/86box/plat_netsocket.h @@ -16,7 +16,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port); void plat_netsocket_close(SOCKET socket); SOCKET plat_netsocket_accept(SOCKET socket); -int plat_netsocket_connected(SOCKET socket); +int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); /* Returns 0 in case of inability to send. -1 in case of errors. */ diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 45ca1f760..044a59860 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -80,6 +80,9 @@ int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); + + + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) return 0; @@ -113,6 +116,8 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (error == WSAEISCONN) return 0; + + res = -1; } return res; } From 3aa81066d3c01b69bf546521d72045a1617d3543 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 11 Mar 2024 21:39:16 +0100 Subject: [PATCH 235/690] Solved the IRQ mess of ESDI MCA. This should also fix the timing/fatal's on ramdisk speeds using said controller on NT and OS/2 on MCA. --- src/disk/hdc_esdi_mca.c | 95 ++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 02f054ca2..3714f93d4 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -92,7 +92,7 @@ #define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" #define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" -#define ESDI_TIME 512.0 +#define ESDI_TIME 500.0 #define CMD_ADAPTER 0 typedef struct esdi_drive_t { @@ -113,6 +113,7 @@ typedef struct esdi_t { uint8_t basic_ctrl; uint8_t status; uint8_t irq_status; + int irq_ena_disable; int irq_in_progress; int cmd_req_in_progress; int cmd_pos; @@ -218,14 +219,26 @@ esdi_mca_log(const char *fmt, ...) static __inline void set_irq(esdi_t *dev) { + dev->irq_ena_disable = 1; + esdi_mca_log("Set IRQ 14: bit=%x, cmd=%02x.\n", dev->basic_ctrl & CTRL_IRQ_ENA, dev->command); if (dev->basic_ctrl & CTRL_IRQ_ENA) - picint(1 << 14); + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, 1, NULL); } static __inline void -clear_irq(UNUSED(esdi_t *dev)) +clear_irq(esdi_t *dev) { - picintc(1 << 14); + dev->irq_ena_disable = 0; + esdi_mca_log("Clear IRQ 14: bit=%x, cmd=%02x.\n", dev->basic_ctrl & CTRL_IRQ_ENA, dev->command); + if (dev->basic_ctrl & CTRL_IRQ_ENA) + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, 0, NULL); +} + +static __inline void +update_irq(esdi_t *dev) +{ + uint8_t set = (dev->basic_ctrl & CTRL_IRQ_ENA) && dev->irq_ena_disable; + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, set, NULL); } static void @@ -235,10 +248,11 @@ esdi_mca_set_callback(esdi_t *dev, double callback) return; } - if (callback) { - timer_on_auto(&dev->timer, callback); - } else { + if (callback == 0.0) { + esdi_mca_log("Callback Stopped.\n"); timer_stop(&dev->timer); + } else { + timer_on_auto(&dev->timer, callback); } } @@ -317,9 +331,9 @@ complete_command_status(esdi_t *dev) { dev->status_len = 7; if (dev->cmd_dev == ATTN_DEVICE_0) - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); + dev->status_data[0] = dev->command | STATUS_LEN(7) | STATUS_DEVICE(0); else - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); + dev->status_data[0] = dev->command | STATUS_LEN(7) | STATUS_DEVICE(1); dev->status_data[1] = 0x0000; /*Error bits*/ dev->status_data[2] = 0x1900; /*Device status*/ dev->status_data[3] = 0; /*Number of blocks left to do*/ @@ -330,15 +344,12 @@ complete_command_status(esdi_t *dev) } #define ESDI_ADAPTER_ONLY() \ - do { \ if (dev->cmd_dev != ATTN_HOST_ADAPTER) { \ cmd_unsupported(dev); \ return; \ - } \ - } while (0) + } #define ESDI_DRIVE_ONLY() \ - do { \ if (dev->cmd_dev != ATTN_DEVICE_0 && dev->cmd_dev != ATTN_DEVICE_1) { \ cmd_unsupported(dev); \ return; \ @@ -346,8 +357,7 @@ complete_command_status(esdi_t *dev) if (dev->cmd_dev == ATTN_DEVICE_0) \ drive = &dev->drives[0]; \ else \ - drive = &dev->drives[1]; \ - } while (0) + drive = &dev->drives[1]; static void esdi_callback(void *priv) @@ -357,19 +367,19 @@ esdi_callback(void *priv) int val; double cmd_time = 0.0; - esdi_mca_set_callback(dev, 0); - /* If we are returning from a RESET, handle this first. */ if (dev->in_reset) { + esdi_mca_log("ESDI reset.\n"); dev->in_reset = 0; dev->status = STATUS_IRQ; dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; - return; } + esdi_mca_log("Command=%02x.\n", dev->command); switch (dev->command) { case CMD_READ: + case 0x15: ESDI_DRIVE_ONLY(); if (!drive->present) { @@ -379,7 +389,8 @@ esdi_callback(void *priv) switch (dev->cmd_state) { case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + if (dev->command == CMD_READ) + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; dev->sector_pos = 0; dev->sector_count = dev->cmd_data[1]; @@ -873,7 +884,7 @@ static uint8_t esdi_read(uint16_t port, void *priv) { esdi_t *dev = (esdi_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0x00; switch (port & 7) { case 2: /*Basic status register*/ @@ -890,6 +901,7 @@ esdi_read(uint16_t port, void *priv) break; } + esdi_mca_log("ESDI: rr(%04x, %02x)\n", port & 7, ret); return ret; } @@ -897,6 +909,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *priv) { esdi_t *dev = (esdi_t *) priv; + uint8_t old; esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val); @@ -906,11 +919,14 @@ esdi_write(uint16_t port, uint8_t val, void *priv) dev->in_reset = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; + } else if (!(dev->basic_ctrl & CTRL_RESET) && (val & CTRL_RESET)) { + esdi_mca_set_callback(dev, 0.0); + dev->status = STATUS_BUSY; } + old = dev->basic_ctrl; dev->basic_ctrl = val; - - if (!(dev->basic_ctrl & CTRL_IRQ_ENA)) - picintc(1 << 14); + if ((val & CTRL_IRQ_ENA) && !(old & CTRL_IRQ_ENA)) + update_irq(dev); break; case 3: /*Attention register*/ @@ -945,6 +961,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) break; case ATTN_DEVICE_0: + esdi_mca_log("ATTN Device 0.\n"); switch (val & ATTN_REQ_MASK) { case ATTN_CMD_REQ: if (dev->cmd_req_in_progress) @@ -957,6 +974,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) break; case ATTN_EOI: + esdi_mca_log("EOI.\n"); dev->irq_in_progress = 0; dev->status &= ~STATUS_IRQ; clear_irq(dev); @@ -1112,15 +1130,40 @@ esdi_mca_write(int port, uint8_t val, void *priv) break; } + if (!(dev->pos_regs[3] & 8)) { + switch (dev->pos_regs[3] & 7) { + case 2: + dev->bios = 0xc8000; + break; + case 3: + dev->bios = 0xcc000; + break; + case 4: + dev->bios = 0xd0000; + break; + case 5: + dev->bios = 0xd4000; + break; + case 6: + dev->bios = 0xd8000; + break; + case 7: + dev->bios = 0xdc000; + break; + default: + break; + } + } else + dev->bios = 0; + if (dev->pos_regs[2] & 1) { io_sethandler(ESDI_IOADDR_PRI, 8, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, dev); - if (!(dev->pos_regs[3] & 8)) { + if (dev->bios) { mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - ((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios, 0x4000); } /* Say hello. */ From d51ba85814a3e4e6aee0782dd2ce71c248d33f98 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 14:27:19 +0600 Subject: [PATCH 236/690] TCP/IP support --- src/device/serial.c | 6 + src/include/86box/serial.h | 1 + src/network/net_modem.c | 241 ++++++++++++++++++++++++++++++++++++- src/qt/CMakeLists.txt | 2 +- src/unix/unix_netsocket.c | 194 +++++++++++++++++++++++++++++ src/win/win_netsocket.c | 45 ++++++- 6 files changed, 479 insertions(+), 10 deletions(-) create mode 100644 src/unix/unix_netsocket.c diff --git a/src/device/serial.c b/src/device/serial.c index b61c8304a..ab26fc622 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -451,6 +451,12 @@ serial_set_ri(serial_t *dev, uint8_t enabled) } } +int +serial_get_ri(serial_t *dev) +{ + return !!(dev->msr & (1 << 6)); +} + void serial_set_clock_src(serial_t *dev, double clock_src) { diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 99b39f56b..c2312f562 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -137,6 +137,7 @@ extern void serial_set_cts(serial_t *dev, uint8_t enabled); extern void serial_set_dsr(serial_t *dev, uint8_t enabled); extern void serial_set_dcd(serial_t *dev, uint8_t enabled); extern void serial_set_ri(serial_t *dev, uint8_t enabled); +extern int serial_get_ri(serial_t *dev); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 131b87653..6e6635ed8 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -20,6 +20,7 @@ #include <86box/plat.h> #include <86box/network.h> #include <86box/plat_unused.h> +#include <86box/plat_netsocket.h> /* From RFC 1055. */ #define END 0300 /* indicates end of packet */ @@ -93,9 +94,17 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; + bool tcpIpMode, tcpIpConnInProgress; + uint32_t tcpIpConnCounter; int doresponse; int cmdpause; + int listen_port; + int ringtimer; + + SOCKET serversocket; + SOCKET clientsocket; + SOCKET waitingclientsocket; struct { bool binary[2]; @@ -309,7 +318,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; - if (data == END) { + if (data == END && !modem->tcpIpMode) { process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); modem->tx_count = 0; } @@ -321,6 +330,9 @@ host_to_modem_cb(void *priv) { modem_t* modem = (modem_t*)priv; + if (modem->in_warmup) + goto no_write_to_machine; + if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { if (fifo_get_full(modem->serial->rcvr_fifo)) { goto no_write_to_machine; @@ -441,6 +453,37 @@ modem_enter_idle_state(modem_t* modem) modem->ringing = false; modem->mode = MODEM_MODE_COMMAND; modem->in_warmup = 0; + modem->tcpIpConnInProgress = 0; + modem->tcpIpConnCounter = 0; + + if (modem->waitingclientsocket != -1) + plat_netsocket_close(modem->waitingclientsocket); + + if (modem->clientsocket != -1) + plat_netsocket_close(modem->clientsocket); + + modem->clientsocket = modem->waitingclientsocket = -1; + if (modem->serversocket != -1) { + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + while (modem->waitingclientsocket != -1) { + plat_netsocket_close(modem->waitingclientsocket); + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + } + plat_netsocket_close(modem->serversocket); + modem->serversocket = -1; + } + + if (modem->waitingclientsocket != -1) + plat_netsocket_close(modem->waitingclientsocket); + + modem->waitingclientsocket = -1; + modem->tcpIpMode = false; + modem->tcpIpConnInProgress = false; + + if (modem->listen_port) { + modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); + } + serial_set_cts(modem->serial, 1); serial_set_dsr(modem->serial, 1); serial_set_dcd(modem->serial, 0); @@ -454,6 +497,9 @@ modem_enter_connected_state(modem_t* modem) modem->mode = MODEM_MODE_DATA; modem->ringing = false; modem->connected = true; + modem->tcpIpMode = true; + plat_netsocket_close(modem->serversocket); + modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); serial_set_dcd(modem->serial, 1); serial_set_ri(modem->serial, 0); @@ -488,15 +534,40 @@ void modem_dial(modem_t* modem, const char* str) { /* TODO: Port TCP/IP support from DOSBox. */ + modem->tcpIpConnCounter = 0; + modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); + modem->tcpIpMode = false; } else { - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + char buf[128] = ""; + const char *destination = buf; + strcpy(buf, str); + // Scan host for port + uint16_t port; + char * hasport = strrchr(buf,':'); + if (hasport) { + *hasport++ = 0; + port = (uint16_t)atoi(hasport); + } + else { + port = 23; + } + + modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); + if (modem->clientsocket == -1) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + + plat_netsocket_connect(modem->clientsocket, buf, port); + modem->tcpIpConnInProgress = 1; + modem->tcpIpConnCounter = 0; } } @@ -551,6 +622,16 @@ char *trim(char *str) return str; } +static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { + int i = 0; + for (i = 0; i < modem->entries_num; i++) { + if (strcmp(input, modem->entries[i].phone) == 0) + return modem->entries[i].address; + } + + return NULL; +} + static void modem_do_command(modem_t* modem) { @@ -583,7 +664,9 @@ modem_do_command(modem_t* modem) char buffer[128]; char obuffer[128]; char * foundstr = &scanbuf[0]; + const char *mappedaddr = NULL; size_t i = 0; + if (*foundstr == 'T' || *foundstr == 'P') foundstr++; @@ -593,6 +676,13 @@ modem_do_command(modem_t* modem) } foundstr = trim(foundstr); + + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); + if (mappedaddr) { + modem_dial(modem, mappedaddr); + return; + } + if (strlen(foundstr) >= 12) { // Check if supplied parameter only consists of digits bool isNum = true; @@ -860,6 +950,9 @@ modem_rx(void *priv, uint8_t *buf, int io_len) uint8_t c = 0; uint32_t i = 0; + if (modem->tcpIpMode) + return 0; + if (!modem->connected) { /* Drop packet. */ pclog("Dropping %d bytes\n", io_len - 14); @@ -914,12 +1007,127 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) #endif } +static void +modem_accept_incoming_call(modem_t* modem) +{ + if (modem->waitingclientsocket != -1) { + modem->clientsocket = modem->waitingclientsocket; + modem->waitingclientsocket = -1; + modem_enter_connected_state(modem); + modem->in_warmup = 250; + } else { + modem_enter_idle_state(modem); + } +} + static void modem_cmdpause_timer_callback(void *priv) { modem_t *dev = (modem_t *) priv; uint32_t guard_threashold = 0; + if (dev->tcpIpConnInProgress) { + int status = plat_netsocket_connected(dev->clientsocket); + + if (status == -1) { + plat_netsocket_close(dev->clientsocket); + dev->clientsocket = -1; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + dev->tcpIpConnInProgress = 0; + } else if (status == 1) { + modem_enter_connected_state(dev); + dev->tcpIpConnInProgress = 0; + } + + dev->tcpIpConnCounter++; + + if (status <= 0 && dev->tcpIpConnCounter >= 5000) { + plat_netsocket_close(dev->clientsocket); + dev->clientsocket = -1; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOANSWER); + dev->tcpIpConnInProgress = 0; + dev->tcpIpMode = 0; + } + } + + if (!dev->connected && dev->waitingclientsocket == -1 && dev->serversocket != -1) { + dev->waitingclientsocket = plat_netsocket_accept(dev->serversocket); + if (dev->waitingclientsocket != -1) { + if (!(dev->serial->mctrl & 1) && dev->dtrmode != 0) { + modem_enter_idle_state(dev); + } else { + dev->ringing = true; + modem_send_res(dev, ResRING); + serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + dev->ringtimer = 3000; + dev->reg[MREG_RING_COUNT] = 0; + } + } + } + if (dev->ringing) { + if (dev->ringtimer <= 0) { + dev->reg[MREG_RING_COUNT]++; + if ((dev->reg[MREG_AUTOANSWER_COUNT] > 0) && + (dev->reg[MREG_RING_COUNT] >= dev->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(dev); + return; + } + modem_send_res(dev, ResRING); + serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + + //MIXER_Enable(mhd.chan,true); + dev->ringtimer = 3000; + } + --dev->ringtimer; + } + + if (dev->in_warmup) { + dev->in_warmup--; + if (dev->in_warmup == 0) { + dev->tx_count = 0; + fifo8_reset(&dev->rx_data); + } + } + else if (dev->connected && dev->tcpIpMode) { + if (dev->tx_count) { + int wouldblock = 0; + int res = plat_netsocket_send(dev->clientsocket, dev->tx_pkt_ser_line, dev->tx_count, &wouldblock); + + if (res <= 0 && !wouldblock) { + /* No bytes sent or error. */ + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } else if (res > 0) { + if (res == dev->tx_count) { + dev->tx_count = 0; + } else { + memmove(dev->tx_pkt_ser_line, &dev->tx_pkt_ser_line[res], dev->tx_count - res); + dev->tx_count -= res; + } + } + } + if (dev->connected) { + uint8_t buffer[16]; + int wouldblock = 0; + int res = plat_netsocket_receive(dev->clientsocket, buffer, sizeof(buffer), &wouldblock); + + if (res > 0) { + fifo8_push_all(&dev->rx_data, buffer, res); + } else if (res == 0) { + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } else if (!wouldblock) { + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } + } + } + dev->cmdpause++; guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); if (dev->cmdpause > guard_threashold) { @@ -938,11 +1146,13 @@ static void * modem_init(const device_t *info) { modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); + const char* phonebook_file = NULL; memset(modem->mac, 0xfc, 6); modem->port = device_get_config_int("port"); modem->baudrate = device_get_config_int("baudrate"); + modem->listen_port = device_get_config_int("listen_port"); fifo8_create(&modem->data_pending, 0x10000); fifo8_create(&modem->rx_data, 0x10000); @@ -955,12 +1165,20 @@ modem_init(const device_t *info) modem_reset(modem); modem->card = network_attach(modem, modem->mac, modem_rx, NULL); + + phonebook_file = device_get_config_string("phonebook_file"); + if (phonebook_file && phonebook_file[0] != 0) { + modem_read_phonebook_file(modem, phonebook_file); + } + return modem; } void modem_close(void *priv) { modem_t* modem = (modem_t*)priv; + modem->listen_port = 0; + modem_reset(modem); fifo8_destroy(&modem->data_pending); fifo8_destroy(&modem->rx_data); netcard_close(modem->card); @@ -1009,6 +1227,23 @@ static const device_config_t modem_config[] = { { .description = "300", .value = 300 }, } }, + { + .name = "listen_port", + .description = "TCP/IP listening port", + .type = CONFIG_INT, + .default_string = "", + .default_int = 5000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = {} + }, + { + .name = "phonebook_file", + .description = "Phonebook File", + .type = CONFIG_FNAME, + .default_string = "", + .file_filter = "Text files (*.txt)|*.txt" + }, { .name = "", .description = "", .type = CONFIG_END } }; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 48b377044..7133093b6 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -223,7 +223,7 @@ endif() if(WIN32) target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) else() - target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c) + target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) endif() if (APPLE) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c new file mode 100644 index 000000000..bf0dd45da --- /dev/null +++ b/src/unix/unix_netsocket.c @@ -0,0 +1,194 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/log.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/device.h> +#include <86box/plat_netsocket.h> +#include <86box/ui.h> + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SOCKET plat_netsocket_create(int type) +{ + SOCKET fd = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + return fd; +} + +SOCKET plat_netsocket_create_server(int type, unsigned short port) +{ + struct sockaddr_in sock_addr; + SOCKET fd = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = port; + + if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { + plat_netsocket_close(fd); + return (SOCKET)-1; + } + + if (listen(fd, 5) == -1) { + plat_netsocket_close(fd); + return (SOCKET)-1; + } + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + return fd; +} + +void plat_netsocket_close(SOCKET socket) +{ + close((SOCKET)socket); +} + +SOCKET plat_netsocket_accept(SOCKET socket) +{ + SOCKET clientsocket = accept(socket, NULL, NULL); + + if (clientsocket == -1) + return -1; + + return clientsocket; +} + +int plat_netsocket_connected(SOCKET socket) +{ + struct sockaddr addr; + socklen_t len = sizeof(struct sockaddr); + fd_set wrfds; + struct timeval tv; + int res = -1; + int status = 0; + int optlen = 4; + + FD_ZERO(&wrfds); + FD_SET(socket, &wrfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + res = select(socket + 1, NULL, &wrfds, NULL, &tv); + + if (res == -1) + return -1; + + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) + return 0; + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + if (res == -1) + return -1; + + if (status != 0) + return -1; + + if (getpeername(socket, &addr, &len) == -1) + return -1; + + return 1; +} + +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +{ + struct sockaddr_in sock_addr; + int res = -1; + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = inet_addr(hostname); + sock_addr.sin_port = htons(port); + + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { + struct hostent *hp; + + hp = gethostbyname(hostname); + + if (hp) + memcpy(&sock_addr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); + else + return -1; + } + + res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + + if (res == -1) { + int error = errno; + + if (error == EISCONN) + return 0; + + res = -1; + } + return res; +} + +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = send(socket, (const char*)data, size, 0); + + if (res == -1) { + int error = errno; + + if (wouldblock) + *wouldblock = !!(error == EWOULDBLOCK || error == EAGAIN); + + return -1; + } + return res; +} + +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = recv(socket, (char*)data, size, 0); + + if (res == -1) { + int error = errno; + + if (wouldblock) + *wouldblock = !!(error == EWOULDBLOCK || error == EAGAIN); + + return -1; + } + return res; +} diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 044a59860..6bbd7aafb 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -38,9 +38,15 @@ SOCKET plat_netsocket_create(int type) SOCKET plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET socket = plat_netsocket_create(type); + SOCKET socket = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) - return (SOCKET)-1; + return -1; memset(&sock_addr, 0, sizeof(struct sockaddr_in)); @@ -58,6 +64,8 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) return (SOCKET)-1; } + ioctlsocket(socket, FIONBIO, &yes); + return socket; } @@ -79,13 +87,38 @@ SOCKET plat_netsocket_accept(SOCKET socket) int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; - socklen_t len = sizeof(struct sockaddr); + socklen_t len = sizeof(struct sockaddr); + fd_set wrfds; + struct timeval tv; + int res = SOCKET_ERROR; + int status = 0; + int optlen = 4; + FD_ZERO(&wrfds); + FD_SET(socket, &wrfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + res = select(1, NULL, &wrfds, NULL, &tv); + + if (res == SOCKET_ERROR) + return -1; - - if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + if (res == SOCKET_ERROR) + return -1; + + if (status != 0) + return -1; + + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + return -1; + return 1; } @@ -98,7 +131,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == -1 || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { struct hostent *hp; hp = gethostbyname(hostname); From fb8ff563b2f37583554ebcfa3f10f8931a7d2f35 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 14:29:24 +0600 Subject: [PATCH 237/690] Oversight --- src/network/net_modem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6e6635ed8..c584ae820 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1154,6 +1154,8 @@ modem_init(const device_t *info) modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); + modem->clientsocket = modem->serversocket = modem->waitingclientsocket = -1; + fifo8_create(&modem->data_pending, 0x10000); fifo8_create(&modem->rx_data, 0x10000); From 59466a74f44a3b0cb9d8b631551bc5ed54fddcc0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:01:00 +0600 Subject: [PATCH 238/690] More TCP/IP related changes --- src/network/net_modem.c | 198 ++++++++++++++++++++------------------ src/unix/unix_netsocket.c | 2 +- src/win/win_netsocket.c | 15 ++- 3 files changed, 120 insertions(+), 95 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index c584ae820..64e16d920 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -456,32 +456,35 @@ modem_enter_idle_state(modem_t* modem) modem->tcpIpConnInProgress = 0; modem->tcpIpConnCounter = 0; - if (modem->waitingclientsocket != -1) + if (modem->waitingclientsocket != (SOCKET)-1) plat_netsocket_close(modem->waitingclientsocket); - if (modem->clientsocket != -1) + if (modem->clientsocket != (SOCKET)-1) plat_netsocket_close(modem->clientsocket); - modem->clientsocket = modem->waitingclientsocket = -1; - if (modem->serversocket != -1) { + modem->clientsocket = modem->waitingclientsocket = (SOCKET)-1; + if (modem->serversocket != (SOCKET)-1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); - while (modem->waitingclientsocket != -1) { + while (modem->waitingclientsocket != (SOCKET)-1) { plat_netsocket_close(modem->waitingclientsocket); modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); } plat_netsocket_close(modem->serversocket); - modem->serversocket = -1; + modem->serversocket = (SOCKET)-1; } - if (modem->waitingclientsocket != -1) + if (modem->waitingclientsocket != (SOCKET)-1) plat_netsocket_close(modem->waitingclientsocket); - modem->waitingclientsocket = -1; + modem->waitingclientsocket = (SOCKET)-1; modem->tcpIpMode = false; modem->tcpIpConnInProgress = false; if (modem->listen_port) { modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); + if (modem->serversocket == (SOCKET)-1) { + pclog("Failed to set up server on port %d\n", modem->listen_port); + } } serial_set_cts(modem->serial, 1); @@ -560,12 +563,18 @@ modem_dial(modem_t* modem, const char* str) modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { + pclog("Failed to create client socket\n"); modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); return; } - plat_netsocket_connect(modem->clientsocket, buf, port); + if (-1 == plat_netsocket_connect(modem->clientsocket, buf, port)) { + pclog("Failed to connect to %s\n", buf); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } modem->tcpIpConnInProgress = 1; modem->tcpIpConnCounter = 0; } @@ -724,6 +733,7 @@ modem_do_command(modem_t* modem) } } modem_dial(modem, foundstr); + break; } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { @@ -1023,120 +1033,125 @@ modem_accept_incoming_call(modem_t* modem) static void modem_cmdpause_timer_callback(void *priv) { - modem_t *dev = (modem_t *) priv; + modem_t *modem = (modem_t *) priv; uint32_t guard_threashold = 0; + timer_on_auto(&modem->cmdpause_timer, 1000); - if (dev->tcpIpConnInProgress) { - int status = plat_netsocket_connected(dev->clientsocket); + if (modem->tcpIpConnInProgress) { + do { + int status = plat_netsocket_connected(modem->clientsocket); - if (status == -1) { - plat_netsocket_close(dev->clientsocket); - dev->clientsocket = -1; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); - dev->tcpIpConnInProgress = 0; - } else if (status == 1) { - modem_enter_connected_state(dev); - dev->tcpIpConnInProgress = 0; - } + if (status == -1) { + plat_netsocket_close(modem->clientsocket); + modem->clientsocket = -1; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem->tcpIpConnInProgress = 0; + break; + } else if (status == 1) { + modem_enter_connected_state(modem); + modem->tcpIpConnInProgress = 0; + break; + } - dev->tcpIpConnCounter++; + modem->tcpIpConnCounter++; - if (status <= 0 && dev->tcpIpConnCounter >= 5000) { - plat_netsocket_close(dev->clientsocket); - dev->clientsocket = -1; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOANSWER); - dev->tcpIpConnInProgress = 0; - dev->tcpIpMode = 0; - } + if (status < 0 || (status == 0 && modem->tcpIpConnCounter >= 5000)) { + plat_netsocket_close(modem->clientsocket); + modem->clientsocket = -1; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOANSWER); + modem->tcpIpConnInProgress = 0; + modem->tcpIpMode = 0; + break; + } + } while (0); } - if (!dev->connected && dev->waitingclientsocket == -1 && dev->serversocket != -1) { - dev->waitingclientsocket = plat_netsocket_accept(dev->serversocket); - if (dev->waitingclientsocket != -1) { - if (!(dev->serial->mctrl & 1) && dev->dtrmode != 0) { - modem_enter_idle_state(dev); + if (!modem->connected && modem->waitingclientsocket == -1 && modem->serversocket != -1) { + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + if (modem->waitingclientsocket != -1) { + if (!(modem->serial->mctrl & 1) && modem->dtrmode != 0) { + modem_enter_idle_state(modem); } else { - dev->ringing = true; - modem_send_res(dev, ResRING); - serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); - dev->ringtimer = 3000; - dev->reg[MREG_RING_COUNT] = 0; + modem->ringing = true; + modem_send_res(modem, ResRING); + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + modem->ringtimer = 3000; + modem->reg[MREG_RING_COUNT] = 0; } } } - if (dev->ringing) { - if (dev->ringtimer <= 0) { - dev->reg[MREG_RING_COUNT]++; - if ((dev->reg[MREG_AUTOANSWER_COUNT] > 0) && - (dev->reg[MREG_RING_COUNT] >= dev->reg[MREG_AUTOANSWER_COUNT])) { - modem_accept_incoming_call(dev); + if (modem->ringing) { + if (modem->ringtimer <= 0) { + modem->reg[MREG_RING_COUNT]++; + if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && + (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(modem); return; } - modem_send_res(dev, ResRING); - serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + modem_send_res(modem, ResRING); + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - //MIXER_Enable(mhd.chan,true); - dev->ringtimer = 3000; + modem->ringtimer = 3000; } - --dev->ringtimer; + --modem->ringtimer; } - if (dev->in_warmup) { - dev->in_warmup--; - if (dev->in_warmup == 0) { - dev->tx_count = 0; - fifo8_reset(&dev->rx_data); + if (modem->in_warmup) { + modem->in_warmup--; + if (modem->in_warmup == 0) { + modem->tx_count = 0; + fifo8_reset(&modem->rx_data); } } - else if (dev->connected && dev->tcpIpMode) { - if (dev->tx_count) { + else if (modem->connected && modem->tcpIpMode) { + if (modem->tx_count) { int wouldblock = 0; - int res = plat_netsocket_send(dev->clientsocket, dev->tx_pkt_ser_line, dev->tx_count, &wouldblock); + int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); if (res <= 0 && !wouldblock) { /* No bytes sent or error. */ - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } else if (res > 0) { - if (res == dev->tx_count) { - dev->tx_count = 0; + if (res == modem->tx_count) { + modem->tx_count = 0; } else { - memmove(dev->tx_pkt_ser_line, &dev->tx_pkt_ser_line[res], dev->tx_count - res); - dev->tx_count -= res; + memmove(modem->tx_pkt_ser_line, &modem->tx_pkt_ser_line[res], modem->tx_count - res); + modem->tx_count -= res; } } } - if (dev->connected) { + if (modem->connected) { uint8_t buffer[16]; int wouldblock = 0; - int res = plat_netsocket_receive(dev->clientsocket, buffer, sizeof(buffer), &wouldblock); + int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { - fifo8_push_all(&dev->rx_data, buffer, res); + fifo8_push_all(&modem->rx_data, buffer, res); } else if (res == 0) { - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } else if (!wouldblock) { - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } } } - dev->cmdpause++; - guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); - if (dev->cmdpause > guard_threashold) { - if (dev->plusinc == 0) { - dev->plusinc = 1; - } else if (dev->plusinc == 4) { - dev->mode = MODEM_MODE_COMMAND; - modem_send_res(dev, ResOK); - dev->plusinc = 0; + modem->cmdpause++; + guard_threashold = (uint32_t)(modem->reg[MREG_GUARD_TIME] * 20); + if (modem->cmdpause > guard_threashold) { + if (modem->plusinc == 0) { + modem->plusinc = 1; + } else if (modem->plusinc == 4) { + modem->mode = MODEM_MODE_COMMAND; + modem_send_res(modem, ResOK); + modem->plusinc = 0; } } } @@ -1232,12 +1247,13 @@ static const device_config_t modem_config[] = { { .name = "listen_port", .description = "TCP/IP listening port", - .type = CONFIG_INT, - .default_string = "", - .default_int = 5000, - .file_filter = NULL, - .spinner = { 0 }, - .selection = {} + .type = CONFIG_SPINNER, + .spinner = + { + .min = 0, + .max = 32767 + }, + .default_int = 0 }, { .name = "phonebook_file", diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index bf0dd45da..e0353a463 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -155,7 +155,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (res == -1) { int error = errno; - if (error == EISCONN) + if (error == EISCONN || error == EWOULDBLOCK || error == EAGAIN || error == EINPROGRESS) return 0; res = -1; diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 6bbd7aafb..0f8c5f87a 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -17,6 +17,7 @@ #include #include #include +#include SOCKET plat_netsocket_create(int type) { @@ -88,23 +89,31 @@ int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); - fd_set wrfds; + fd_set wrfds, exfds; struct timeval tv; int res = SOCKET_ERROR; int status = 0; int optlen = 4; FD_ZERO(&wrfds); + FD_ZERO(&exfds); FD_SET(socket, &wrfds); + FD_SET(socket, &exfds); tv.tv_sec = 0; tv.tv_usec = 0; - res = select(1, NULL, &wrfds, NULL, &tv); + res = select(socket + 1, NULL, &wrfds, &exfds, &tv); if (res == SOCKET_ERROR) return -1; + if (res >= 1 && FD_ISSET(socket, &exfds)) { + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + pclog("Socket error %d\n", status); + return -1; + } + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; @@ -147,7 +156,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (res == SOCKET_ERROR) { int error = WSAGetLastError(); - if (error == WSAEISCONN) + if (error == WSAEISCONN || error == WSAEWOULDBLOCK) return 0; res = -1; From 6be8ada352e732056803a2837b7eae8caf90de9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:04:29 +0600 Subject: [PATCH 239/690] Copyright text --- src/network/net_modem.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 64e16d920..b79669da7 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,5 +1,22 @@ -/* TODO: SLIP support. */ +/* + * 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. + * + * Hayes AT-compliant modem emulation. + * + * + * + * Authors: Cacodemon345 + * The DOSBox Team + * + * Copyright 2024 Cacodemon345 + * Copyright 2002-2021 The DOSBox Team + */ #include #include From babadfb5c28c1533fa67030caa5de1b0993af161 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:23:35 +0600 Subject: [PATCH 240/690] Handle large packets being sent --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 131b87653..120887bcc 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -866,7 +866,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) return 0; } - if ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { + while ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } From 074de35653d7c72598a81b8163324fb4d0905cd5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:34:01 +0600 Subject: [PATCH 241/690] Telnet emulation --- src/network/net_modem.c | 131 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 95247ad80..d35172ada 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -112,6 +112,7 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; + bool telnet_mode; uint32_t tcpIpConnCounter; int doresponse; @@ -683,7 +684,22 @@ modem_do_command(modem_t* modem) char chr = modem_fetch_character(&scanbuf); switch (chr) { case '+': - /* None supported yet. */ + if (is_next_token("NET", sizeof("NET"), scanbuf)) { + // only walk the pointer ahead if the command matches + scanbuf += 3; + const uint32_t requested_mode = modem_scan_number(&scanbuf); + + // If the mode isn't valid then stop parsing + if (requested_mode != 1 && requested_mode != 0) { + modem_send_res(modem, ResERROR); + return; + } + // Inform the user on changes + if (modem->telnet_mode != !!requested_mode) { + modem->telnet_mode = !!requested_mode; + } + break; + } modem_send_res(modem, ResERROR); return; case 'D': { // Dial. @@ -968,6 +984,106 @@ fifo8_resize_2x(Fifo8* fifo) free(temp_buf); } +#define TEL_CLIENT 0 +#define TEL_SERVER 1 +void modem_process_telnet(modem_t* modem, uint8_t *data, uint32_t size) +{ + uint32_t i = 0; + for (i = 0; i < size; i++) { + uint8_t c = data[i]; + if (modem->telClient.inIAC) { + if (modem->telClient.recCommand) { + if ((c != 0) && (c != 1) && (c != 3)) { + if (modem->telClient.command > 250) { + /* Reject anything we don't recognize */ + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, c); /* We won't do crap! */ + } + } + switch (modem->telClient.command) { + case 251: /* Will */ + if (c == 0) modem->telClient.binary[TEL_SERVER] = true; + if (c == 1) modem->telClient.echo[TEL_SERVER] = true; + if (c == 3) modem->telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if (c == 0) modem->telClient.binary[TEL_SERVER] = false; + if (c == 1) modem->telClient.echo[TEL_SERVER] = false; + if (c == 3) modem->telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ + } + break; + default: + break; + } + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + continue; + } else { + if (c == 249) { + /* Go Ahead received */ + modem->telClient.inIAC = false; + continue; + } + modem->telClient.command = c; + modem->telClient.recCommand = true; + + if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + fifo8_push(&modem->rx_data, 0xff); + continue; + } + } + } else { + if (c == 0xff) { + modem->telClient.inIAC = true; + continue; + } + fifo8_push(&modem->rx_data, c); + } + } +} static int modem_rx(void *priv, uint8_t *buf, int io_len) @@ -1147,7 +1263,10 @@ modem_cmdpause_timer_callback(void *priv) int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { - fifo8_push_all(&modem->rx_data, buffer, res); + if (modem->telnet_mode) + modem_process_telnet(modem, buffer, res); + else + fifo8_push_all(&modem->rx_data, buffer, res); } else if (res == 0) { modem->tx_count = 0; modem_enter_idle_state(modem); @@ -1185,6 +1304,7 @@ modem_init(const device_t *info) modem->port = device_get_config_int("port"); modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); + modem->telnet_mode = device_get_config_int("telnet_mode"); modem->clientsocket = modem->serversocket = modem->waitingclientsocket = -1; @@ -1279,6 +1399,13 @@ static const device_config_t modem_config[] = { .default_string = "", .file_filter = "Text files (*.txt)|*.txt" }, + { + .name = "telnet_mode", + .description = "Telnet emulation", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "", .description = "", .type = CONFIG_END } }; From 7d28e7727367677c6e5e8675afd80f98c089422d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:37:16 +0600 Subject: [PATCH 242/690] EOF handling --- src/network/net_modem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index d35172ada..bbcef00d1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -178,6 +178,9 @@ modem_read_phonebook_file(modem_t* modem, const char* path) continue; } + if (res == EOF) + break; + if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ continue; From dbd875285f39f27b3709088c71bf90d398112db4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:38:52 +0600 Subject: [PATCH 243/690] Fix SDL2 builds --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 48a5950b9..5a43dffdb 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ CMakeLists.txt.user # MacOS Finder stuff .DS_Store + +# clangd +.cache From 097c9b4169427e3c24fae928ccf791fda1a24f8d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:41:12 +0600 Subject: [PATCH 244/690] Fix SDL2 builds --- src/unix/CMakeLists.txt | 2 +- src/unix/unix_netsocket.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 43c730315..aa4cc84e2 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -17,7 +17,7 @@ # Copyright 2021-2022 Jasmine Iwanek. # -add_library(plat OBJECT unix.c unix_serial_passthrough.c) +add_library(plat OBJECT unix.c unix_serial_passthrough.c unix_netsocket.c) if (NOT CPPTHREADS) target_sources(plat PRIVATE unix_thread.c) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e0353a463..76ae0831b 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -22,14 +22,16 @@ #include #include #include +#include #include #include +#include #include SOCKET plat_netsocket_create(int type) { SOCKET fd = -1; - u_long yes = 1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; @@ -47,7 +49,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; SOCKET fd = -1; - u_long yes = 1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; From 3e623c88f49f6b173e0a6486dcd409fae9b581bf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:43:11 +0600 Subject: [PATCH 245/690] More type fixes --- src/unix/unix_netsocket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 76ae0831b..1e3282555 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -1,3 +1,4 @@ +#include #define _XOPEN_SOURCE 500 #include #include @@ -102,7 +103,7 @@ int plat_netsocket_connected(SOCKET socket) struct timeval tv; int res = -1; int status = 0; - int optlen = 4; + socklen_t optlen = 4; FD_ZERO(&wrfds); FD_SET(socket, &wrfds); From 515a69b318f524f15b6a64089298f56e75ea7f69 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:49:17 +0600 Subject: [PATCH 246/690] Deal with accidental includes --- src/unix/unix_netsocket.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 1e3282555..7e7163801 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -1,4 +1,3 @@ -#include #define _XOPEN_SOURCE 500 #include #include From 324299a6f3a9f52e7b6112376ba81da8e369eed2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 21:01:46 +0600 Subject: [PATCH 247/690] unix_netsocket.c: Unused variables cleanup --- src/unix/unix_netsocket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 7e7163801..e65b53bee 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ SOCKET plat_netsocket_create(int type) return -1; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); return fd; } @@ -75,6 +77,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) } fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); return fd; } @@ -141,7 +144,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); From 42e062143b3d441c6fbeb5d9a88e53e0a6fea567 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 01:29:21 +0600 Subject: [PATCH 248/690] Fix brace warning --- src/device/novell_cardkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 9f489cad7..4730b6bb4 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -102,7 +102,7 @@ static const device_config_t keycard_config[] = { .default_int = 0, .file_filter = "", .spinner = { 0 }, - .selection = { 0 } + .selection = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -120,4 +120,4 @@ const device_t novell_keycard_device = { .speed_changed = NULL, .force_redraw = NULL, .config = keycard_config -}; \ No newline at end of file +}; From b2a4d7457e6152243524a56e965d3629379663d6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 16:38:32 +0600 Subject: [PATCH 249/690] netsockets: Swap port number --- src/network/net_modem.c | 4 +++- src/unix/unix_netsocket.c | 2 +- src/win/win_netsocket.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index bbcef00d1..fe8ebfc57 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -113,6 +113,7 @@ typedef struct modem_t bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; bool telnet_mode; + bool dtrstate; uint32_t tcpIpConnCounter; int doresponse; @@ -957,6 +958,7 @@ void modem_dtr_callback(serial_t* serial, int status, void *priv) { modem_t *dev = (modem_t *) priv; + dev->dtrstate = !!status; if (status == 1) timer_disable(&dev->dtr_timer); else if (!timer_is_enabled(&dev->dtr_timer)) @@ -1207,7 +1209,7 @@ modem_cmdpause_timer_callback(void *priv) if (!modem->connected && modem->waitingclientsocket == -1 && modem->serversocket != -1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); if (modem->waitingclientsocket != -1) { - if (!(modem->serial->mctrl & 1) && modem->dtrmode != 0) { + if (modem->dtrstate == 0 && modem->dtrmode != 0) { modem_enter_idle_state(modem); } else { modem->ringing = true; diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e65b53bee..9e9ac2f49 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -64,7 +64,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = port; + sock_addr.sin_port = htons(port); if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { plat_netsocket_close(fd); diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 0f8c5f87a..902d5e6ff 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -53,7 +53,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = port; + sock_addr.sin_port = htons(port); if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { plat_netsocket_close(socket); From 7f68245eae59fdd26ddd94d26287354a88ac8511 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 17:46:36 +0600 Subject: [PATCH 250/690] unix_netsocket.c: Fix comparison value --- src/unix/unix_netsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 9e9ac2f49..e6ec6285f 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -144,7 +144,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == ((in_addr_t)-1) || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); From 607f66a1f83925c0f7824022392482f8a3ac9a7f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 19:14:00 +0600 Subject: [PATCH 251/690] net_modem: Implement answer command --- src/network/net_modem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index fe8ebfc57..372b39123 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -153,6 +153,7 @@ static modem_t *instance; #define MREG_DTR_DELAY 25 static void modem_do_command(modem_t* modem); +static void modem_answer_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -822,8 +823,12 @@ modem_do_command(modem_t* modem) break; case 'A': // Answer call { - modem_send_res(modem, ResERROR); - return; + if (modem->waitingclientsocket == -1) { + modem_send_res(modem, ResERROR); + return; + } + modem_answer_incoming_call(modem); + break; } return; case 'Z': { // Reset and load profiles From 53baaeece7679572df8cfa99f7d240f74e7433c3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 19:21:16 +0600 Subject: [PATCH 252/690] Comments cleanup and function name fixes --- src/network/net_modem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 372b39123..c7d0aea2c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -153,7 +153,7 @@ static modem_t *instance; #define MREG_DTR_DELAY 25 static void modem_do_command(modem_t* modem); -static void modem_answer_incoming_call(modem_t* modem); +static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -559,7 +559,6 @@ modem_reset(modem_t* modem) void modem_dial(modem_t* modem, const char* str) { - /* TODO: Port TCP/IP support from DOSBox. */ modem->tcpIpConnCounter = 0; modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) @@ -827,7 +826,7 @@ modem_do_command(modem_t* modem) modem_send_res(modem, ResERROR); return; } - modem_answer_incoming_call(modem); + modem_accept_incoming_call(modem); break; } return; From 7c9e94fb9bd09c1047680a52a9b5d2884a0262a5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 14 Mar 2024 01:10:29 +0600 Subject: [PATCH 253/690] net_modem.c: Make sure the CONNECT response gets through --- src/network/net_modem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index c7d0aea2c..4c2985bda 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -112,6 +112,7 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; + bool cooldown; bool telnet_mode; bool dtrstate; uint32_t tcpIpConnCounter; @@ -369,13 +370,17 @@ host_to_modem_cb(void *priv) if (!((modem->serial->mctrl & 2) || modem->flowcontrol != 3)) goto no_write_to_machine; - if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data) && !modem->cooldown) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); serial_write_fifo(modem->serial, val); } + if (fifo8_num_used(&modem->data_pending) == 0) { + modem->cooldown = false; + } + no_write_to_machine: timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); } @@ -524,6 +529,7 @@ modem_enter_connected_state(modem_t* modem) modem->ringing = false; modem->connected = true; modem->tcpIpMode = true; + modem->cooldown = true; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); From e1180a77df2c605b93b3f1325bba86a54850adf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Mar 2024 01:06:12 +0100 Subject: [PATCH 254/690] NCR 53c8xx: Implement the readout of SODL via SBDL when STEST2 bit 7 is set, v3.04 BIOS'es now work. --- src/scsi/scsi_ncr53c8xx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 42925338d..ad1b31fe8 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -280,6 +280,7 @@ typedef struct ncr53c8xx_t { uint8_t swide; uint8_t gpcntl; uint8_t last_command; + uint8_t sodl; int command_complete; ncr53c8xx_request *current; @@ -1704,6 +1705,8 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) dev->stest3 = val; break; case 0x54: + dev->sodl = val; + break; case 0x55: break; CASE_SET_REG32(scratchb, 0x5c) @@ -1989,6 +1992,9 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) if ((dev->sstat1 & PHASE_MASK) == PHASE_MI) { ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->msg[0]); return dev->msg[0]; + } else if (dev->stest2 & 0x80) { + ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->sodl); + return dev->sodl; } ncr53c8xx_log("NCR 810: Read SBDL 00\n"); return 0; From 6e87964b28c2dbd61f8942315bc607b9fb4fbfea Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 14 Mar 2024 16:14:06 +0600 Subject: [PATCH 255/690] net_modem: process '&' escaped commands properly --- src/network/net_modem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4c2985bda..bbbe2e37a 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -919,6 +919,7 @@ modem_do_command(modem_t* modem) } break; } + break; case '\\': { // \ escaped commands char cmdchar = modem_fetch_character(&scanbuf); switch (cmdchar) { From 0ce889e9ad0e8b54f8d88ebc58f79c50023cdc2b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 15 Mar 2024 02:46:00 +0600 Subject: [PATCH 256/690] net_modem.c: Fix memory leak --- src/network/net_modem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index bbbe2e37a..b1b6a2eca 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,4 +1,3 @@ - /* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM @@ -323,9 +322,9 @@ send_tx_packet: buf[13] = 0x00; memcpy(buf + 14, processed_tx_packet, received); network_tx(modem->card, buf, received + 14); - free(processed_tx_packet); free(buf); } + free(processed_tx_packet); return; } @@ -530,6 +529,7 @@ modem_enter_connected_state(modem_t* modem) modem->connected = true; modem->tcpIpMode = true; modem->cooldown = true; + modem->tx_count = 0; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); From 64f343049fc5c1ba10b8ba58b084f48e756c9bde Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 15 Mar 2024 14:01:12 +0500 Subject: [PATCH 257/690] Fix Novell NE2000's default IRQ being out of range --- src/network/net_ne2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 03327ac0c..ee32119ba 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -1329,7 +1329,7 @@ static const device_config_t ne2000_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 10, + .default_int = 3, .file_filter = "", .spinner = { 0 }, .selection = { From 474df94008b1de603c6d8eabdaaa5dc0e8027e79 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 15 Mar 2024 14:01:46 +0500 Subject: [PATCH 258/690] Correct a typo in the comment --- src/include/86box/net_ne2000.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index fe1a71934..75185cf90 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -39,7 +39,7 @@ enum { NE2K_NONE = 0, NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ - NE2K_NE1000_COMPAT = 2, /* 16-bit ISA NE2000-Compatible */ + NE2K_NE1000_COMPAT = 2, /* 8-bit ISA NE1000-Compatible */ NE2K_NE2000 = 3, /* 16-bit ISA NE2000 */ NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ NE2K_ETHERNEXT_MC = 5, /* 16-bit MCA EtherNext/MC */ From e34a66a4f6f60398f22451f973d2530f80ac3493 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:06:54 -0400 Subject: [PATCH 259/690] GHA: Disable win32 in CodeQL --- .github/workflows/codeql_windows_msys2.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index dc18544c7..dda14a182 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -61,9 +61,6 @@ jobs: new: on slug: -NDR ui: - - name: Win32 GUI - qt: off - static: on - name: Qt GUI qt: on static: off From 2c5a460d2315c1c72e247db9013b9e0ed10d781c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 15 Mar 2024 18:16:21 +0100 Subject: [PATCH 260/690] Removed the Win32 UI and the legacy makefiles. --- src/Makefile.local | 200 - src/{win => qt}/86Box-qt.rc | 0 src/{win => qt}/86Box.manifest | 0 src/qt/CMakeLists.txt | 10 +- src/{win => qt}/assets/86Box-green.png | Bin src/{win => qt}/assets/86box-rb.png | Bin src/{win => qt}/assets/86box-red.png | Bin src/{win => qt}/assets/86box-yellow.png | Bin src/{win => qt}/assets/86box.png | Bin src/{win => qt}/assets/status-paused.png | Bin src/{win => qt}/assets/status-running.png | Bin src/{win => qt}/icons/86Box-gray.ico | Bin src/{win => qt}/icons/86Box-green.ico | Bin src/{win => qt}/icons/86Box-red.ico | Bin src/{win => qt}/icons/86Box-yellow.ico | Bin src/{win => qt}/icons/acpi_shutdown.ico | Bin src/{win => qt}/icons/cartridge.ico | Bin src/{win => qt}/icons/cartridge_empty.ico | Bin src/{win => qt}/icons/cassette.ico | Bin src/{win => qt}/icons/cassette_active.ico | Bin src/{win => qt}/icons/cassette_empty.ico | Bin .../icons/cassette_empty_active.ico | Bin src/{win => qt}/icons/cdrom.ico | Bin src/{win => qt}/icons/cdrom_active.ico | Bin src/{win => qt}/icons/cdrom_disabled.ico | Bin src/{win => qt}/icons/cdrom_empty.ico | Bin src/{win => qt}/icons/cdrom_empty_active.ico | Bin src/{win => qt}/icons/display.ico | Bin src/{win => qt}/icons/floppy_35.ico | Bin src/{win => qt}/icons/floppy_35_active.ico | Bin src/{win => qt}/icons/floppy_35_empty.ico | Bin .../icons/floppy_35_empty_active.ico | Bin src/{win => qt}/icons/floppy_525.ico | Bin src/{win => qt}/icons/floppy_525_active.ico | Bin src/{win => qt}/icons/floppy_525_empty.ico | Bin .../icons/floppy_525_empty_active.ico | Bin .../icons/floppy_and_cdrom_drives.ico | Bin src/{win => qt}/icons/floppy_disabled.ico | Bin src/{win => qt}/icons/hard_disk.ico | Bin src/{win => qt}/icons/hard_disk_active.ico | Bin src/{win => qt}/icons/hard_reset.ico | Bin src/{win => qt}/icons/input_devices.ico | Bin src/{win => qt}/icons/machine.ico | Bin src/{win => qt}/icons/mo.ico | Bin src/{win => qt}/icons/mo_active.ico | Bin src/{win => qt}/icons/mo_disabled.ico | Bin src/{win => qt}/icons/mo_empty.ico | Bin src/{win => qt}/icons/mo_empty_active.ico | Bin src/{win => qt}/icons/network.ico | Bin src/{win => qt}/icons/network_active.ico | Bin src/{win => qt}/icons/network_empty.ico | Bin src/{win => qt}/icons/other_peripherals.ico | Bin .../icons/other_removable_devices.ico | Bin src/{win => qt}/icons/pause.ico | Bin src/{win => qt}/icons/ports.ico | Bin src/{win => qt}/icons/run.ico | Bin src/{win => qt}/icons/send_cad.ico | Bin src/{win => qt}/icons/send_cae.ico | Bin src/{win => qt}/icons/settings.ico | Bin src/{win => qt}/icons/sound.ico | Bin src/{win => qt}/icons/storage_controllers.ico | Bin src/{win => qt}/icons/zip.ico | Bin src/{win => qt}/icons/zip_active.ico | Bin src/{win => qt}/icons/zip_disabled.ico | Bin src/{win => qt}/icons/zip_empty.ico | Bin src/{win => qt}/icons/zip_empty_active.ico | Bin src/qt/qt_main.cpp | 8 +- src/qt/qt_mainwindow.cpp | 10 +- src/qt/qt_mainwindow.ui | 12 +- src/qt/qt_progsettings.cpp | 2 +- src/qt/qt_settingsstoragecontrollers.cpp | 1 - src/{win => qt}/win_netsocket.c | 0 src/{win => qt}/win_opendir.c | 0 src/{win => qt}/win_serial_passthrough.c | 0 src/qt_resources.qrc | 110 +- src/win/86Box.rc | 365 -- src/win/CMakeLists.txt | 63 - src/win/Makefile.mingw | 988 --- src/win/glad.c | 1047 --- src/win/languages/cs-CZ.rc | 636 -- src/win/languages/de-DE.rc | 636 -- src/win/languages/dialogs.rc | 1143 ---- src/win/languages/en-GB.rc | 636 -- src/win/languages/en-US.rc | 636 -- src/win/languages/es-ES.rc | 636 -- src/win/languages/fi-FI.rc | 636 -- src/win/languages/fr-FR.rc | 636 -- src/win/languages/hr-HR.rc | 636 -- src/win/languages/hu-HU.rc | 640 -- src/win/languages/it-IT.rc | 637 -- src/win/languages/ja-JP.rc | 636 -- src/win/languages/ko-KR.rc | 636 -- src/win/languages/pl-PL.rc | 636 -- src/win/languages/pt-BR.rc | 639 -- src/win/languages/pt-PT.rc | 636 -- src/win/languages/ru-RU.rc | 636 -- src/win/languages/sl-SI.rc | 636 -- src/win/languages/tr-TR.rc | 636 -- src/win/languages/uk-UA.rc | 636 -- src/win/languages/zh-CN.rc | 636 -- src/win/languages/zh-TW.rc | 636 -- src/win/pcap_if.rc | 54 - src/win/win.c | 1346 ---- src/win/win_about.c | 80 - src/win/win_cdrom.c | 258 - src/win/win_devconf.c | 832 --- src/win/win_dialog.c | 256 - src/win/win_dynld.c | 83 - src/win/win_icon.c | 168 - src/win/win_joystick.cpp | 321 - src/win/win_joystick_rawinput.c | 551 -- src/win/win_joystick_xinput.c | 268 - src/win/win_jsconf.c | 527 -- src/win/win_keyboard.c | 198 - src/win/win_media_menu.c | 766 --- src/win/win_mouse.c | 125 - src/win/win_new_floppy.c | 842 --- src/win/win_opengl.c | 1002 --- src/win/win_opengl_glslp.c | 270 - src/win/win_preferences.c | 290 - src/win/win_sdl.c | 626 -- src/win/win_settings.c | 5708 ----------------- src/win/win_snd_gain.c | 90 - src/win/win_specify_dim.c | 188 - src/win/win_stbar.c | 1058 --- src/win/win_thread.c | 180 - src/win/win_toolbar.c | 208 - src/win/win_ui.c | 1662 ----- 128 files changed, 76 insertions(+), 35204 deletions(-) delete mode 100644 src/Makefile.local rename src/{win => qt}/86Box-qt.rc (100%) rename src/{win => qt}/86Box.manifest (100%) rename src/{win => qt}/assets/86Box-green.png (100%) rename src/{win => qt}/assets/86box-rb.png (100%) rename src/{win => qt}/assets/86box-red.png (100%) rename src/{win => qt}/assets/86box-yellow.png (100%) rename src/{win => qt}/assets/86box.png (100%) rename src/{win => qt}/assets/status-paused.png (100%) rename src/{win => qt}/assets/status-running.png (100%) rename src/{win => qt}/icons/86Box-gray.ico (100%) rename src/{win => qt}/icons/86Box-green.ico (100%) rename src/{win => qt}/icons/86Box-red.ico (100%) rename src/{win => qt}/icons/86Box-yellow.ico (100%) rename src/{win => qt}/icons/acpi_shutdown.ico (100%) rename src/{win => qt}/icons/cartridge.ico (100%) rename src/{win => qt}/icons/cartridge_empty.ico (100%) rename src/{win => qt}/icons/cassette.ico (100%) rename src/{win => qt}/icons/cassette_active.ico (100%) rename src/{win => qt}/icons/cassette_empty.ico (100%) rename src/{win => qt}/icons/cassette_empty_active.ico (100%) rename src/{win => qt}/icons/cdrom.ico (100%) rename src/{win => qt}/icons/cdrom_active.ico (100%) rename src/{win => qt}/icons/cdrom_disabled.ico (100%) rename src/{win => qt}/icons/cdrom_empty.ico (100%) rename src/{win => qt}/icons/cdrom_empty_active.ico (100%) rename src/{win => qt}/icons/display.ico (100%) rename src/{win => qt}/icons/floppy_35.ico (100%) rename src/{win => qt}/icons/floppy_35_active.ico (100%) rename src/{win => qt}/icons/floppy_35_empty.ico (100%) rename src/{win => qt}/icons/floppy_35_empty_active.ico (100%) rename src/{win => qt}/icons/floppy_525.ico (100%) rename src/{win => qt}/icons/floppy_525_active.ico (100%) rename src/{win => qt}/icons/floppy_525_empty.ico (100%) rename src/{win => qt}/icons/floppy_525_empty_active.ico (100%) rename src/{win => qt}/icons/floppy_and_cdrom_drives.ico (100%) rename src/{win => qt}/icons/floppy_disabled.ico (100%) rename src/{win => qt}/icons/hard_disk.ico (100%) rename src/{win => qt}/icons/hard_disk_active.ico (100%) rename src/{win => qt}/icons/hard_reset.ico (100%) rename src/{win => qt}/icons/input_devices.ico (100%) rename src/{win => qt}/icons/machine.ico (100%) rename src/{win => qt}/icons/mo.ico (100%) rename src/{win => qt}/icons/mo_active.ico (100%) rename src/{win => qt}/icons/mo_disabled.ico (100%) rename src/{win => qt}/icons/mo_empty.ico (100%) rename src/{win => qt}/icons/mo_empty_active.ico (100%) rename src/{win => qt}/icons/network.ico (100%) rename src/{win => qt}/icons/network_active.ico (100%) rename src/{win => qt}/icons/network_empty.ico (100%) rename src/{win => qt}/icons/other_peripherals.ico (100%) rename src/{win => qt}/icons/other_removable_devices.ico (100%) rename src/{win => qt}/icons/pause.ico (100%) rename src/{win => qt}/icons/ports.ico (100%) rename src/{win => qt}/icons/run.ico (100%) rename src/{win => qt}/icons/send_cad.ico (100%) rename src/{win => qt}/icons/send_cae.ico (100%) rename src/{win => qt}/icons/settings.ico (100%) rename src/{win => qt}/icons/sound.ico (100%) rename src/{win => qt}/icons/storage_controllers.ico (100%) rename src/{win => qt}/icons/zip.ico (100%) rename src/{win => qt}/icons/zip_active.ico (100%) rename src/{win => qt}/icons/zip_disabled.ico (100%) rename src/{win => qt}/icons/zip_empty.ico (100%) rename src/{win => qt}/icons/zip_empty_active.ico (100%) rename src/{win => qt}/win_netsocket.c (100%) rename src/{win => qt}/win_opendir.c (100%) rename src/{win => qt}/win_serial_passthrough.c (100%) delete mode 100644 src/win/86Box.rc delete mode 100644 src/win/CMakeLists.txt delete mode 100644 src/win/Makefile.mingw delete mode 100644 src/win/glad.c delete mode 100644 src/win/languages/cs-CZ.rc delete mode 100644 src/win/languages/de-DE.rc delete mode 100644 src/win/languages/dialogs.rc delete mode 100644 src/win/languages/en-GB.rc delete mode 100644 src/win/languages/en-US.rc delete mode 100644 src/win/languages/es-ES.rc delete mode 100644 src/win/languages/fi-FI.rc delete mode 100644 src/win/languages/fr-FR.rc delete mode 100644 src/win/languages/hr-HR.rc delete mode 100644 src/win/languages/hu-HU.rc delete mode 100644 src/win/languages/it-IT.rc delete mode 100644 src/win/languages/ja-JP.rc delete mode 100644 src/win/languages/ko-KR.rc delete mode 100644 src/win/languages/pl-PL.rc delete mode 100644 src/win/languages/pt-BR.rc delete mode 100644 src/win/languages/pt-PT.rc delete mode 100644 src/win/languages/ru-RU.rc delete mode 100644 src/win/languages/sl-SI.rc delete mode 100644 src/win/languages/tr-TR.rc delete mode 100644 src/win/languages/uk-UA.rc delete mode 100644 src/win/languages/zh-CN.rc delete mode 100644 src/win/languages/zh-TW.rc delete mode 100644 src/win/pcap_if.rc delete mode 100644 src/win/win.c delete mode 100644 src/win/win_about.c delete mode 100644 src/win/win_cdrom.c delete mode 100644 src/win/win_devconf.c delete mode 100644 src/win/win_dialog.c delete mode 100644 src/win/win_dynld.c delete mode 100644 src/win/win_icon.c delete mode 100644 src/win/win_joystick.cpp delete mode 100644 src/win/win_joystick_rawinput.c delete mode 100644 src/win/win_joystick_xinput.c delete mode 100644 src/win/win_jsconf.c delete mode 100644 src/win/win_keyboard.c delete mode 100644 src/win/win_media_menu.c delete mode 100644 src/win/win_mouse.c delete mode 100644 src/win/win_new_floppy.c delete mode 100644 src/win/win_opengl.c delete mode 100644 src/win/win_opengl_glslp.c delete mode 100644 src/win/win_preferences.c delete mode 100644 src/win/win_sdl.c delete mode 100644 src/win/win_settings.c delete mode 100644 src/win/win_snd_gain.c delete mode 100644 src/win/win_specify_dim.c delete mode 100644 src/win/win_stbar.c delete mode 100644 src/win/win_thread.c delete mode 100644 src/win/win_toolbar.c delete mode 100644 src/win/win_ui.c diff --git a/src/Makefile.local b/src/Makefile.local deleted file mode 100644 index fdb2dcab3..000000000 --- a/src/Makefile.local +++ /dev/null @@ -1,200 +0,0 @@ -# -# 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. -# -# Prefix for localizing the general Makefile.mingw for local -# settings, so we can avoid changing the main one for all of -# our local setups. -# -# Authors: Fred N. van Kempen, -# - -######################################################################### -# Anything here will override defaults in Makefile.MinGW. # -######################################################################### - - -# Name of the executable. -#PROG := 86box.exe - - -# Various compile-time options. -# -DROM_TRACE=0xc800 traces ROM access from segment C800 -# -DIO_TRACE=0x66 traces I/O on port 0x66 -# -DIO_CATCH enables I/O range catch logs -STUFF := - -# Add feature selections here. -# -DANSI_CFG forces the config file to ANSI encoding. -# Root logging: -# -DENABLE_ACPI_LOG=N sets logging level at N. -# -DENABLE_APM_LOG=N sets logging level at N. -# -DENABLE_BUGGER_LOG=N sets logging level at N. -# -DENABLE_CONFIG_LOG=N sets logging level at N. -# -DENABLE_DDMA_LOG=N sets logging level at N. -# -DENABLE_DEVICE_LOG=N sets logging level at N. -# -DENABLE_DMA_LOG=N sets logging level at N. -# -DENABLE_IO_LOG=N sets logging level at N. -# -DENABLE_IOAPIC_LOG=N sets logging level at N. -# -DENABLE_ISAMEM_LOG=N sets logging level at N. -# -DENABLE_ISARTC_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N. -# -DENABLE_LM75_LOG=N sets logging level at N. -# -DENABLE_LM78_LOG=N sets logging level at N. -# -DENABLE_MEM_LOG=N sets logging level at N. -# -DENABLE_MOUSE_LOG=N sets logging level at N. -# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N. -# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N. -# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_NVR_LOG=N sets logging level at N. -# -DENABLE_PC_LOG=N sets logging level at N. -# -DENABLE_PCI_LOG=N sets logging level at N. -# -DENABLE_PIC_LOG=N sets logging level at N. -# -DENABLE_PIT_LOG=N sets logging level at N. -# -DENABLE_POSTCARD_LOG=N sets logging level at N. -# -DENABLE_ROM_LOG=N sets logging level at N. -# -DENABLE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_SMBUS_LOG=N sets logging level at N. -# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N. -# -DENABLE_SPD_LOG=N sets logging level at N. -# -DENABLE_USB_LOG=N sets logging level at N. -# -DENABLE_VNC_LOG=N sets logging level at N. -# -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N. -# cdrom/ logging: -# -DENABLE_CDROM_LOG=N sets logging level at N. -# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N. -# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N. -# chipset/ logging: -# -DENABLE_I420EX_LOG=N sets logging level at N. -# -DENABLE_NEAT_LOG=N sets logging level at N. -# -DENABLE_OPTI495_LOG=N sets logging level at N. -# -DENABLE_OPTI895_LOG=N sets logging level at N. -# -DENABLE_PIIX_LOG=N sets logging level at N. -# -DENABLE_SIO_LOG=N sets logging level at N. -# -DENABLE_SIS_85C496_LOG=N sets logging level at N. -# codegen/, codegen_new/, cpu/ logging: -# -DENABLE_X86SEG_LOG=N sets logging level at N. -# cpu/ logging: -# -DENABLE_386_LOG=N sets logging level at N. -# -DENABLE_386_COMMON_LOG=N sets logging level at N. -# -DENABLE_386_DYNAREC_LOG=N sets logging level at N. -# -DENABLE_808X_LOG=N sets logging level at N. -# -DENABLE_CPU_LOG=N sets logging level at N. -# -DENABLE_FPU_LOG=N sets logging level at N. -# disk/ logging: -# -DENABLE_ESDI_AT_LOG=N sets logging level at N. -# -DENABLE_ESDI_MCA_LOG=N sets logging level at N. -# -DENABLE_HDC_LOG=N sets logging level at N. -# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N. -# -DENABLE_IDE_LOG=N sets logging level at N. -# -DENABLE_MO_LOG=N sets logging level at N. -# -DENABLE_SFF_LOG=N sets logging level at N. -# -DENABLE_ST506_AT_LOG=N sets logging level at N. -# -DENABLE_ST506_XT_LOG=N sets logging level at N. -# -DENABLE_XTA_LOG=N sets logging level at N. -# -DENABLE_ZIP_LOG=N sets logging level at N. -# floppy/ logging: -# -DENABLE_D86F_LOG=N sets logging level at N. -# -DENABLE_FDC_LOG=N sets logging level at N. -# -DENABLE_FDD_LOG=N sets logging level at N. -# -DENABLE_FDI_LOG=N sets logging level at N. -# -DENABLE_FDI2RAW_LOG=N sets logging level at N. -# -DENABLE_IMD_LOG=N sets logging level at N. -# -DENABLE_IMG_LOG=N sets logging level at N. -# -DENABLE_JSON_LOG=N sets logging level at N. -# -DENABLE_MFM_LOG=N sets logging level at N. -# -DENABLE_TD0_LOG=N sets logging level at N. -# machine/ logging: -# -DENABLE_AMSTRAD_LOG=N sets logging level at N. -# -DENABLE_EUROPC_LOG=N sets logging level at N. -# -DENABLE_M24VID_LOG=N sets logging level at N. -# -DENABLE_MACHINE_LOG=N sets logging level at N. -# -DENABLE_PS1_HDC_LOG=N sets logging level at N. -# -DENABLE_PS2_MCA_LOG=N sets logging level at N. -# -DENABLE_TANDY_LOG=N sets logging level at N. -# -DENABLE_T1000_LOG=N sets logging level at N. -# -DENABLE_T3100E_LOG=N sets logging level at N. -# network/ logging: -# -DENABLE_3COM503_LOG=N sets logging level at N. -# -DENABLE_DP8390_LOG=N sets logging level at N. -# -DENABLE_NETWORK_LOG=N sets logging level at N. -# -DENABLE_NE2K_LOG=N sets logging level at N. -# -DENABLE_PCAP_LOG=N sets logging level at N. -# -DENABLE_PCNET_LOG=N sets logging level at N. -# -DENABLE_SLIRP_LOG=N sets logging level at N. -# -DENABLE_WD_LOG=N sets logging level at N. -# printer/ logging: -# -DENABLE_ESCP_LOG=N sets logging level at N. -# scsi/ logging: -# -DENABLE_AHA154X_LOG=N sets logging level at N. -# -DENABLE_BUSLOGIC_LOG=N sets logging level at N. -# -DENABLE_NCR5380_LOG=N sets logging level at N. -# -DENABLE_NCR53C8XX_LOG=N sets logging level at N. -# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N. -# -DENABLE_SCSI_DISK_LOG=N sets logging level at N. -# -DENABLE_SPOCK_LOG=N sets logging level at N. -# -DENABLE_X54X_LOG=N sets logging level at N. -# sound/ logging: -# -DENABLE_ADLIB_LOG=N sets logging level at N. -# -DENABLE_AUDIOPCI_LOG=N sets logging level at N. -# -DENABLE_EMU8K_LOG=N sets logging level at N. -# -DENABLE_MPU401_LOG=N sets logging level at N. -# -DENABLE_PAS16_LOG=N sets logging level at N. -# -DENABLE_SB_LOG=N sets logging level at N. -# -DENABLE_SB_DSP_LOG=N sets logging level at N. -# -DENABLE_SOUND_LOG=N sets logging level at N. -# video/ logging: -# -DENABLE_ATI28800_LOG=N sets logging level at N. -# -DENABLE_MACH64_LOG=N sets logging level at N. -# -DENABLE_COMPAQ_CGA_LOG=N sets logging level at N. -# -DENABLE_ET4000W32_LOG=N sets logging level at N. -# -DENABLE_HT216_LOG=N sets logging level at N. -# -DENABLE_ICD2061_LOG=N sets logging level at N. -# -DENABLE_IM1024_LOG=N sets logging level at N. -# -DENABLE_PGC_LOG=N sets logging level at N. -# -DENABLE_S3_VIRGE_LOG=N sets logging level at N. -# -DENABLE_VID_TABLE_LOG=N sets logging level at N. -# -DENABLE_VIDEO_LOG=N sets logging level at N. -# -DENABLE_VOODOO_LOG=N sets logging level at N. -# win/ logging: -# -DENABLE_WIN_LOG=N sets logging level at N. -# -DENABLE_DISCORD_LOG=N sets logging level at N. -# -DENABLE_DYNLD_LOG=N sets logging level at N. -# -DENABLE_JOYSTICK_LOG=N sets logging level at N. -# -DENABLE_SDL_LOG=N sets logging level at N. -# -DENABLE_SETTINGS_LOG=N sets logging level at N. -EXTRAS := - - -AUTODEP := n -DEBUG := n -OPTIM := n -X64 := n -RELEASE := n -USB := n -VNC := n -RDP := n -DEV_BUILD := n -DEV_BRANCH := n -CIRRUS := n -NE1000 := n -NV_RIVA := n -OPENAL := y -FLUIDSYNTH := y -MUNT := y -PAS16 := n -DYNAREC := y - - -######################################################################### -# Include the master Makefile.MinGW for the rest. # -######################################################################### -include win/Makefile.mingw - - -# End of Makefile.local. diff --git a/src/win/86Box-qt.rc b/src/qt/86Box-qt.rc similarity index 100% rename from src/win/86Box-qt.rc rename to src/qt/86Box-qt.rc diff --git a/src/win/86Box.manifest b/src/qt/86Box.manifest similarity index 100% rename from src/win/86Box.manifest rename to src/qt/86Box.manifest diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 23cf865a0..e189ec569 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -189,7 +189,7 @@ endif() if(WIN32) enable_language(RC) - target_sources(86Box PUBLIC ../win/86Box-qt.rc) + target_sources(86Box PUBLIC 86Box-qt.rc) target_sources(plat PRIVATE win_dynld.c) # CMake 3.22 messed this up for clang/clang++ @@ -198,8 +198,8 @@ if(WIN32) # MSVC linker adds its own manifest to the executable, which fails if # we include ours in 86Box.rc. We therefore need to pass the manifest # directly as as a source file, so the linker can use that instead. - set_property(SOURCE ../win/86Box-qt.rc DIRECTORY .. PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) - target_sources(86Box PRIVATE ../win/86Box.manifest) + set_property(SOURCE 86Box-qt.rc DIRECTORY .. PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) + target_sources(86Box PRIVATE 86Box.manifest) endif() if (MINGW) @@ -217,11 +217,11 @@ else() endif() if(WIN32 AND NOT MINGW) - target_sources(plat PRIVATE ../win/win_opendir.c) + target_sources(plat PRIVATE win_opendir.c) endif() if(WIN32) - target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) + target_sources(plat PRIVATE win_serial_passthrough.c win_netsocket.c) else() target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) endif() diff --git a/src/win/assets/86Box-green.png b/src/qt/assets/86Box-green.png similarity index 100% rename from src/win/assets/86Box-green.png rename to src/qt/assets/86Box-green.png diff --git a/src/win/assets/86box-rb.png b/src/qt/assets/86box-rb.png similarity index 100% rename from src/win/assets/86box-rb.png rename to src/qt/assets/86box-rb.png diff --git a/src/win/assets/86box-red.png b/src/qt/assets/86box-red.png similarity index 100% rename from src/win/assets/86box-red.png rename to src/qt/assets/86box-red.png diff --git a/src/win/assets/86box-yellow.png b/src/qt/assets/86box-yellow.png similarity index 100% rename from src/win/assets/86box-yellow.png rename to src/qt/assets/86box-yellow.png diff --git a/src/win/assets/86box.png b/src/qt/assets/86box.png similarity index 100% rename from src/win/assets/86box.png rename to src/qt/assets/86box.png diff --git a/src/win/assets/status-paused.png b/src/qt/assets/status-paused.png similarity index 100% rename from src/win/assets/status-paused.png rename to src/qt/assets/status-paused.png diff --git a/src/win/assets/status-running.png b/src/qt/assets/status-running.png similarity index 100% rename from src/win/assets/status-running.png rename to src/qt/assets/status-running.png diff --git a/src/win/icons/86Box-gray.ico b/src/qt/icons/86Box-gray.ico similarity index 100% rename from src/win/icons/86Box-gray.ico rename to src/qt/icons/86Box-gray.ico diff --git a/src/win/icons/86Box-green.ico b/src/qt/icons/86Box-green.ico similarity index 100% rename from src/win/icons/86Box-green.ico rename to src/qt/icons/86Box-green.ico diff --git a/src/win/icons/86Box-red.ico b/src/qt/icons/86Box-red.ico similarity index 100% rename from src/win/icons/86Box-red.ico rename to src/qt/icons/86Box-red.ico diff --git a/src/win/icons/86Box-yellow.ico b/src/qt/icons/86Box-yellow.ico similarity index 100% rename from src/win/icons/86Box-yellow.ico rename to src/qt/icons/86Box-yellow.ico diff --git a/src/win/icons/acpi_shutdown.ico b/src/qt/icons/acpi_shutdown.ico similarity index 100% rename from src/win/icons/acpi_shutdown.ico rename to src/qt/icons/acpi_shutdown.ico diff --git a/src/win/icons/cartridge.ico b/src/qt/icons/cartridge.ico similarity index 100% rename from src/win/icons/cartridge.ico rename to src/qt/icons/cartridge.ico diff --git a/src/win/icons/cartridge_empty.ico b/src/qt/icons/cartridge_empty.ico similarity index 100% rename from src/win/icons/cartridge_empty.ico rename to src/qt/icons/cartridge_empty.ico diff --git a/src/win/icons/cassette.ico b/src/qt/icons/cassette.ico similarity index 100% rename from src/win/icons/cassette.ico rename to src/qt/icons/cassette.ico diff --git a/src/win/icons/cassette_active.ico b/src/qt/icons/cassette_active.ico similarity index 100% rename from src/win/icons/cassette_active.ico rename to src/qt/icons/cassette_active.ico diff --git a/src/win/icons/cassette_empty.ico b/src/qt/icons/cassette_empty.ico similarity index 100% rename from src/win/icons/cassette_empty.ico rename to src/qt/icons/cassette_empty.ico diff --git a/src/win/icons/cassette_empty_active.ico b/src/qt/icons/cassette_empty_active.ico similarity index 100% rename from src/win/icons/cassette_empty_active.ico rename to src/qt/icons/cassette_empty_active.ico diff --git a/src/win/icons/cdrom.ico b/src/qt/icons/cdrom.ico similarity index 100% rename from src/win/icons/cdrom.ico rename to src/qt/icons/cdrom.ico diff --git a/src/win/icons/cdrom_active.ico b/src/qt/icons/cdrom_active.ico similarity index 100% rename from src/win/icons/cdrom_active.ico rename to src/qt/icons/cdrom_active.ico diff --git a/src/win/icons/cdrom_disabled.ico b/src/qt/icons/cdrom_disabled.ico similarity index 100% rename from src/win/icons/cdrom_disabled.ico rename to src/qt/icons/cdrom_disabled.ico diff --git a/src/win/icons/cdrom_empty.ico b/src/qt/icons/cdrom_empty.ico similarity index 100% rename from src/win/icons/cdrom_empty.ico rename to src/qt/icons/cdrom_empty.ico diff --git a/src/win/icons/cdrom_empty_active.ico b/src/qt/icons/cdrom_empty_active.ico similarity index 100% rename from src/win/icons/cdrom_empty_active.ico rename to src/qt/icons/cdrom_empty_active.ico diff --git a/src/win/icons/display.ico b/src/qt/icons/display.ico similarity index 100% rename from src/win/icons/display.ico rename to src/qt/icons/display.ico diff --git a/src/win/icons/floppy_35.ico b/src/qt/icons/floppy_35.ico similarity index 100% rename from src/win/icons/floppy_35.ico rename to src/qt/icons/floppy_35.ico diff --git a/src/win/icons/floppy_35_active.ico b/src/qt/icons/floppy_35_active.ico similarity index 100% rename from src/win/icons/floppy_35_active.ico rename to src/qt/icons/floppy_35_active.ico diff --git a/src/win/icons/floppy_35_empty.ico b/src/qt/icons/floppy_35_empty.ico similarity index 100% rename from src/win/icons/floppy_35_empty.ico rename to src/qt/icons/floppy_35_empty.ico diff --git a/src/win/icons/floppy_35_empty_active.ico b/src/qt/icons/floppy_35_empty_active.ico similarity index 100% rename from src/win/icons/floppy_35_empty_active.ico rename to src/qt/icons/floppy_35_empty_active.ico diff --git a/src/win/icons/floppy_525.ico b/src/qt/icons/floppy_525.ico similarity index 100% rename from src/win/icons/floppy_525.ico rename to src/qt/icons/floppy_525.ico diff --git a/src/win/icons/floppy_525_active.ico b/src/qt/icons/floppy_525_active.ico similarity index 100% rename from src/win/icons/floppy_525_active.ico rename to src/qt/icons/floppy_525_active.ico diff --git a/src/win/icons/floppy_525_empty.ico b/src/qt/icons/floppy_525_empty.ico similarity index 100% rename from src/win/icons/floppy_525_empty.ico rename to src/qt/icons/floppy_525_empty.ico diff --git a/src/win/icons/floppy_525_empty_active.ico b/src/qt/icons/floppy_525_empty_active.ico similarity index 100% rename from src/win/icons/floppy_525_empty_active.ico rename to src/qt/icons/floppy_525_empty_active.ico diff --git a/src/win/icons/floppy_and_cdrom_drives.ico b/src/qt/icons/floppy_and_cdrom_drives.ico similarity index 100% rename from src/win/icons/floppy_and_cdrom_drives.ico rename to src/qt/icons/floppy_and_cdrom_drives.ico diff --git a/src/win/icons/floppy_disabled.ico b/src/qt/icons/floppy_disabled.ico similarity index 100% rename from src/win/icons/floppy_disabled.ico rename to src/qt/icons/floppy_disabled.ico diff --git a/src/win/icons/hard_disk.ico b/src/qt/icons/hard_disk.ico similarity index 100% rename from src/win/icons/hard_disk.ico rename to src/qt/icons/hard_disk.ico diff --git a/src/win/icons/hard_disk_active.ico b/src/qt/icons/hard_disk_active.ico similarity index 100% rename from src/win/icons/hard_disk_active.ico rename to src/qt/icons/hard_disk_active.ico diff --git a/src/win/icons/hard_reset.ico b/src/qt/icons/hard_reset.ico similarity index 100% rename from src/win/icons/hard_reset.ico rename to src/qt/icons/hard_reset.ico diff --git a/src/win/icons/input_devices.ico b/src/qt/icons/input_devices.ico similarity index 100% rename from src/win/icons/input_devices.ico rename to src/qt/icons/input_devices.ico diff --git a/src/win/icons/machine.ico b/src/qt/icons/machine.ico similarity index 100% rename from src/win/icons/machine.ico rename to src/qt/icons/machine.ico diff --git a/src/win/icons/mo.ico b/src/qt/icons/mo.ico similarity index 100% rename from src/win/icons/mo.ico rename to src/qt/icons/mo.ico diff --git a/src/win/icons/mo_active.ico b/src/qt/icons/mo_active.ico similarity index 100% rename from src/win/icons/mo_active.ico rename to src/qt/icons/mo_active.ico diff --git a/src/win/icons/mo_disabled.ico b/src/qt/icons/mo_disabled.ico similarity index 100% rename from src/win/icons/mo_disabled.ico rename to src/qt/icons/mo_disabled.ico diff --git a/src/win/icons/mo_empty.ico b/src/qt/icons/mo_empty.ico similarity index 100% rename from src/win/icons/mo_empty.ico rename to src/qt/icons/mo_empty.ico diff --git a/src/win/icons/mo_empty_active.ico b/src/qt/icons/mo_empty_active.ico similarity index 100% rename from src/win/icons/mo_empty_active.ico rename to src/qt/icons/mo_empty_active.ico diff --git a/src/win/icons/network.ico b/src/qt/icons/network.ico similarity index 100% rename from src/win/icons/network.ico rename to src/qt/icons/network.ico diff --git a/src/win/icons/network_active.ico b/src/qt/icons/network_active.ico similarity index 100% rename from src/win/icons/network_active.ico rename to src/qt/icons/network_active.ico diff --git a/src/win/icons/network_empty.ico b/src/qt/icons/network_empty.ico similarity index 100% rename from src/win/icons/network_empty.ico rename to src/qt/icons/network_empty.ico diff --git a/src/win/icons/other_peripherals.ico b/src/qt/icons/other_peripherals.ico similarity index 100% rename from src/win/icons/other_peripherals.ico rename to src/qt/icons/other_peripherals.ico diff --git a/src/win/icons/other_removable_devices.ico b/src/qt/icons/other_removable_devices.ico similarity index 100% rename from src/win/icons/other_removable_devices.ico rename to src/qt/icons/other_removable_devices.ico diff --git a/src/win/icons/pause.ico b/src/qt/icons/pause.ico similarity index 100% rename from src/win/icons/pause.ico rename to src/qt/icons/pause.ico diff --git a/src/win/icons/ports.ico b/src/qt/icons/ports.ico similarity index 100% rename from src/win/icons/ports.ico rename to src/qt/icons/ports.ico diff --git a/src/win/icons/run.ico b/src/qt/icons/run.ico similarity index 100% rename from src/win/icons/run.ico rename to src/qt/icons/run.ico diff --git a/src/win/icons/send_cad.ico b/src/qt/icons/send_cad.ico similarity index 100% rename from src/win/icons/send_cad.ico rename to src/qt/icons/send_cad.ico diff --git a/src/win/icons/send_cae.ico b/src/qt/icons/send_cae.ico similarity index 100% rename from src/win/icons/send_cae.ico rename to src/qt/icons/send_cae.ico diff --git a/src/win/icons/settings.ico b/src/qt/icons/settings.ico similarity index 100% rename from src/win/icons/settings.ico rename to src/qt/icons/settings.ico diff --git a/src/win/icons/sound.ico b/src/qt/icons/sound.ico similarity index 100% rename from src/win/icons/sound.ico rename to src/qt/icons/sound.ico diff --git a/src/win/icons/storage_controllers.ico b/src/qt/icons/storage_controllers.ico similarity index 100% rename from src/win/icons/storage_controllers.ico rename to src/qt/icons/storage_controllers.ico diff --git a/src/win/icons/zip.ico b/src/qt/icons/zip.ico similarity index 100% rename from src/win/icons/zip.ico rename to src/qt/icons/zip.ico diff --git a/src/win/icons/zip_active.ico b/src/qt/icons/zip_active.ico similarity index 100% rename from src/win/icons/zip_active.ico rename to src/qt/icons/zip_active.ico diff --git a/src/win/icons/zip_disabled.ico b/src/qt/icons/zip_disabled.ico similarity index 100% rename from src/win/icons/zip_disabled.ico rename to src/qt/icons/zip_disabled.ico diff --git a/src/win/icons/zip_empty.ico b/src/qt/icons/zip_empty.ico similarity index 100% rename from src/win/icons/zip_empty.ico rename to src/qt/icons/zip_empty.ico diff --git a/src/win/icons/zip_empty_active.ico b/src/qt/icons/zip_empty_active.ico similarity index 100% rename from src/win/icons/zip_empty_active.ico rename to src/qt/icons/zip_empty_active.ico diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 197ca980c..f87f8b6a9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -199,13 +199,13 @@ main(int argc, char *argv[]) #ifndef Q_OS_MACOS # ifdef RELEASE_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-green.ico")); # elif defined ALPHA_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-red.ico")); # elif defined BETA_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-yellow.ico")); # else - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-gray.ico")); # endif # ifdef Q_OS_UNIX diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f24ab0788..f0d2cf431 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1704,13 +1704,13 @@ MainWindow::on_actionAbout_86Box_triggered() QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); #ifdef RELEASE_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-green.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-green.ico").pixmap(32, 32)); #elif defined ALPHA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-red.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-red.ico").pixmap(32, 32)); #elif defined BETA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-yellow.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-yellow.ico").pixmap(32, 32)); #else - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-gray.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-gray.ico").pixmap(32, 32)); #endif msgBox.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); msgBox.exec(); @@ -1869,7 +1869,7 @@ MainWindow::setSendKeyboardInput(bool enabled) void MainWindow::updateUiPauseState() { - auto pause_icon = dopause ? QIcon(":/menuicons/win/icons/run.ico") : QIcon(":/menuicons/win/icons/pause.ico"); + auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : QIcon(":/menuicons/qt/icons/pause.ico"); auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 08d8bbf63..90dbfdab7 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -292,7 +292,7 @@ - :/menuicons/win/icons/hard_reset.ico:/menuicons/win/icons/hard_reset.ico + :/menuicons/qt/icons/hard_reset.ico:/menuicons/qt/icons/hard_reset.ico &Hard Reset... @@ -304,7 +304,7 @@ - :/menuicons/win/icons/send_cad.ico:/menuicons/win/icons/send_cad.ico + :/menuicons/qt/icons/send_cad.ico:/menuicons/qt/icons/send_cad.ico &Ctrl+Alt+Del @@ -325,7 +325,7 @@ - :/menuicons/win/icons/send_cae.ico:/menuicons/win/icons/send_cae.ico + :/menuicons/qt/icons/send_cae.ico:/menuicons/qt/icons/send_cae.ico Ctrl+Alt+&Esc @@ -340,7 +340,7 @@ - :/menuicons/win/icons/pause.ico:/menuicons/win/icons/pause.ico + :/menuicons/qt/icons/pause.ico:/menuicons/qt/icons/pause.ico &Pause @@ -357,7 +357,7 @@ - :/menuicons/win/icons/settings.ico:/menuicons/win/icons/settings.ico + :/menuicons/qt/icons/settings.ico:/menuicons/qt/icons/settings.ico &Settings... @@ -768,7 +768,7 @@ - :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico + :/menuicons/qt/icons/acpi_shutdown.ico:/menuicons/qt/icons/acpi_shutdown.ico ACPI shutdown diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4dda901d7..35466e667 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -46,7 +46,7 @@ ProgSettings::getIconSetPath() { if (iconset_to_qt.isEmpty()) { // Always include default bundled icons - iconset_to_qt.insert("", ":/settings/win/icons"); + iconset_to_qt.insert("", ":/settings/qt/icons"); // Walk rom_paths to get the candidates for (rom_path_t *emu_rom_path = &rom_paths; emu_rom_path != nullptr; emu_rom_path = emu_rom_path->next) { // Check for icons subdir in each candidate diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index bc2be70cd..0f19d46fc 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -206,7 +206,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setEnabled(false); } - ui->checkBoxLbaEnhancer->setEnabled(device_available(&lba_enhancer_device)); ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } diff --git a/src/win/win_netsocket.c b/src/qt/win_netsocket.c similarity index 100% rename from src/win/win_netsocket.c rename to src/qt/win_netsocket.c diff --git a/src/win/win_opendir.c b/src/qt/win_opendir.c similarity index 100% rename from src/win/win_opendir.c rename to src/qt/win_opendir.c diff --git a/src/win/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c similarity index 100% rename from src/win/win_serial_passthrough.c rename to src/qt/win_serial_passthrough.c diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index 67f9cadac..265fb6376 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -1,62 +1,62 @@ - win/icons/cartridge.ico - win/icons/cartridge_empty.ico - win/icons/cassette.ico - win/icons/cassette_active.ico - win/icons/cassette_empty.ico - win/icons/cassette_empty_active.ico - win/icons/cdrom.ico - win/icons/cdrom_active.ico - win/icons/cdrom_disabled.ico - win/icons/cdrom_empty.ico - win/icons/cdrom_empty_active.ico - win/icons/display.ico - win/icons/floppy_35.ico - win/icons/floppy_35_active.ico - win/icons/floppy_35_empty.ico - win/icons/floppy_35_empty_active.ico - win/icons/floppy_525.ico - win/icons/floppy_525_active.ico - win/icons/floppy_525_empty.ico - win/icons/floppy_525_empty_active.ico - win/icons/floppy_and_cdrom_drives.ico - win/icons/floppy_disabled.ico - win/icons/hard_disk.ico - win/icons/hard_disk_active.ico - win/icons/input_devices.ico - win/icons/machine.ico - win/icons/mo.ico - win/icons/mo_active.ico - win/icons/mo_disabled.ico - win/icons/mo_empty.ico - win/icons/mo_empty_active.ico - win/icons/network.ico - win/icons/network_active.ico - win/icons/network_empty.ico - win/icons/other_peripherals.ico - win/icons/other_removable_devices.ico - win/icons/ports.ico - win/icons/sound.ico - win/icons/storage_controllers.ico - win/icons/zip.ico - win/icons/zip_active.ico - win/icons/zip_disabled.ico - win/icons/zip_empty.ico - win/icons/zip_empty_active.ico - win/icons/86Box-gray.ico - win/icons/86Box-green.ico - win/icons/86Box-red.ico - win/icons/86Box-yellow.ico + qt/icons/cartridge.ico + qt/icons/cartridge_empty.ico + qt/icons/cassette.ico + qt/icons/cassette_active.ico + qt/icons/cassette_empty.ico + qt/icons/cassette_empty_active.ico + qt/icons/cdrom.ico + qt/icons/cdrom_active.ico + qt/icons/cdrom_disabled.ico + qt/icons/cdrom_empty.ico + qt/icons/cdrom_empty_active.ico + qt/icons/display.ico + qt/icons/floppy_35.ico + qt/icons/floppy_35_active.ico + qt/icons/floppy_35_empty.ico + qt/icons/floppy_35_empty_active.ico + qt/icons/floppy_525.ico + qt/icons/floppy_525_active.ico + qt/icons/floppy_525_empty.ico + qt/icons/floppy_525_empty_active.ico + qt/icons/floppy_and_cdrom_drives.ico + qt/icons/floppy_disabled.ico + qt/icons/hard_disk.ico + qt/icons/hard_disk_active.ico + qt/icons/input_devices.ico + qt/icons/machine.ico + qt/icons/mo.ico + qt/icons/mo_active.ico + qt/icons/mo_disabled.ico + qt/icons/mo_empty.ico + qt/icons/mo_empty_active.ico + qt/icons/network.ico + qt/icons/network_active.ico + qt/icons/network_empty.ico + qt/icons/other_peripherals.ico + qt/icons/other_removable_devices.ico + qt/icons/ports.ico + qt/icons/sound.ico + qt/icons/storage_controllers.ico + qt/icons/zip.ico + qt/icons/zip_active.ico + qt/icons/zip_disabled.ico + qt/icons/zip_empty.ico + qt/icons/zip_empty_active.ico + qt/icons/86Box-gray.ico + qt/icons/86Box-green.ico + qt/icons/86Box-red.ico + qt/icons/86Box-yellow.ico - win/icons/acpi_shutdown.ico - win/icons/hard_reset.ico - win/icons/pause.ico - win/icons/run.ico - win/icons/send_cad.ico - win/icons/send_cae.ico - win/icons/settings.ico + qt/icons/acpi_shutdown.ico + qt/icons/hard_reset.ico + qt/icons/pause.ico + qt/icons/run.ico + qt/icons/send_cad.ico + qt/icons/send_cae.ico + qt/icons/settings.ico qt/texture_vert.spv diff --git a/src/win/86Box.rc b/src/win/86Box.rc deleted file mode 100644 index 2932b7d62..000000000 --- a/src/win/86Box.rc +++ /dev/null @@ -1,365 +0,0 @@ -/* - * 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. - * - * Application resource script for Windows. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021 Laci bá' - */ -#define IN_RESOURCE_H -#include <86box/resource.h> -#include <86box/language.h> -#include <86box/version.h> -#undef IN_RESOURCE_H - -#define APSTUDIO_READONLY_SYMBOLS -#define APSTUDIO_HIDDEN_SYMBOLS -#include -#undef APSTUDIO_HIDDEN_SYMBOLS -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -MainAccel ACCELERATORS MOVEABLE PURE -BEGIN -#ifdef MTR_ENABLED - "T", IDM_ACTION_TRACE, CONTROL, VIRTKEY -#endif - // VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT - VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL - VK_PAUSE,IDM_ACTION_PAUSE, VIRTKEY -END - - -#ifndef NO_INCLUDE_MANIFEST -///////////////////////////////////////////////////////////////////////////// -// -// 24 -// - -1 24 MOVEABLE PURE "86Box.manifest" -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -#ifdef CMAKE -#define ICON_PATH -#else -#define ICON_PATH "win/" -#endif - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -// defining the icons depending on the build status -#ifdef RELEASE_BUILD -/* Icon by OBattler and laciba96 (green for release builds)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-green.ico" -#elif BETA_BUILD -/* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-yellow.ico" -#elif ALPHA_BUILD -/* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-red.ico" -#else -/* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-gray.ico" -#endif - 16 ICON DISCARDABLE ICON_PATH "icons/floppy_525.ico" - 17 ICON DISCARDABLE ICON_PATH "icons/floppy_525_active.ico" - 24 ICON DISCARDABLE ICON_PATH "icons/floppy_35.ico" - 25 ICON DISCARDABLE ICON_PATH "icons/floppy_35_active.ico" - 32 ICON DISCARDABLE ICON_PATH "icons/cdrom.ico" - 33 ICON DISCARDABLE ICON_PATH "icons/cdrom_active.ico" - 48 ICON DISCARDABLE ICON_PATH "icons/zip.ico" - 49 ICON DISCARDABLE ICON_PATH "icons/zip_active.ico" - 56 ICON DISCARDABLE ICON_PATH "icons/mo.ico" - 57 ICON DISCARDABLE ICON_PATH "icons/mo_active.ico" - 64 ICON DISCARDABLE ICON_PATH "icons/cassette.ico" - 65 ICON DISCARDABLE ICON_PATH "icons/cassette_active.ico" - 80 ICON DISCARDABLE ICON_PATH "icons/hard_disk.ico" - 81 ICON DISCARDABLE ICON_PATH "icons/hard_disk_active.ico" - 96 ICON DISCARDABLE ICON_PATH "icons/network.ico" - 97 ICON DISCARDABLE ICON_PATH "icons/network_active.ico" -104 ICON DISCARDABLE ICON_PATH "icons/cartridge.ico" -144 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty.ico" -145 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty_active.ico" -152 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty.ico" -153 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty_active.ico" -160 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty.ico" -161 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty_active.ico" -176 ICON DISCARDABLE ICON_PATH "icons/zip_empty.ico" -177 ICON DISCARDABLE ICON_PATH "icons/zip_empty_active.ico" -184 ICON DISCARDABLE ICON_PATH "icons/mo_empty.ico" -185 ICON DISCARDABLE ICON_PATH "icons/mo_empty_active.ico" -192 ICON DISCARDABLE ICON_PATH "icons/cassette_empty.ico" -193 ICON DISCARDABLE ICON_PATH "icons/cassette_empty_active.ico" -200 ICON DISCARDABLE ICON_PATH "icons/run.ico" -201 ICON DISCARDABLE ICON_PATH "icons/pause.ico" -202 ICON DISCARDABLE ICON_PATH "icons/send_cad.ico" -203 ICON DISCARDABLE ICON_PATH "icons/send_cae.ico" -204 ICON DISCARDABLE ICON_PATH "icons/hard_reset.ico" -205 ICON DISCARDABLE ICON_PATH "icons/acpi_shutdown.ico" -206 ICON DISCARDABLE ICON_PATH "icons/settings.ico" -232 ICON DISCARDABLE ICON_PATH "icons/cartridge_empty.ico" -240 ICON DISCARDABLE ICON_PATH "icons/machine.ico" -241 ICON DISCARDABLE ICON_PATH "icons/display.ico" -242 ICON DISCARDABLE ICON_PATH "icons/input_devices.ico" -243 ICON DISCARDABLE ICON_PATH "icons/sound.ico" -244 ICON DISCARDABLE ICON_PATH "icons/ports.ico" -245 ICON DISCARDABLE ICON_PATH "icons/other_peripherals.ico" -246 ICON DISCARDABLE ICON_PATH "icons/floppy_and_cdrom_drives.ico" -247 ICON DISCARDABLE ICON_PATH "icons/other_removable_devices.ico" -248 ICON DISCARDABLE ICON_PATH "icons/floppy_disabled.ico" -249 ICON DISCARDABLE ICON_PATH "icons/cdrom_disabled.ico" -250 ICON DISCARDABLE ICON_PATH "icons/zip_disabled.ico" -251 ICON DISCARDABLE ICON_PATH "icons/mo_disabled.ico" -252 ICON DISCARDABLE ICON_PATH "icons/storage_controllers.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resources.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - DLG_SND_GAIN, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 167 - TOPMARGIN, 7 - BOTTOMMARGIN, 129 - END - - DLG_NEW_FLOPPY, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 219 - TOPMARGIN, 7 - BOTTOMMARGIN, 79 - END - - DLG_CFG_MAIN, DIALOG - BEGIN - RIGHTMARGIN, 365 - END - - ABOUTDLG, DIALOG - BEGIN - RIGHTMARGIN, 208 - END - - DLG_CFG_MACHINE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 -#ifdef USE_DYNAREC - BOTTOMMARGIN, 87 -#else - BOTTOMMARGIN, 72 -#endif - END - - DLG_CFG_VIDEO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 38 - END - - DLG_CFG_INPUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 58 - END - - DLG_CFG_SOUND, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 109 - END - - DLG_CFG_NETWORK, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 56 - END - - DLG_CFG_PORTS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 48 - END - - DLG_CFG_PERIPHERALS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 85 - END - - DLG_CFG_HARD_DISKS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 137 - END - - DLG_CFG_FLOPPY_DRIVES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 96 - END - - DLG_CFG_OTHER_REMOVABLE_DEVICES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 214 - END -END -#endif // APSTUDIO_INVOKED - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM - PRODUCTVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", EMU_NAME "\0" - VALUE "FileDescription", EMU_NAME "\0" - VALUE "FileVersion", EMU_VERSION "\0" - VALUE "InternalName", EMU_NAME "\0" - VALUE "LegalCopyright", "Copyright \xa9 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" - VALUE "OriginalFilename", EMU_NAME ".exe\0" - VALUE "ProductName", EMU_NAME "\0" - VALUE "ProductVersion", EMU_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -#endif - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - - -#include "languages/zh-CN.rc" -#include "languages/cs-CZ.rc" -#include "languages/de-DE.rc" -#include "languages/en-US.rc" -#include "languages/en-GB.rc" -#include "languages/fr-FR.rc" -#include "languages/hr-HR.rc" -#include "languages/fi-FI.rc" -#include "languages/hu-HU.rc" -#include "languages/it-IT.rc" -#include "languages/ja-JP.rc" -#include "languages/ko-KR.rc" -#include "languages/pl-PL.rc" -#include "languages/pt-BR.rc" -#include "languages/pt-PT.rc" -#include "languages/ru-RU.rc" -#include "languages/sl-SI.rc" -#include "languages/es-ES.rc" -#include "languages/tr-TR.rc" -#include "languages/uk-UA.rc" -#include "languages/zh-TW.rc" diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt deleted file mode 100644 index dc8c53e45..000000000 --- a/src/win/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# -# 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. -# -# CMake build script. -# -# Authors: David Hrdlička, -# -# Copyright 2020,2021 David Hrdlička. -# Copyright 2021-2022 Jasmine Iwanek. -# - -enable_language(RC) - -add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_keyboard.c - win_mouse.c win_serial_passthrough.c) - -add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win_about.c - win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c - win_jsconf.c win_media_menu.c win_preferences.c glad.c win_opengl.c - win_opengl_glslp.c win_toolbar.c 86Box.rc) - -if(NOT CPPTHREADS) - target_sources(plat PRIVATE win_thread.c) -endif() - -if(RTMIDI) - target_compile_definitions(ui PRIVATE USE_RTMIDI) -endif() - -# CMake 3.22 messed this up for clang/clang++ -# See https://gitlab.kitware.com/cmake/cmake/-/issues/23066 -if(MSVC OR (NOT MINGW AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)) - # MSVC linker adds its own manifest to the executable, which fails if - # we include ours in 86Box.rc. We therefore need to pass the manifest - # directly as as a source file, so the linker can use that instead. - set_property(SOURCE 86Box.rc PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) - target_sources(86Box PRIVATE 86Box.manifest) -endif() - -if(NOT MINGW) - # Append null to resource strings (fixes file dialogs) - set_property(SOURCE 86Box.rc PROPERTY COMPILE_FLAGS -n) - - # `opendir` is only included in MinGW, so include an implementation - # for other builds. - target_sources(plat PRIVATE win_opendir.c) -endif() - -option(DINPUT "Use DirectInput joystick backend instead of raw input" OFF) -if(DINPUT) - target_sources(plat PRIVATE win_joystick.cpp) - target_link_libraries(86Box dinput8) -else() - target_sources(plat PRIVATE win_joystick_rawinput.c) -endif() - -target_link_libraries(86Box advapi32 comctl32 comdlg32 gdi32 shell32 iphlpapi - dxguid imm32 hid setupapi uxtheme version winmm psapi ws2_32) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw deleted file mode 100644 index a80458938..000000000 --- a/src/win/Makefile.mingw +++ /dev/null @@ -1,988 +0,0 @@ -# -# -# 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. -# -# Makefile for Win32 (MinGW32) environment. -# -# Authors: Miran Grca, -# Fred N. van Kempen, -# - -# Various compile-time options. -ifndef STUFF - STUFF := -endif - -# Add feature selections here. -ifndef EXTRAS - EXTRAS := -endif - -ifndef DEV_BUILD - DEV_BUILD := n -endif - -ifeq ($(DEV_BUILD), y) - ifndef DEBUG - DEBUG := y - endif - ifndef GDBSTUB - GDBSTUB := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := y - endif - ifndef AMD_K5 - AMD_K5 := y - endif - ifndef AN430TX - AN430TX := y - endif - ifndef CYRIX_6X86 - CYRIX_6X86 := y - endif - ifndef DESKPRO386 - DESKPRO386 := y - endif - ifndef GUSMAX - GUSMAX := y - endif - ifndef ISAMEM_RAMPAGE - ISAMEM_RAMPAGE := y - endif - ifndef ISAMEM_IAB - ISAMEM_IAB := y - endif - ifndef ISAMEM_BRAT - ISAMEM_BRAT := y - endif - ifndef LASERXT - LASERXT := y - endif - ifndef OLIVETTI - OLIVETTI := y - endif - ifndef OPEN_AT - OPEN_AT := y - endif - ifndef OPL4ML - OPL4ML := y - endif - ifndef PAS16 - PAS16 := y - endif - ifndef PCI_DUMMY - PCI_DUMMY := y - endif - ifndef SIO_DETECT - SIO_DETECT := y - endif - ifndef VGAWONDER - VGAWONDER := y - endif - ifndef XL24 - XL24 := y - endif - ifndef NEW_KBC - NEW_KBC := n - endif -else - ifndef DEBUG - DEBUG := n - endif - ifndef GDBSTUB - GDBSTUB := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := n - endif - ifndef AMD_K5 - AMD_K5 := n - endif - ifndef AN430TX - AN430TX := n - endif - ifndef CYRIX_6X86 - CYRIX_6X86 := n - endif - ifndef DESKPRO386 - DESKPRO386 := n - endif - ifndef GUSMAX - GUSMAX := n - endif - ifndef ISAMEM_RAMPAGE - ISAMEM_RAMPAGE := n - endif - ifndef ISAMEM_IAB - ISAMEM_IAB := n - endif - ifndef ISAMEM_BRAT - ISAMEM_BRAT := n - endif - ifndef LASERXT - LASERXT := n - endif - ifndef OLIVETTI - OLIVETTI := n - endif - ifndef OPEN_AT - OPEN_AT := n - endif - ifndef OPL4ML - OPL4ML := n - endif - ifndef PAS16 - PAS16 := n - endif - ifndef PCI_DUMMY - PCI_DUMMY := n - endif - ifndef SIO_DETECT - SIO_DETECT := n - endif - ifndef VGAWONDER - VGAWONDER := n - endif - ifndef XL24 - XL24 := n - endif - ifndef NEW_KBC - NEW_KBC := n - endif -endif - -# Defaults for several build options (possibly defined in a chained file.) -ifndef AUTODEP - AUTODEP := n -endif -ifndef OPTIM - OPTIM := n -endif -ifndef RELEASE - RELEASE := n -endif -ifndef X64 - X64 := n -endif -ifndef ARM - ARM := n -endif -ifndef ARM64 - ARM64 := n -endif -ifndef DINPUT - DINPUT := n -endif -ifndef FAUDIO - FAUDIO := n -endif -ifndef OPENAL - OPENAL := y -endif -ifndef FLUIDSYNTH - FLUIDSYNTH := y -endif -ifndef MUNT - MUNT := y -endif -ifndef VNC - VNC := n -endif -ifndef NEW_DYNAREC - NEW_DYNAREC := n -endif -ifndef DYNAREC - DYNAREC := y -endif -ifndef CPPTHREADS - CPPTHREADS := y -endif -ifndef RTMIDI - RTMIDI := y -endif -ifndef MINITRACE - MINITRACE := n -endif -ifndef AVX - AVX := n -endif -ifeq ($(DYNAREC), y) - ifeq ($(ARM), y) - ifeq ($(NEW_DYNAREC), n) - DYNAREC := n - endif - endif - ifeq ($(ARM64), y) - ifeq ($(NEW_DYNAREC), n) - DYNAREC := n - endif - endif -endif - - -# Path to the dynamic recompiler code. -ifeq ($(NEW_DYNAREC), y) - CODEGEN := codegen_new -else - CODEGEN := codegen -endif - - -# Name of the executable. -PROG := 86Box - - -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu cpu/softfloat \ - cpu/808x cdrom chipset device disk disk/minivhd floppy \ - game machine mem printer \ - sio sound \ - sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper sound/munt/srchelper/srctools/src \ - sound/resid-fp sound/ymfm \ - scsi video network win - -WINDRES := windres -STRIP := strip -ifeq ($(X64), y) - TOOL_PREFIX := x86_64-w64-mingw32- -else - ifeq ($(ARM64), y) - TOOL_PREFIX := aarch64-w64-mingw32- - WINDRES := ${TOOL_PREFIX}windres - STRIP := ${TOOL_PREFIX}strip - endif - ifeq ($(ARM), y) - TOOL_PREFIX := armv7-w64-mingw32- - WINDRES := ${TOOL_PREFIX}windres - STRIP := ${TOOL_PREFIX}strip - endif - TOOL_PREFIX := i686-w64-mingw32- -endif - -ifeq ($(CLANG), y) - CPP := clang++ - CC := clang -else - CPP := ${TOOL_PREFIX}g++ - CC := ${TOOL_PREFIX}gcc -endif - -DEPS = -MMD -MF $*.d -c $< -DEPFILE := win/.depends - -# Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) -OPTS += -Iinclude -Iinclude_make \ - -iquote $(CODEGEN) -iquote cpu -ifdef EXFLAGS - OPTS += $(EXFLAGS) -endif -ifdef EXINC - OPTS += -I$(EXINC) -endif -ifeq ($(OPTIM), y) - DFLAGS := -march=native -else - ifeq ($(X64), y) - DFLAGS := - else - DFLAGS := -march=i686 - endif -endif -ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG - AOPTIM := - ifndef COPTIM - COPTIM := -Og - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os - else - CXXOPTIM := -Og - endif - endif -else - DFLAGS += -g0 - ifeq ($(OPTIM), y) - AOPTIM := -mtune=native - ifndef COPTIM - CXXOPTIM := -O3 -ffp-contract=fast -flto - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os -ffp-contract=fast -flto - else - CXXOPTIM := -O3 -ffp-contract=fast -flto - endif - endif - else - ifndef COPTIM - COPTIM := -O3 - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os - else - CXXOPTIM := -O3 - endif - endif - endif -endif -ifeq ($(AVX), y) - AFLAGS := -msse2 -msse3 -mssse3 -msse4 -msse4a -mavx -mavx2 -mfpmath=sse -else - AFLAGS := -msse2 -mfpmath=sse -endif -ifeq ($(ARM), y) - DFLAGS := -march=armv7-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -ifeq ($(ARM64), y) - DFLAGS := -march=armv8-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -RFLAGS := --input-format=rc -O coff -Iinclude -Iinclude_make -ifeq ($(RELEASE), y) - OPTS += -DRELEASE_BUILD - RFLAGS += -DRELEASE_BUILD -endif - - -# Optional modules. -ifeq ($(DYNAREC), y) - OPTS += -DUSE_DYNAREC - RFLAGS += -DUSE_DYNAREC - - ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC - - ifeq ($(X64), y) - PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ - codegen_backend_x86-64_uops.o - else ifeq ($(ARM64), y) - PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ - codegen_backend_arm64_imm.o - else ifeq ($(ARM), y) - PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o - else - PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ - codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o - endif - - DYNARECOBJ := codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ - codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ - codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o \ - codegen_ops_jump.o codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ - codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ - codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o $(PLATCG) - else - ifeq ($(X64), y) - PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o - else - PLATCG := codegen_x86.o codegen_accumulate_x86.o - endif - - DYNARECOBJ := codegen.o \ - codegen_ops.o $(PLATCG) - endif - - CGTOBJ := codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o -else - ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC - endif -endif - -ifeq ($(FLUIDSYNTH), y) - OPTS += -DUSE_FLUIDSYNTH - FSYNTHOBJ := midi_fluidsynth.o -endif - -ifeq ($(MUNT), y) - OPTS += -DUSE_MUNT - MUNTOBJ := midi_mt32.o \ - Analog.o BReverbModel.o Display.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter.o \ - FIRResampler.o IIR2xResampler.o LinearResampler.o ResamplerModel.o \ - SincResampler.o InternalResampler.o \ - Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o -endif - -ifeq ($(CPPTHREADS), y) - THREADOBJ := thread.o -else - THREADOBJ := win_thread.o -endif - -ifeq ($(VNC), y) - OPTS += -DUSE_VNC - RFLAGS += -DUSE_VNC - ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)\INCLUDE - VNCLIB := -L$(VNC_PATH)\LIB - endif - VNCLIB += -lvncserver.dll - VNCOBJ := vnc.o vnc_keymap.o -endif - -ifeq ($(MINITRACE), y) - OPTS += -DMTR_ENABLED - RFLAGS += -DMTR_ENABLED - MINITRACEOBJ := minitrace.o -endif - -ifeq ($(FAUDIO), y) - OPTS += -DUSE_FAUDIO -endif - -# Options for the DEV branch. -ifeq ($(DEV_BRANCH), y) - OPTS += -DDEV_BRANCH - RFLAGS += -DDEV_BRANCH - DEVBROBJ := - - ifeq ($(AMD_K5), y) - OPTS += -DUSE_AMD_K5 - endif - - ifeq ($(AN430TX), y) - OPTS += -DUSE_AN430TX - endif - - ifeq ($(CYRIX_6X86), y) - OPTS += -DUSE_CYRIX_6X86 - endif - - ifeq ($(DESKPRO386), y) - OPTS += -DUSE_DESKPRO386 - endif - - ifeq ($(GUSMAX), y) - OPTS += -DUSE_GUSMAX - endif - - ifeq ($(ISAMEM_RAMPAGE), y) - OPTS += -DUSE_ISAMEM_RAMPAGE - endif - - ifeq ($(ISAMEM_IAB), y) - OPTS += -DUSE_ISAMEM_IAB - endif - - ifeq ($(ISAMEM_BRAT), y) - OPTS += -DUSE_ISAMEM_BRAT - endif - - ifeq ($(LASERXT), y) - OPTS += -DUSE_LASERXT - DEVBROBJ += m_xt_laserxt.o - endif - - ifeq ($(OPEN_AT), y) - OPTS += -DUSE_OPEN_AT - endif - - ifeq ($(OPL4ML), y) - OPTS += -DUSE_OPL4ML - DEVBROBJ += midi_opl4.o midi_opl4_yrw801.o - endif - - ifeq ($(PAS16), y) - OPTS += -DUSE_PAS16 - DEVBROBJ += snd_pas16.o - endif - - ifeq ($(PCI_DUMMY), y) - OPTS += -DUSE_PCI_DUMMY - DEVBROBJ += pci_dummy.o - endif - - ifeq ($(SIO_DETECT), y) - OPTS += -DUSE_SIO_DETECT - DEVBROBJ += sio_detect.o - endif - - ifeq ($(VGAWONDER), y) - OPTS += -DUSE_VGAWONDER - endif - - ifeq ($(XL24), y) - OPTS += -DUSE_XL24 - endif - - ifeq ($(OLIVETTI), y) - OPTS += -DUSE_OLIVETTI - DEVBROBJ += olivetti_eva.o - endif - - ifeq ($(GDBSTUB), y) - OPTS += -DUSE_GDBSTUB - DEVBROBJ += gdbstub.o - endif -endif - -ifeq ($(RTMIDI), y) - OPTS += -DUSE_RTMIDI -endif - - -# Final versions of the toolchain flags. -CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing - -# Add freetyp2 references through pkgconfig -CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` - -CXXFLAGS := $(OPTS) $(DFLAGS) $(CXXOPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing - -CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ - -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition - - -######################################################################### -# 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 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 \ - smram.o spd.o sst_flash.o - -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_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 - -CHIPSETOBJ := 82c100.o acc2168.o \ - compaq_386.o \ - contaq_82c59x.o \ - cs4031.o cs8230.o \ - ali1429.o ali1435.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ - gc100.o headland.o \ - ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ - ioapic.o \ - neat.o \ - opti283.o opti291.o opti391.o opti495.o opti602.o opti822.o opti895.o opti5x7.o \ - scamp.o scat.o \ - stpc.o \ - wd76c10.o vl82c480.o \ - umc_8886.o umc_hb4.o \ - via_vt82c49x.o via_vt82c505.o via_apollo.o via_pipc.o \ - sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o - -MCHOBJ := machine.o machine_table.o \ - m_xt.o m_xt_compaq.o \ - m_xt_philips.o \ - m_xt_t1000.o m_xt_t1000_vid.o \ - m_xt_xi8088.o m_xt_zenith.o \ - m_pcjr.o \ - m_amstrad.o m_europc.o \ - m_elt.o \ - m_xt_olivetti.o m_tandy.o m_v86p.o \ - m_at.o m_at_commodore.o \ - m_at_t3100e.o m_at_t3100e_vid.o \ - m_ps1.o m_ps1_hdc.o \ - m_ps2_isa.o m_ps2_mca.o \ - m_at_compaq.o \ - m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4.o m_at_socket5.o m_at_socket7_3v.o m_at_socket7.o m_at_sockets7.o \ - m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ - m_at_misc.o - -KBCOBJ := kbc_at.o kbc_at_dev.o \ - keyboard_at.o - -DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ - ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - clock_ics9xxx.o isapnp.o \ - i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ - keyboard.o \ - keyboard_xt.o $(KBCOBJ) \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o \ - mouse_wacom_tablet.o \ - nec_mate_unk.o phoenix_486_jumper.o \ - serial_passthrough.o \ - unittester.o - -SIOOBJ := sio_acc3221.o sio_ali5123.o \ - sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ - sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ - sio_it86x1f.o \ - sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ - sio_prime3b.o sio_prime3c.o \ - sio_w83787f.o \ - sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o \ - sio_vt82c686.o - -FDDOBJ := fdd.o fdc.o fdc_magitronic.o fdc_monster.o fdc_pii15xb.o \ - fdi2raw.o \ - fdd_common.o fdd_86f.o \ - fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ - fdd_mfm.o fdd_td0.o - -GAMEOBJ := gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o - -HDDOBJ := hdd.o \ - hdd_image.o hdd_table.o \ - hdc.o \ - hdc_st506_xt.o hdc_st506_at.o \ - hdc_xta.o \ - hdc_esdi_at.o hdc_esdi_mca.o \ - hdc_xtide.o hdc_ide.o \ - hdc_ide_ali5213.o \ - hdc_ide_opti611.o \ - hdc_ide_cmd640.o hdc_ide_cmd646.o \ - hdc_ide_sff8038i.o - -MINIVHDOBJ := cwalk.o xml2_encoding.o convert.o \ - create.o minivhd_io.o manage.o struct_rw.o minivhd_util.o - -CDROMOBJ := cdrom.o \ - cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o - -ZIPOBJ := zip.o - -MOOBJ := mo.o - -SCSIOBJ := scsi.o scsi_device.o \ - scsi_cdrom.o scsi_disk.o \ - scsi_x54x.o \ - scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o \ - scsi_pcscsi.o scsi_spock.o - -NETOBJ := network.o \ - net_pcap.o \ - net_slirp.o \ - net_dp8390.o net_3c501.o \ - net_3c503.o net_ne2000.o \ - net_pcnet.o net_wd8003.o \ - net_plip.o net_event.o \ - net_null.o \ - net_eeprom_nmc93cxx.o \ - net_tulip.o \ - net_rtl8139.o \ - net_l80225.o - -PRINTOBJ := png.o prt_cpmap.o \ - prt_escp.o prt_text.o prt_ps.o - -SNDOBJ := sound.o \ - snd_opl.o snd_opl_nuked.o snd_opl_ymfm.o \ - ymfm_adpcm.o ymfm_misc.o ymfm_opl.o ymfm_opm.o \ - ymfm_opn.o ymfm_opq.o ymfm_opz.o ymfm_pcm.o ymfm_ssg.o \ - snd_resid.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - midi.o \ - snd_speaker.o \ - snd_pssj.o \ - snd_ps1.o \ - snd_lpt_dac.o snd_lpt_dss.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ - snd_ac97_codec.o snd_ac97_via.o \ - snd_azt2316a.o snd_cs423x.o \ - snd_optimc.o snd_cmi8x38.o \ - snd_cms.o \ - snd_gus.o \ - snd_sb.o snd_sb_dsp.o \ - snd_emu8k.o snd_mpu401.o \ - snd_sn76489.o snd_ssi2001.o \ - snd_wss.o \ - snd_ym7128.o - -VIDOBJ := agpgart.o video.o \ - vid_table.o \ - vid_cga.o vid_cga_comp.o \ - vid_compaq_cga.o \ - vid_mda.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_pgc.o vid_im1024.o \ - vid_sigma.o \ - vid_wy700.o \ - vid_ega.o vid_ega_render.o \ - vid_svga.o vid_svga_render.o \ - vid_8514a.o \ - vid_ddc.o \ - vid_vga.o \ - vid_ati_eeprom.o \ - vid_ati18800.o vid_ati28800.o \ - vid_ati_mach8.o \ - vid_ati68875_ramdac.o \ - vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_bt48x_ramdac.o \ - vid_chips_69000.o \ - vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ - vid_cl54xx.o \ - vid_et3000.o \ - vid_et4000.o vid_sc1148x_ramdac.o \ - vid_sc1502x_ramdac.o \ - vid_et4000w32.o vid_stg_ramdac.o \ - vid_ht216.o \ - vid_oak_oti.o \ - vid_paradise.o \ - vid_rtg310x.o \ - vid_ti_cf62011.o \ - vid_f82c425.o \ - vid_tvga.o \ - vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_att20c49x_ramdac.o \ - vid_att2xc498_ramdac.o \ - vid_s3.o vid_s3_virge.o \ - vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ - vid_ogc.o \ - vid_mga.o \ - vid_nga.o \ - vid_tvp3026_ramdac.o \ - vid_xga.o - -VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ - vid_voodoo_banshee_blitter.o \ - vid_voodoo_blitter.o \ - vid_voodoo_display.o vid_voodoo_fb.o \ - vid_voodoo_fifo.o vid_voodoo_reg.o \ - vid_voodoo_render.o vid_voodoo_setup.o \ - vid_voodoo_texture.o - -PLATOBJ := win.o \ - win_dynld.o \ - win_cdrom.o win_keyboard.o \ - win_mouse.o win_serial_passthrough.o - -UIOBJ := win_ui.o win_icon.o win_stbar.o discord.o \ - win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ - win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o win_preferences.o \ - win_new_floppy.o win_jsconf.o \ - win_media_menu.o win_toolbar.o - -ifeq ($(DINPUT), y) - PLATOBJ += win_joystick.o -else - PLATOBJ += win_joystick_rawinput.o -endif - -ifeq ($(OPENAL), y) - SNDOBJ += openal.o -else - SNDOBJ += xaudio2.o -endif - -ifeq ($(RTMIDI), y) - SNDOBJ += midi_rtmidi.o -endif - -OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ - $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ - $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) -ifdef EXOBJ - OBJ += $(EXOBJ) -endif - -ifeq ($(LOG), y) - MWIN := -lcomdlg32 -else - MWIN := -mwindows -endif - -LIBS := -lfreetype -lfluidsynth -lslirp -lbz2 -lharfbuzz -lgraphite2 -lbrotlidec \ - -lbrotlicommon -lusp10 -lrpcrt4 -lgomp -lsndfile -lflac -lmp3lame -lmpg123 \ - -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline \ - -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv - -ifeq ($(OPENAL), y) - LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ - -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ - -luuid -lws2_32 -else - ifeq ($(FAUDIO), y) - LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ - -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ - -luuid -lws2_32 - else - LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 \ - -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid \ - -lws2_32 - endif -endif - -ifeq ($(RTMIDI), y) - ifeq ($(CLANG), y) - LIBS += -lrtmidi.dll -lwinmm - else - LIBS += -lrtmidi -lwinmm - endif -endif - -ifeq ($(VNC), y) - LIBS += $(VNCLIB) -lws2_32 -endif -ifeq ($(CLANG), y) - LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++.dll -else - LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ -endif -ifneq ($(X64), y) - ifneq ($(ARM64), y) - LIBS += -Wl,--large-address-aware - endif -endif -ifeq ($(ARM64), y) - LIBS += -lgcc -endif -ifeq ($(DINPUT), y) - LIBS += -ldinput8 -endif - -LIBS += -static - -# Build module rules. -ifeq ($(AUTODEP), y) -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< -else -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.d: %.c $(wildcard $*.d) - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -E $< >/dev/null - -%.d: %.cc $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null - -%.d: %.cpp $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null -endif - -# Suppress false positive warnings in vid_voodoo_codegen_x86[-64].h -# that cause ~3000 lines to be output into the logs each time. -ifneq ($(CLANG), y) - $(VOODOOOBJ): CFLAGS += -Wstringop-overflow=0 -endif - -all: $(PROG).exe - - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) -v $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res - -$(PROG).exe: $(OBJ) 86Box.res - @echo Linking $(PROG).exe .. - @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe -ifneq ($(DEBUG), y) - @$(STRIP) $(PROG).exe -endif - -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res - -pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res - @echo Linking pcap_if.exe .. - @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res -ifneq ($(DEBUG), y) - @$(STRIP) pcap_if.exe -endif - -hello.exe: hello.o - $(CXX) $(LDFLAGS) -o hello.exe hello.o $(LIBS) -ifneq ($(DEBUG), y) - @$(STRIP) hello.exe -endif - - -clean: - @echo Cleaning objects.. - @-rm -f *.o 2>/dev/null - @-rm -f *.res 2>/dev/null - -clobber: clean - @echo Cleaning executables.. - @-rm -f *.d 2>/dev/null - @-rm -f *.exe 2>/dev/null -# @-rm -f $(DEPFILE) 2>/dev/null - -ifneq ($(AUTODEP), y) -depclean: - @-rm -f $(DEPFILE) 2>/dev/null - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) - -depends: DEPOBJ=$(OBJ:%.o=%.d) -depends: depclean $(OBJ:%.o=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @-rm -f $(DEPOBJ) - -$(DEPFILE): -endif - - -# Module dependencies. -ifeq ($(AUTODEP), y) -#-include $(OBJ:%.o=%.d) (better, but sloooowwwww) --include *.d -else -include $(wildcard $(DEPFILE)) -endif - - -# End of Makefile.mingw. diff --git a/src/win/glad.c b/src/win/glad.c deleted file mode 100644 index 7c282ebee..000000000 --- a/src/win/glad.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - - OpenGL loader generated by glad 0.1.36 on Sat Jan 7 18:24:33 2023. - - Language/Generator: C/C++ - Specification: gl - APIs: gl=3.0 - Profile: core - Extensions: - GL_ARB_buffer_storage, - GL_ARB_debug_output, - GL_ARB_sync - Loader: True - Local files: False - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="core" --api="gl=3.0" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output,GL_ARB_sync" - Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.0&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output&extensions=GL_ARB_sync -*/ - -#include -#include -#include -#include - -static void *get_proc(const char *namez); - -#if defined(_WIN32) || defined(__CYGWIN__) -# ifndef _WINDOWS_ -# undef APIENTRY -# endif -# include -static HMODULE libGL; - -typedef void *(APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char *); -static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; - -# ifdef _MSC_VER -# ifdef __has_include -# if __has_include() -# define HAVE_WINAPIFAMILY 1 -# endif -# elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ -# define HAVE_WINAPIFAMILY 1 -# endif -# endif - -# ifdef HAVE_WINAPIFAMILY -# include -# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -# define IS_UWP 1 -# endif -# endif - -static int -open_gl(void) -{ -# ifndef IS_UWP - libGL = LoadLibraryW(L"opengl32.dll"); - if (libGL != NULL) { - void (*tmp)(void); - tmp = (void (*)(void)) GetProcAddress(libGL, "wglGetProcAddress"); - gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp; - return gladGetProcAddressPtr != NULL; - } -# endif - - return 0; -} - -static void -close_gl(void) -{ - if (libGL != NULL) { - FreeLibrary((HMODULE) libGL); - libGL = NULL; - } -} -#else -# include -static void *libGL; - -# if !defined(__APPLE__) && !defined(__HAIKU__) -typedef void *(APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char *); -static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; -# endif - -static int -open_gl(void) -{ -# ifdef __APPLE__ - static const char *NAMES[] = { - "../Frameworks/OpenGL.framework/OpenGL", - "/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" - }; -# else - static const char *NAMES[] = { "libGL.so.1", "libGL.so" }; -# endif - - unsigned int index = 0; - for (index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) { - libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL); - - if (libGL != NULL) { -# if defined(__APPLE__) || defined(__HAIKU__) - return 1; -# else - gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE) dlsym(libGL, - "glXGetProcAddressARB"); - return gladGetProcAddressPtr != NULL; -# endif - } - } - - return 0; -} - -static void -close_gl(void) -{ - if (libGL != NULL) { - dlclose(libGL); - libGL = NULL; - } -} -#endif - -static void * -get_proc(const char *namez) -{ - void *result = NULL; - if (libGL == NULL) - return NULL; - -#if !defined(__APPLE__) && !defined(__HAIKU__) - if (gladGetProcAddressPtr != NULL) { - result = gladGetProcAddressPtr(namez); - } -#endif - if (result == NULL) { -#if defined(_WIN32) || defined(__CYGWIN__) - result = (void *) GetProcAddress((HMODULE) libGL, namez); -#else - result = dlsym(libGL, namez); -#endif - } - - return result; -} - -int -gladLoadGL(void) -{ - int status = 0; - - if (open_gl()) { - status = gladLoadGLLoader(&get_proc); - close_gl(); - } - - return status; -} - -struct gladGLversionStruct GLVersion = { 0, 0 }; - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -# define _GLAD_IS_SOME_NEW_VERSION 1 -#endif - -static int max_loaded_major; -static int max_loaded_minor; - -static const char *exts = NULL; -static int num_exts_i = 0; -static char **exts_i = NULL; - -static int -get_exts(void) -{ -#ifdef _GLAD_IS_SOME_NEW_VERSION - if (max_loaded_major < 3) { -#endif - exts = (const char *) glGetString(GL_EXTENSIONS); -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - unsigned int index; - - num_exts_i = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **) malloc((size_t) num_exts_i * (sizeof *exts_i)); - } - - if (exts_i == NULL) { - return 0; - } - - for (index = 0; index < (unsigned) num_exts_i; index++) { - const char *gl_str_tmp = (const char *) glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp); - - char *local_str = (char *) malloc((len + 1) * sizeof(char)); - if (local_str != NULL) { - memcpy(local_str, gl_str_tmp, (len + 1) * sizeof(char)); - } - exts_i[index] = local_str; - } - } -#endif - return 1; -} - -static void -free_exts(void) -{ - if (exts_i != NULL) { - int index; - for (index = 0; index < num_exts_i; index++) { - free((char *) exts_i[index]); - } - free((void *) exts_i); - exts_i = NULL; - } -} - -static int -has_ext(const char *ext) -{ -#ifdef _GLAD_IS_SOME_NEW_VERSION - if (max_loaded_major < 3) { -#endif - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if (extensions == NULL || ext == NULL) { - return 0; - } - - while (1) { - loc = strstr(extensions, ext); - if (loc == NULL) { - return 0; - } - - terminator = loc + strlen(ext); - if ((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - int index; - if (exts_i == NULL) - return 0; - for (index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - - if (exts_i[index] != NULL && strcmp(e, ext) == 0) { - return 1; - } - } - } -#endif - - return 0; -} -int GLAD_GL_VERSION_1_0 = 0; -int GLAD_GL_VERSION_1_1 = 0; -int GLAD_GL_VERSION_1_2 = 0; -int GLAD_GL_VERSION_1_3 = 0; -int GLAD_GL_VERSION_1_4 = 0; -int GLAD_GL_VERSION_1_5 = 0; -int GLAD_GL_VERSION_2_0 = 0; -int GLAD_GL_VERSION_2_1 = 0; -int GLAD_GL_VERSION_3_0 = 0; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -int GLAD_GL_ARB_buffer_storage = 0; -int GLAD_GL_ARB_debug_output = 0; -int GLAD_GL_ARB_sync = 0; -PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; -PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; -PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; -PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; -PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -static void -load_GL_VERSION_1_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_0) - return; - glad_glCullFace = (PFNGLCULLFACEPROC) load("glCullFace"); - glad_glFrontFace = (PFNGLFRONTFACEPROC) load("glFrontFace"); - glad_glHint = (PFNGLHINTPROC) load("glHint"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC) load("glLineWidth"); - glad_glPointSize = (PFNGLPOINTSIZEPROC) load("glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load("glPolygonMode"); - glad_glScissor = (PFNGLSCISSORPROC) load("glScissor"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load("glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load("glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load("glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load("glTexParameteriv"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load("glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load("glTexImage2D"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load("glDrawBuffer"); - glad_glClear = (PFNGLCLEARPROC) load("glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC) load("glClearColor"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load("glClearStencil"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load("glClearDepth"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC) load("glStencilMask"); - glad_glColorMask = (PFNGLCOLORMASKPROC) load("glColorMask"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC) load("glDepthMask"); - glad_glDisable = (PFNGLDISABLEPROC) load("glDisable"); - glad_glEnable = (PFNGLENABLEPROC) load("glEnable"); - glad_glFinish = (PFNGLFINISHPROC) load("glFinish"); - glad_glFlush = (PFNGLFLUSHPROC) load("glFlush"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load("glBlendFunc"); - glad_glLogicOp = (PFNGLLOGICOPPROC) load("glLogicOp"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load("glStencilFunc"); - glad_glStencilOp = (PFNGLSTENCILOPPROC) load("glStencilOp"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load("glDepthFunc"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load("glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load("glPixelStorei"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC) load("glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC) load("glReadPixels"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load("glGetBooleanv"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load("glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC) load("glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC) load("glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load("glGetIntegerv"); - glad_glGetString = (PFNGLGETSTRINGPROC) load("glGetString"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load("glGetTexImage"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load("glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load("glGetTexParameteriv"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load("glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load("glGetTexLevelParameteriv"); - glad_glIsEnabled = (PFNGLISENABLEDPROC) load("glIsEnabled"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load("glDepthRange"); - glad_glViewport = (PFNGLVIEWPORTPROC) load("glViewport"); -} -static void -load_GL_VERSION_1_1(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_1) - return; - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load("glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load("glDrawElements"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load("glPolygonOffset"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load("glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load("glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load("glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load("glCopyTexSubImage2D"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load("glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load("glTexSubImage2D"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load("glBindTexture"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load("glDeleteTextures"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC) load("glGenTextures"); - glad_glIsTexture = (PFNGLISTEXTUREPROC) load("glIsTexture"); -} -static void -load_GL_VERSION_1_2(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_2) - return; - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load("glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load("glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load("glTexSubImage3D"); - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load("glCopyTexSubImage3D"); -} -static void -load_GL_VERSION_1_3(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_3) - return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load("glActiveTexture"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load("glSampleCoverage"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load("glCompressedTexImage3D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load("glCompressedTexImage2D"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load("glCompressedTexImage1D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load("glCompressedTexSubImage3D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load("glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load("glCompressedTexSubImage1D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load("glGetCompressedTexImage"); -} -static void -load_GL_VERSION_1_4(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_4) - return; - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load("glBlendFuncSeparate"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load("glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load("glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load("glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load("glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load("glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load("glPointParameteriv"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC) load("glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load("glBlendEquation"); -} -static void -load_GL_VERSION_1_5(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_5) - return; - glad_glGenQueries = (PFNGLGENQUERIESPROC) load("glGenQueries"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load("glDeleteQueries"); - glad_glIsQuery = (PFNGLISQUERYPROC) load("glIsQuery"); - glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load("glBeginQuery"); - glad_glEndQuery = (PFNGLENDQUERYPROC) load("glEndQuery"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load("glGetQueryiv"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load("glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load("glGetQueryObjectuiv"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load("glBindBuffer"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load("glDeleteBuffers"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load("glGenBuffers"); - glad_glIsBuffer = (PFNGLISBUFFERPROC) load("glIsBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC) load("glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load("glBufferSubData"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load("glGetBufferSubData"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load("glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load("glUnmapBuffer"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load("glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load("glGetBufferPointerv"); -} -static void -load_GL_VERSION_2_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_2_0) - return; - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load("glBlendEquationSeparate"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load("glDrawBuffers"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load("glStencilOpSeparate"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load("glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load("glStencilMaskSeparate"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC) load("glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load("glBindAttribLocation"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load("glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load("glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC) load("glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load("glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC) load("glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC) load("glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load("glDisableVertexAttribArray"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load("glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load("glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load("glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load("glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load("glGetAttribLocation"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load("glGetProgramiv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load("glGetProgramInfoLog"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load("glGetShaderiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load("glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load("glGetShaderSource"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load("glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load("glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load("glGetUniformiv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load("glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load("glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load("glGetVertexAttribiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load("glGetVertexAttribPointerv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC) load("glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC) load("glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load("glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load("glShaderSource"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load("glUseProgram"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC) load("glUniform1f"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC) load("glUniform2f"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC) load("glUniform3f"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC) load("glUniform4f"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC) load("glUniform1i"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC) load("glUniform2i"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC) load("glUniform3i"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC) load("glUniform4i"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load("glUniform1fv"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load("glUniform2fv"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load("glUniform3fv"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load("glUniform4fv"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load("glUniform1iv"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load("glUniform2iv"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load("glUniform3iv"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load("glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load("glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load("glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load("glUniformMatrix4fv"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load("glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load("glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load("glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load("glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load("glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load("glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load("glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load("glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load("glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load("glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load("glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load("glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load("glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load("glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load("glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load("glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load("glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load("glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load("glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load("glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load("glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load("glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load("glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load("glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load("glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load("glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load("glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load("glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load("glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load("glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load("glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load("glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load("glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load("glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load("glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load("glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load("glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load("glVertexAttribPointer"); -} -static void -load_GL_VERSION_2_1(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_2_1) - return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load("glUniformMatrix2x3fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load("glUniformMatrix3x2fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load("glUniformMatrix2x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load("glUniformMatrix4x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load("glUniformMatrix3x4fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load("glUniformMatrix4x3fv"); -} -static void -load_GL_VERSION_3_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_3_0) - return; - glad_glColorMaski = (PFNGLCOLORMASKIPROC) load("glColorMaski"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load("glGetBooleani_v"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v"); - glad_glEnablei = (PFNGLENABLEIPROC) load("glEnablei"); - glad_glDisablei = (PFNGLDISABLEIPROC) load("glDisablei"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load("glIsEnabledi"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load("glBeginTransformFeedback"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load("glEndTransformFeedback"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load("glTransformFeedbackVaryings"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load("glGetTransformFeedbackVarying"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC) load("glClampColor"); - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load("glBeginConditionalRender"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load("glEndConditionalRender"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load("glVertexAttribIPointer"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load("glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load("glGetVertexAttribIuiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load("glVertexAttribI1i"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load("glVertexAttribI2i"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load("glVertexAttribI3i"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load("glVertexAttribI4i"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load("glVertexAttribI1ui"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load("glVertexAttribI2ui"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load("glVertexAttribI3ui"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load("glVertexAttribI4ui"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load("glVertexAttribI1iv"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load("glVertexAttribI2iv"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load("glVertexAttribI3iv"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load("glVertexAttribI4iv"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load("glVertexAttribI1uiv"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load("glVertexAttribI2uiv"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load("glVertexAttribI3uiv"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load("glVertexAttribI4uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load("glVertexAttribI4bv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load("glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load("glVertexAttribI4ubv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load("glVertexAttribI4usv"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load("glGetUniformuiv"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load("glBindFragDataLocation"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load("glGetFragDataLocation"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load("glUniform1ui"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load("glUniform2ui"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load("glUniform3ui"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load("glUniform4ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load("glUniform1uiv"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load("glUniform2uiv"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load("glUniform3uiv"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load("glUniform4uiv"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load("glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load("glTexParameterIuiv"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load("glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load("glGetTexParameterIuiv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load("glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load("glClearBufferuiv"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load("glClearBufferfv"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load("glClearBufferfi"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC) load("glGetStringi"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load("glIsRenderbuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load("glBindRenderbuffer"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load("glDeleteRenderbuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load("glGenRenderbuffers"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load("glRenderbufferStorage"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load("glGetRenderbufferParameteriv"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load("glIsFramebuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load("glBindFramebuffer"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load("glDeleteFramebuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load("glGenFramebuffers"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load("glCheckFramebufferStatus"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load("glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load("glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load("glFramebufferTexture3D"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load("glFramebufferRenderbuffer"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetFramebufferAttachmentParameteriv"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load("glGenerateMipmap"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load("glFramebufferTextureLayer"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load("glMapBufferRange"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load("glFlushMappedBufferRange"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load("glBindVertexArray"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load("glDeleteVertexArrays"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load("glGenVertexArrays"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load("glIsVertexArray"); -} -static void -load_GL_ARB_buffer_storage(GLADloadproc load) -{ - if (!GLAD_GL_ARB_buffer_storage) - return; - glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load("glBufferStorage"); -} -static void -load_GL_ARB_debug_output(GLADloadproc load) -{ - if (!GLAD_GL_ARB_debug_output) - return; - glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) load("glDebugMessageControlARB"); - glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) load("glDebugMessageInsertARB"); - glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) load("glDebugMessageCallbackARB"); - glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) load("glGetDebugMessageLogARB"); -} -static void -load_GL_ARB_sync(GLADloadproc load) -{ - if (!GLAD_GL_ARB_sync) - return; - glad_glFenceSync = (PFNGLFENCESYNCPROC) load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC) load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC) load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC) load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load("glGetSynciv"); -} -static int -find_extensionsGL(void) -{ - if (!get_exts()) - return 0; - GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage"); - GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output"); - GLAD_GL_ARB_sync = has_ext("GL_ARB_sync"); - free_exts(); - return 1; -} - -static void -find_coreGL(void) -{ - - /* Thank you @elmindreda - * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 - * https://github.com/glfw/glfw/blob/master/src/context.c#L36 - */ - int i, major, minor; - - const char *version; - const char *prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - - version = (const char *) glGetString(GL_VERSION); - if (!version) - return; - - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - -/* PR #18 */ -#ifdef _MSC_VER - sscanf_s(version, "%d.%d", &major, &minor); -#else - sscanf(version, "%d.%d", &major, &minor); -#endif - - GLVersion.major = major; - GLVersion.minor = minor; - max_loaded_major = major; - max_loaded_minor = minor; - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 0)) { - max_loaded_major = 3; - max_loaded_minor = 0; - } -} - -int -gladLoadGLLoader(GLADloadproc load) -{ - GLVersion.major = 0; - GLVersion.minor = 0; - glGetString = (PFNGLGETSTRINGPROC) load("glGetString"); - if (glGetString == NULL) - return 0; - if (glGetString(GL_VERSION) == NULL) - return 0; - find_coreGL(); - load_GL_VERSION_1_0(load); - load_GL_VERSION_1_1(load); - load_GL_VERSION_1_2(load); - load_GL_VERSION_1_3(load); - load_GL_VERSION_1_4(load); - load_GL_VERSION_1_5(load); - load_GL_VERSION_2_0(load); - load_GL_VERSION_2_1(load); - load_GL_VERSION_3_0(load); - - if (!find_extensionsGL()) - return 0; - load_GL_ARB_buffer_storage(load); - load_GL_ARB_debug_output(load); - load_GL_ARB_sync(load); - return GLVersion.major != 0 || GLVersion.minor != 0; -} diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc deleted file mode 100644 index cbda41e7e..000000000 --- a/src/win/languages/cs-CZ.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Czech (Czech Republic) resources - -#ifdef _WIN32 -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Akce" - BEGIN - MENUITEM "&Klávesnice vyžaduje záběr", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Pravý Ctrl je levý Alt", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Resetovat", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "P&ozastavit", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Ukončit", IDM_ACTION_EXIT - END - POPUP "&Zobrazení" - BEGIN - MENUITEM "&Schovat stavový řádek", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Schovat panel &nástrojů", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Měnitelná velikost okna", IDM_VID_RESIZE - MENUITEM "&Pamatovat velikost a pozici", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Zadat velikost...", IDM_VID_SPECIFY_DIM - MENUITEM "&Dodržovat poměr stran 4:3", IDM_VID_FORCE43 - POPUP "&Násobek zvětšení okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda &filtrování" - BEGIN - MENUITEM "&Nejbližší", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineární", IDM_VID_FILTER_LINEAR - END - MENUITEM "Š&kálování HiDPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Celá obrazovka\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Režím roztá&hnutí při celé obrazovce" - BEGIN - MENUITEM "&Roztáhnout", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Zachovat poměr stran", IDM_VID_FS_KEEPRATIO - MENUITEM "&Celočíselné škálování", IDM_VID_FS_INT - END - POPUP "Nastavení pro E&GA a (S)VGA" - BEGIN - MENUITEM "&Převrátit barvy", IDM_VID_INVERT - POPUP "&Typ VGA monitoru" - BEGIN - MENUITEM "RGB &barevný", IDM_VID_GRAY_RGB - MENUITEM "&Odstíny šedi", IDM_VID_GRAY_MONO - MENUITEM "&Jantarová obrazovka", IDM_VID_GRAY_AMBER - MENUITEM "&Zelená obrazovka", IDM_VID_GRAY_GREEN - MENUITEM "&Bílá obrazovka", IDM_VID_GRAY_WHITE - END - POPUP "Převod na &odstíny šedi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Průměr", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Přesah obrazu CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Upravit kontrast černobílé obrazovky", IDM_VID_CGACON - END - MENUITEM "&Média", IDM_MEDIA - POPUP "&Nástroje" - BEGIN - MENUITEM "&Nastavení...", IDM_CONFIG - MENUITEM "&Aktualizovat ikony stavového řádku", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Pořídit &screenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Předvolby...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Povolit integraci s &Discordem", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Zesílení zvuku", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Začít trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Zastavit trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "Ná&pověda" - BEGIN - MENUITEM "&Dokumentace", IDM_DOCS - MENUITEM "&O programu 86Box", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nahrávat", IDM_CASSETTE_RECORD - MENUITEM "&Přehrát", IDM_CASSETTE_PLAY - MENUITEM "Přetočit na &začátek", IDM_CASSETTE_REWIND - MENUITEM "Přetočit na &konec", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportovat do 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Ztišit", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CDROM_EMPTY - MENUITEM "&Načíst znova předchozí obraz", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Složka...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_ZIP_EJECT - MENUITEM "&Načíst znova předchozí obraz", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_MO_EJECT - MENUITEM "&Načíst znova předchozí obraz", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Cílová snímková frekvence" - BEGIN - MENUITEM "&Synchronizovat s obrazem", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Zvolit shader...", IDM_VID_GL_SHADER - MENUITEM "&Odebrat shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Předvolby" -#define STR_SND_GAIN "Zesílení zvuku" -#define STR_NEW_FLOPPY "Nový obraz" -#define STR_CONFIG "Nastavení" -#define STR_SPECIFY_DIM "Zadat rozměry hlavního okna" - -#define STR_OK "OK" -#define STR_CANCEL "Storno" -#define STR_GLOBAL "Uložit toto nastavení jako &globální výchozí stav" -#define STR_DEFAULT "&Výchozí" -#define STR_LANGUAGE "Jazyk:" -#define STR_ICONSET "Sada ikon:" - -#define STR_GAIN "Zesílení" - -#define STR_FILE_NAME "Název souboru:" -#define STR_DISK_SIZE "Velikost disku:" -#define STR_RPM_MODE "Režím ot./m:" -#define STR_PROGRESS "Průběh:" - -#define STR_WIDTH "Šířka:" -#define STR_HEIGHT "Výška:" -#define STR_LOCK_TO_SIZE "Uzamknout na tyto rozměry" - -#define STR_MACHINE_TYPE "Typ počítače:" -#define STR_MACHINE "Počítač:" -#define STR_CONFIGURE "Nastavit" -#define STR_CPU_TYPE "Procesor:" -#define STR_CPU_SPEED "Rychlost:" -#define STR_FPU "Koprocesor:" -#define STR_WAIT_STATES "Čekací stavy:" -#define STR_MB "MB" -#define STR_MEMORY "Pamět:" -#define STR_TIME_SYNC "Synchronizace času" -#define STR_DISABLED "Vypnuta" -#define STR_ENABLED_LOCAL "Zapnuta (místní čas)" -#define STR_ENABLED_UTC "Zapnuta (UTC)" -#define STR_DYNAREC "Dynamický překladač" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Grafika:" -#define STR_VIDEO_2 "Grafika 2:" -#define STR_VOODOO "Použít grafický akcelerátor Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/A" -#define STR_XGA "Grafika XGA" - -#define STR_MOUSE "Myš:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Zvuková karta 1:" -#define STR_SOUND2 "Zvuková karta 2:" -#define STR_SOUND3 "Zvuková karta 3:" -#define STR_SOUND4 "Zvuková karta 4:" -#define STR_MIDI_OUT "MIDI výstup:" -#define STR_MIDI_IN "MIDI vstup:" -#define STR_MPU401 "Samostatný MPU-401" -#define STR_FLOAT "Použít zvuk FLOAT32" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (přesnější)" -#define STR_FM_DRV_YMFM "YMFM (rychlejší)" - -#define STR_NET_TYPE "Druh sítě:" -#define STR_PCAP "PCap zařízení:" -#define STR_NET "Síťový adaptér:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Zařízení na COM1:" -#define STR_COM2 "Zařízení na COM2:" -#define STR_COM3 "Zařízení na COM3:" -#define STR_COM4 "Zařízení na COM4:" -#define STR_LPT1 "Zařízení na LPT1:" -#define STR_LPT2 "Zařízení na LPT2:" -#define STR_LPT3 "Zařízení na LPT3:" -#define STR_LPT4 "Zařízení na LPT4:" -#define STR_SERIAL1 "Povolit port COM1" -#define STR_SERIAL2 "Povolit port COM2" -#define STR_SERIAL3 "Povolit port COM3" -#define STR_SERIAL4 "Povolit port COM4" -#define STR_PARALLEL1 "Povolit port LPT1" -#define STR_PARALLEL2 "Povolit port LPT2" -#define STR_PARALLEL3 "Povolit port LPT3" -#define STR_PARALLEL4 "Povolit port LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Řadič disku:" -#define STR_FDC "Disketový řadič:" -#define STR_IDE_TER "Třetí řadič IDE" -#define STR_IDE_QUA "Čtvrtý řadič IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Řadič 1:" -#define STR_SCSI_2 "Řadič 2:" -#define STR_SCSI_3 "Řadič 3:" -#define STR_SCSI_4 "Řadič 4:" -#define STR_CASSETTE "Kazeta" - -#define STR_HDD "Pevné disky:" -#define STR_NEW "&Nový..." -#define STR_EXISTING "&Existující..." -#define STR_REMOVE "&Odebrat" -#define STR_BUS "Sběrnice:" -#define STR_CHANNEL "Kanál:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Zadat..." -#define STR_SECTORS "Sektory:" -#define STR_HEADS "Hlavy:" -#define STR_CYLS "Cylindry:" -#define STR_SIZE_MB "Velikost (MB):" -#define STR_TYPE "Typ:" -#define STR_IMG_FORMAT "Formát obrazu:" -#define STR_BLOCK_SIZE "Velikost bloků:" - -#define STR_FLOPPY_DRIVES "Disketové mechaniky:" -#define STR_TURBO "Turbo časování" -#define STR_CHECKBPB "Kontrola BPB" -#define STR_CDROM_DRIVES "Mechaniky CD-ROM:" -#define STR_CD_SPEED "Rychlost:" - -#define STR_MO_DRIVES "Magnetooptické mechaniky:" -#define STR_ZIP_DRIVES "Mechaniky ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA hodiny:" -#define STR_ISAMEM "ISA rozšíření paměti" -#define STR_ISAMEM_1 "Karta 1:" -#define STR_ISAMEM_2 "Karta 2:" -#define STR_ISAMEM_3 "Karta 3:" -#define STR_ISAMEM_4 "Karta 4:" -#define STR_BUGGER "Zařízení ISABugger" -#define STR_POSTCARD "Karta pro kódy POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Chyba" - IDS_2050 "Kritická chyba" - IDS_2051 " - PAUSED" - IDS_2052 "Stiskněte Ctrl+Alt+PgDn pro návrat z režimu celé obrazovky." - IDS_2053 "Rychlost" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Obrazy ZIP disků (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nenalezl žádné použitelné image pamětí ROM.\n\nStáhněte sadu obrazů ROM a extrahujte ji do složky ""roms""." - IDS_2057 "(prázdné)" - IDS_2058 "Obrazy ZIP disků (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Zap." - IDS_2061 "Vyp." - IDS_2062 "Všechny obrazy disků (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Základní sektorové obrazy (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Obrazy povrchu (*.86F)\0*.86F\0" - IDS_2063 "Počítač ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/machines"". Konfigurace se přepne na jiný dostupný počítač." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video adaptér ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/video"". Konfigurace se přepne na jiný dostupný adaptér." - IDS_2065 "Počítač" - IDS_2066 "Obraz" - IDS_2067 "Vstupní zařízení" - IDS_2068 "Zvuk" - IDS_2069 "Síť" - IDS_2070 "COM a LPT porty" - IDS_2071 "Řadiče úložiště" - IDS_2072 "Pevné disky" - IDS_2073 "Disketové a CD-ROM mechaniky" - IDS_2074 "Další vyměnitelná zařízení" - IDS_2075 "Jiné příslušenství" - IDS_2076 "Obrazy povrchu (*.86F)\0*.86F\0" - IDS_2077 "Klikněte pro zabraní myši" - IDS_2078 "Stiskněte F8+F12 pro uvolnění myši" - IDS_2079 "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Sběrnice" - IDS_2082 "Soubor" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Kontrola BPB" - IDS_2089 "KB" - IDS_2090 "Nastala chyba při inicializaci video rendereru." - IDS_2091 "Výchozí" - IDS_2092 "%i čekací stav(y)" - IDS_2093 "Typ" - IDS_2094 "Nastala chyba při inicializaci knihovny PCap" - IDS_2095 "Nebyla nalezena žádná PCap zařízení" - IDS_2096 "Neplatné PCap zařízení" - IDS_2097 "Standardní 2tlačítkový joystick" - IDS_2098 "Standardní 4tlačítkový joystick" - IDS_2099 "Standardní 6tlačítkový joystick" - IDS_2100 "Standardní 8tlačítkový joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Žadné" - IDS_2105 "Nebylo možné nahrát klávesnicové zkratky." - IDS_2106 "Nebylo možné zaregistrovat raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketová mechanika %i (%s): %ls" - IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" - IDS_2114 "Opravdu chcete ukončit 86Box?" - IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2118 "Vítejte v programu 86Box!" - IDS_2119 "Vestavěný řadič" - IDS_2120 "Ukončit" - IDS_2121 "Nebyly nalezeny žádné obrazy ROM" - IDS_2122 "Chcete uložit nastavení?" - IDS_2123 "Pokračováním se resetuje emulovaný počítač." - IDS_2124 "Uložit" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." - IDS_2128 "OK" - IDS_2129 "Hardware není dostupný" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Ujistěte se, že je nainstalován " LIB_NAME_PCAP " a používáte síťové připojení s ním kompatibilní." - IDS_2131 "Neplatná konfigurace" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." - IDS_2135 "Vstup do režimu celé obrazovky" - IDS_2136 "Nezobrazovat dále tuto zprávu" - IDS_2137 "Neukončovat" - IDS_2138 "Resetovat" - IDS_2139 "Neresetovat" - IDS_2140 "Obraz magnetooptického disku (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2141 "Obraz CD-ROM disku (*.ISO;*.CUE)\0*.ISO;*.CUE\0Všechny soubory (*.*)\0*.*\0" - IDS_2142 "Konfigurace zařízení %hs" - IDS_2143 "Monitor je v režimu spánku" - IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "Možnosti OpenGL" - IDS_2146 "Pokoušíte se spustit nepodporovanou konfiguraci" - IDS_2147 "Pro tuto konfiguraci bylo vypnuto filtrování procesorů podle zvoleného počítače.\n\nToto umožňuje zvolit procesor, který by jinak se zvoleným počítačem nebyl kompatibilní. Můžou však nastat potíže s BIOSem nebo jiným softwarem.\n\nPovolení tohoto nastavení není oficiálně podporováno a jakákoliv hlášení o chybách mohou být uzavřeny jako neplatné." - IDS_2148 "Pokračovat" - IDS_2149 "Kazeta: %s" - IDS_2150 "Kazetové nahrávky (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Všechny soubory (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Obrazy cartridge (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Všechny soubory (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Obnovit" - IDS_2156 "Pozastavit" - IDS_2157 "Stisknout Ctrl+Alt+Delete" - IDS_2158 "Stisknout Ctrl+Alt+Esc" - IDS_2159 "Resetovat" - IDS_2160 "Vypnout skrze rozhraní ACPI" - IDS_2161 "Nastavení" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Pevný disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "CD-ROM mechaniky pro rozhraní MFM/RLL nebo ESDI nikdy neexistovaly" - IDS_4100 "Vlastní..." - IDS_4101 "Vlastní (velký)..." - IDS_4102 "Přidat nový pevný disk" - IDS_4103 "Přidat existující pevný disk" - IDS_4104 "Obraz disku formátu HDI nemůžou být větší než 4 GB." - IDS_4105 "Obraz disku nemůžou být větší než 127 GB." - IDS_4106 "Obrazy pevného disku (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Všechny soubory (*.*)\0*.*\0" - IDS_4107 "Nebylo možné přečíst soubor" - IDS_4108 "Nebylo možné zapisovat do souboru" - IDS_4109 "Obraz disku ve formátu HDI nebo HDX s velikostí sektoru jinou než 512 bajtů nejsou podporovány." - IDS_4110 "USB zatím není podporováno." - IDS_4111 "Soubor obrazu disku již existuje" - IDS_4112 "Zadejte platný název souboru." - IDS_4113 "Obraz disku byl vytvořen" - IDS_4114 "Ujistěte se, že soubor existuje a lze jej přečíst." - IDS_4115 "Ujistěte se, že se do složky, kde se má soubor uložit, dá zapisovat." - IDS_4116 "Obraz disku je příliš velký" - IDS_4117 "Nezapomeňte nově vytvořený disk rozdělit a naformátovat." - IDS_4118 "Zvolený soubor bude přepsán. Opravdu jej chcete použít?" - IDS_4119 "Nepodporovaný obraz disku" - IDS_4120 "Přepsat" - IDS_4121 "Nepřepisovat" - IDS_4122 "Surový obraz (.img)" - IDS_4123 "HDI obraz (.hdi)" - IDS_4124 "HDX obraz (.hdx)" - IDS_4125 "VHD s pevnou velikostí (.vhd)" - IDS_4126 "VHD s dynamickou velikostí (.vhd)" - IDS_4127 "Rozdílový VHD (.vhd)" - IDS_4128 "Velké bloky (2 MB)" - IDS_4129 "Malé bloky (512 KB)" - IDS_4130 "Soubory VHD (*.VHD)\0*.VHD\0Všechny soubory (*.*)\0*.*\0" - IDS_4131 "Vyberte nadřazený virtuální disk" - IDS_4132 "To může znamenat, že se obsahy nadřazeného disku změnily po vytvoření rozdílového disku.\n\nTato chyba také může nastat, pokud byl obraz disku kopírován nebo přesunut, nebo kvůli chybě v programu, který jej vytvořil.\n\nChcete časová razítka opravit?" - IDS_4133 "Časová razítka nadřazeného a podřazeného disku nesouhlasí" - IDS_4134 "Nebylo možné opravit časové razítko VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Vypnuto" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Vypnuto" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Dokonalé otáčky za minutu" - IDS_6145 "1% pod dokonalými ot./m" - IDS_6146 "1.5% pod dokonalými ot./m" - IDS_6147 "2% pod dokonalými ot./m" - - IDS_7168 "(Výchozí nastavení systému)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Czech (Czech Republic) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc deleted file mode 100644 index 9859d3d26..000000000 --- a/src/win/languages/de-DE.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// German (de-DE) resources - -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Aktionen" - BEGIN - MENUITEM "&Tastatur benötigt das Einfangen des Mauszeigers", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Die rechte Strg-Taste ist die Linke Alt-Taste", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard-Reset...", IDM_ACTION_HRESET - MENUITEM "&Strg+Alt+Entf\tStrg+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Strg+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Be&enden...", IDM_ACTION_EXIT - END - POPUP "&Ansicht" - BEGIN - MENUITEM "&Statusleiste ausblenden", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Werkzeugleiste ausblenden", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Größenverstellbares Fenster", IDM_VID_RESIZE - MENUITEM "&Größe && Position merken", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0-Kern)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Fenstergröße einstellen...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3-Seitenverhältnis erzwingen", IDM_VID_FORCE43 - POPUP "&Fensterskalierungsfaktor" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filteringmethode" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI-Skalierung", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Vollbild\tStrg+Alt+Bild auf", IDM_VID_FULLSCREEN - POPUP "&Stretching-Modus im Vollbildmodus" - BEGIN - MENUITEM "&Vollbild-Stretching", IDM_VID_FS_FULL - MENUITEM "&4:3-Seitenverhältnis erzwingen", IDM_VID_FS_43 - MENUITEM "&Quadratische Pixel (Seitenverhältnis beibehalten)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer-Skalierung", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA-Einstellungen" - BEGIN - MENUITEM "&Invertierte VGA-Anzeige", IDM_VID_INVERT - POPUP "&VGA-Bildschirmtyp" - BEGIN - MENUITEM "&RGB-Farbe", IDM_VID_GRAY_RGB - MENUITEM "&RGB-Graustufen", IDM_VID_GRAY_MONO - MENUITEM "&Bernstein-Monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Grüner Monitor", IDM_VID_GRAY_GREEN - MENUITEM "&Weißer Monitor", IDM_VID_GRAY_WHITE - END - POPUP "Methode zur &Graustufenkonversion" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Durchschnittsmethode", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan für CGA/PCjr/Tandy/E&GA/(S)VGA-Displays", IDM_VID_OVERSCAN - MENUITEM "Kontrast für &monochrome Displays ändern", IDM_VID_CGACON - END - MENUITEM "&Medien", IDM_MEDIA - POPUP "&Werkzeuge" - BEGIN - MENUITEM "&Optionen...", IDM_CONFIG - MENUITEM "&Statusleistenicons aktualisieren", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "S&creenshot aufnehmen\tStrg+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Einstellungen...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord-Integration aktivieren", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Klangverstärkung...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Tracing starten\tStrg+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Tracing beenden\tStrg+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Hilfe" - BEGIN - MENUITEM "&Dokumentation...", IDM_DOCS - MENUITEM "&Über 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Aufnehmen", IDM_CASSETTE_RECORD - MENUITEM "&Abspielen", IDM_CASSETTE_PLAY - MENUITEM "&An den Anfang zurückspulen", IDM_CASSETTE_REWIND - MENUITEM "&An das Ende vorspulen", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Cartridgeimage...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&In das 86F-Format e&xportieren...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Auswerfen", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Stummschalten", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "L&eer", IDM_CDROM_EMPTY - MENUITEM "&Voriges Image neu laden", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Verzeichnis...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_ZIP_EJECT - MENUITEM "&Voriges Image neu laden", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Auswerfen", IDM_MO_EJECT - MENUITEM "&Bestehendes Image erneut laden", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Ziel&framerate" - BEGIN - MENUITEM "&Mit Videoausgabe synchronisieren", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Shader auswählen...", IDM_VID_GL_SHADER - MENUITEM "&Shader entfernen", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Einstellungen" -#define STR_SND_GAIN "Klangverstärkung" -#define STR_NEW_FLOPPY "Neues Image" -#define STR_CONFIG "Optionen" -#define STR_SPECIFY_DIM "Fenstergröße einstellen" - -#define STR_OK "OK" -#define STR_CANCEL "Abbrechen" -#define STR_GLOBAL "Einstellungen als &globalen Standard speichern" -#define STR_DEFAULT "&Standard" -#define STR_LANGUAGE "Sprache:" -#define STR_ICONSET "Icon-Satz:" - -#define STR_GAIN "Verstärkung" - -#define STR_FILE_NAME "Dateiname:" -#define STR_DISK_SIZE "Plattengröße:" -#define STR_RPM_MODE "Drehzahlmodus:" -#define STR_PROGRESS "Fortschritt:" - -#define STR_WIDTH "Breite:" -#define STR_HEIGHT "Höhe:" -#define STR_LOCK_TO_SIZE "Feste Größe" - -#define STR_MACHINE_TYPE "Systemtyp:" -#define STR_MACHINE "System:" -#define STR_CONFIGURE "Einstellen" -#define STR_CPU_TYPE "CPU-Typ:" -#define STR_CPU_SPEED "Takt:" -#define STR_FPU "FPU-Einheit:" -#define STR_WAIT_STATES "Wartezustände:" -#define STR_MB "MB" -#define STR_MEMORY "Hauptspeicher:" -#define STR_TIME_SYNC "Zeitsynchronisierung" -#define STR_DISABLED "Deaktiviert" -#define STR_ENABLED_LOCAL "Aktiviert (Lokale Uhrzeit)" -#define STR_ENABLED_UTC "Aktiviert (UTC)" -#define STR_DYNAREC "Dynamischer Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Videokarte:" -#define STR_VIDEO_2 "Videokarte 2:" -#define STR_VOODOO "Voodoo-Grafik" -#define STR_IBM8514 "IBM 8514/A-Grafik" -#define STR_XGA "XGA-Grafik" - -#define STR_MOUSE "Maus:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Soundkarte 1:" -#define STR_SOUND2 "Soundkarte 2:" -#define STR_SOUND3 "Soundkarte 3:" -#define STR_SOUND4 "Soundkarte 4:" -#define STR_MIDI_OUT "MIDI Out-Gerät:" -#define STR_MIDI_IN "MIDI In-Gerät:" -#define STR_MPU401 "Standalone-MPU-401-Gerät" -#define STR_FLOAT "FLOAT32-Wiedergabe benutzen" -#define STR_FM_DRIVER "FM-Synth-Treiber" -#define STR_FM_DRV_NUKED "Nuked (genauer)" -#define STR_FM_DRV_YMFM "YMFM (schneller)" - -#define STR_NET_TYPE "Netzwerktyp:" -#define STR_PCAP "PCap-Gerät:" -#define STR_NET "Netzwerkadapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1-Gerät:" -#define STR_COM2 "COM2-Gerät:" -#define STR_COM3 "COM3-Gerät:" -#define STR_COM4 "COM4-Gerät:" -#define STR_LPT1 "LPT1-Gerät:" -#define STR_LPT2 "LPT2-Gerät:" -#define STR_LPT3 "LPT3-Gerät:" -#define STR_LPT4 "LPT4-Gerät:" -#define STR_SERIAL1 "Serielle Schnittstelle 1" -#define STR_SERIAL2 "Serielle Schnittstelle 2" -#define STR_SERIAL3 "Serielle Schnittstelle 3" -#define STR_SERIAL4 "Serielle Schnittstelle 4" -#define STR_PARALLEL1 "Parallelport 1" -#define STR_PARALLEL2 "Parallelport 2" -#define STR_PARALLEL3 "Parallelport 3" -#define STR_PARALLEL4 "Parallelport 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HDD-Controller:" -#define STR_FDC "FD-Controller:" -#define STR_IDE_TER "Tertiärer IDE-Controller" -#define STR_IDE_QUA "Quartärer IDE-Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Kassette" - -#define STR_HDD "Festplatten:" -#define STR_NEW "&Neu..." -#define STR_EXISTING "&Vorhanden..." -#define STR_REMOVE "&Entfernen" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Festlegen..." -#define STR_SECTORS "Sektoren:" -#define STR_HEADS "Köpfe:" -#define STR_CYLS "Zylinder:" -#define STR_SIZE_MB "Größe (MB):" -#define STR_TYPE "Typ:" -#define STR_IMG_FORMAT "Imageformat:" -#define STR_BLOCK_SIZE "Blockgröße:" - -#define STR_FLOPPY_DRIVES "Diskettenlaufwerke:" -#define STR_TURBO "Turbo-Timings" -#define STR_CHECKBPB "BPB überprüfen" -#define STR_CDROM_DRIVES "CD-ROM-Laufwerke:" -#define STR_CD_SPEED "Geschwindigkeit:" - -#define STR_MO_DRIVES "MO-Laufwerke:" -#define STR_ZIP_DRIVES "ZIP-Laufwerke:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA-Echtzeituhr:" -#define STR_ISAMEM "ISA-Speichererweiterung:" -#define STR_ISAMEM_1 "Steckkarte 1:" -#define STR_ISAMEM_2 "Steckkarte 2:" -#define STR_ISAMEM_3 "Steckkarte 3:" -#define STR_ISAMEM_4 "Steckkarte 4:" -#define STR_BUGGER "ISABugger-Gerät" -#define STR_POSTCARD "POST-Code-Karte" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Fehler" - IDS_2050 "Fataler Fehler" - IDS_2051 " - PAUSED" - IDS_2052 "Bitte Strg+Alt+Bild ab zur Rückkehr in den Fenstermodus drücken." - IDS_2053 "Geschwindigkeit" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-Images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box konnte keine nutzbaren ROM-Dateien finden.\n\nBitte besuchen Sie download, laden ein ROM-Set herunter und extrahieren dies in das ""roms""-Verzeichnis." - IDS_2057 "(leer)" - IDS_2058 "ZIP-Images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "An" - IDS_2061 "Aus" - IDS_2062 "Alle Images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basissektorimages (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Oberflächenimages (*.86F)\0*.86F\0" - IDS_2063 "Das System ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/machines nicht verfügbar. Es wird auf ein verfügbares System gewechselt." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Die Videokarte ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird auf eine verfügbare Videokarte gewechselt." - IDS_2065 "System" - IDS_2066 "Anzeige" - IDS_2067 "Eingabegeräte" - IDS_2068 "Multimedia" - IDS_2069 "Netzwerk" - IDS_2070 "Anschlüsse (COM & LPT)" - IDS_2071 "Speichercontroller" - IDS_2072 "Festplatten" - IDS_2073 "Disketten- & CD-ROM-Laufwerke" - IDS_2074 "Andere Wechsellaufwerke" - IDS_2075 "Andere Peripheriegeräte" - IDS_2076 "Oberflächenimages (*.86F)\0*.86F\0" - IDS_2077 "Zum Einfangen des Mauszeigers bitte klicken" - IDS_2078 "Bitte F8+F12 zur Mausfreigabe drücken" - IDS_2079 "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Datei" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB prüfen" - IDS_2089 "KB" - IDS_2090 "Der Videorenderer konnte nicht initialisiert werden." - IDS_2091 "Standard" - IDS_2092 "%i Wartezustände" - IDS_2093 "Typ" - IDS_2094 "PCap konnte nicht eingerichtet werden" - IDS_2095 "Keine PCap-Geräte gefunden" - IDS_2096 "Ungültiges PCap-Gerät" - IDS_2097 "Standard 2-Tasten-Joystick(s)" - IDS_2098 "Standard 4-Tasten-Joystick" - IDS_2099 "Standard 6-Tasten-Joystick" - IDS_2100 "Standard 8-Tasten-Joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ohne" - IDS_2105 "Tastaturbeschleuniger konnten nicht geladen werden." - IDS_2106 "Roheingaben konnten nicht registriert werden." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Diskette %i (%s): %ls" - IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" - IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" - IDS_2115 "Ghostscript konnte nicht initialisiert werden" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2118 "Willkommen bei 86Box!" - IDS_2119 "Interner Controller" - IDS_2120 "Beenden" - IDS_2121 "Keine ROMs gefunden" - IDS_2122 "Möchten Sie die Einstellungen speichern?" - IDS_2123 "Dies wird zu einem Hard-Reset des emulierten Systems führen." - IDS_2124 "Speichern" - IDS_2125 "Über 86Box" - IDS_2126 "86Box Version " EMU_VERSION - - IDS_2127 "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." - IDS_2128 "OK" - IDS_2129 "Hardware nicht verfügbar" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Bitte stellen Sie sicher, dass " LIB_NAME_PCAP " installiert ist und sie eine " LIB_NAME_PCAP "-kompatible Netzwerkverbindung nutzen." - IDS_2131 "Ungültige Konfiguration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." - IDS_2135 "Vollbildmodus wird aktiviert" - IDS_2136 "Diese Nachricht nicht mehr anzeigen" - IDS_2137 "Nicht beenden" - IDS_2138 "Zurücksetzen" - IDS_2139 "Nicht zurücksetzen" - IDS_2140 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2141 "CD-ROM-Images (*.ISO;*.CUE)\0*.ISO;*.CUE\0Alle Dateien (*.*)\0*.*\0" - IDS_2142 "%hs-Gerätekonfiguration" - IDS_2143 "Monitor im Standbymodus" - IDS_2144 "OpenGL-Shader (*.GLSL)\0*.GLSL\0Alle Dateien (*.*)\0*.*\0" - IDS_2145 "OpenGL-Optionen" - IDS_2146 "Sie laden gerade eine nicht unterstützte Konfiguration" - IDS_2147 "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als ""invalid"" geschlossen werden." - IDS_2148 "Fortfahren" - IDS_2149 "Kassette: %s" - IDS_2150 "Kassettenimages (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Alle Dateien (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridgeimages (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Alle Dateien (*.*)\0*.*\0" - IDS_2153 "Fehler bei der Rendererinitialisierung" - IDS_2154 "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." - IDS_2155 "Fortsetzen" - IDS_2156 "Pausieren" - IDS_2157 "Strg+Alt+Entf drücken" - IDS_2158 "Strg+Alt+Esc drücken" - IDS_2159 "Hard-Reset" - IDS_2160 "ACPI-basiertes Herunterfahren" - IDS_2161 "Optionen" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Festplatte (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" - IDS_4100 "Angepasst..." - IDS_4101 "Angepasst (Groß)..." - IDS_4102 "Neue Festplatte hinzufügen" - IDS_4103 "Bestehende Festplatte hinzufügen" - IDS_4104 "HDI-Diskimages können nicht größer als 4 GB groß sein." - IDS_4105 "Festplattenimages können nicht größer als 127 GB groß sein." - IDS_4106 "Festplattenimages (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Alle Dateien (*.*)\0*.*\0" - IDS_4107 "Die Datei konnte nicht gelesen werden" - IDS_4108 "Die Datei konnte nicht beschrieben werden" - IDS_4109 "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." - IDS_4110 "USB wird noch nicht unterstützt" - IDS_4111 "Die Festplattenimagedatei existiert bereits" - IDS_4112 "Bitte geben Sie einen gültigen Dateinamen ein." - IDS_4113 "Disk-Image wurde erstellt" - IDS_4114 "Bitte stellen Sie sicher, dass die Datei existiert und lesbar ist." - IDS_4115 "Bitte stellen Sie sicher, dass die Datei in ein Verzeichnis mit Schreibberechtigungen gespeichert wird." - IDS_4116 "Festplattenimage ist zu groß" - IDS_4117 "Bitte denken Sie an das Partitionieren und Formatieren des neu erstellten Laufwerks." - IDS_4118 "Die ausgewählte Datei wird überschrieben. Möchten Sie diese Datei nutzen?" - IDS_4119 "Nicht unterstütztes Festplattenimage" - IDS_4120 "Überschreiben" - IDS_4121 "Nicht überschreiben" - IDS_4122 "Rohdatenimages (.img)" - IDS_4123 "HDI-Images (.hdi)" - IDS_4124 "HDX-Images (.hdx)" - IDS_4125 "VHD mit fester Größe (.vhd)" - IDS_4126 "VHD mit dynamischer Größe (.vhd)" - IDS_4127 "Differenzierende VHD (.vhd)" - IDS_4128 "Große Blöcke (2 MB)" - IDS_4129 "Kleine Blöcke (512 KB)" - IDS_4130 "VHD-Dateien (*.VHD)\0*.VHD\0Alle Dateien (*.*)\0*.*\0" - IDS_4131 "Eltern-VHD-Datei bitte auswählen" - IDS_4132 "Dies bedeutet, dass das Elternimage nach der Erstellung des differenzierenden Images erzeugt wurde.\n\nDies kann auch passieren, falls die Image-Dateien verschoben oder kopiert wurden. Ebenso kann auch dies durch einen Bug im Programm, welches das Image erstellt hat, passieren.\n\nMöchten Sie die Zeitstempel korrigieren?" - IDS_4133 "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" - IDS_4134 "Der Zeitstempel der VHD konnte nicht korrigiert werden." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deaktiviert" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deaktiviert" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (1024 Cluster)" - IDS_5898 "DMF (2048 Cluster)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3,5-Zoll 128 MB (ISO 10090)" - IDS_5903 "3,5-Zoll 230 MB (ISO 13963)" - IDS_5904 "3,5-Zoll 540 MB (ISO 15498)" - IDS_5905 "3,5-Zoll 640 MB (ISO 15498)" - IDS_5906 "3,5-Zoll 1,3 GB (GigaMO)" - IDS_5907 "3,5-Zoll 2,3 GB (GigaMO 2)" - IDS_5908 "5,25-Zoll 600 MB" - IDS_5909 "5,25-Zoll 650 MB" - IDS_5910 "5,25-Zoll 1 GB" - IDS_5911 "5,25-Zoll 1,3 GB" - - IDS_6144 "Perfekte Drehzahl" - IDS_6145 "1% unterhalb der perfekten Drehzahl" - IDS_6146 "1,5% unterhalb der perfekten Drehzahl" - IDS_6147 "2% unterhalb der perfekten Drehzahl" - - IDS_7168 "(Systemstandard)" -END -#define IDS_LANG_ENUS IDS_7168 - -// German (de-DE) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc deleted file mode 100644 index 1daf46b4c..000000000 --- a/src/win/languages/dialogs.rc +++ /dev/null @@ -1,1143 +0,0 @@ -#define CFG_CHECKBOX_PRI_WIDTH 94 -#define CFG_CHECKBOX_HEIGHT 10 -#define CFG_BTN_WIDTH 46 -#define CFG_BTN_HEIGHT 14 -#define CFG_PANE_LTEXT_PRI_WIDTH 85 -#define CFG_PANE_LTEXT_PRI_WIDTH_2 170 -#define CFG_PANE_LTEXT_PRI_WIDTH_3 255 -#define CFG_PANE_LTEXT_HEIGHT 10 -#define CFG_COMBO_BTN_WIDTH 212 -#define CFG_COMBO_NOBTN_WIDTH CFG_COMBO_BTN_WIDTH + CFG_BTN_WIDTH + 8 -#define CFG_COMBO_BOX_LEFT CFG_PANE_LTEXT_PRI_WIDTH + 10 -#define CFG_COMBO_BTN_LEFT CFG_COMBO_BOX_LEFT + CFG_COMBO_BTN_WIDTH + 8 -#define CFG_COMBO_HEIGHT 120 -#define CFG_LIST_WIDTH 123 -#define CFG_LIST_HEIGHT 212 -#define CFG_PANE_TOP 0 -#define CFG_PANE_LEFT CFG_LIST_WIDTH + 8 -#define CFG_PANE_WIDTH CFG_COMBO_BOX_LEFT + CFG_COMBO_NOBTN_WIDTH -#define CFG_PANE_HEIGHT 221 -#define CFG_HMARGIN 7 -#define CFG_VMARGIN 9 -#define CFG_SYSLISTVIEW32_WIDTH CFG_PANE_WIDTH - 7 - -DLG_PREFERENCES DIALOG DISCARDABLE 0, 0, 240, 118 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_PREFERENCES -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 123, 97, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 179, 97, 50, CFG_BTN_HEIGHT - - LTEXT STR_LANGUAGE, - 2000, 13, 8, 100, 8 - COMBOBOX IDC_COMBO_LANG, - 13, 18, 213, 22, - CBS_DROPDOWNLIST | CBS_HASSTRINGS - PUSHBUTTON STR_DEFAULT, IDC_BUTTON_DEFAULT, - 162, 32, 60, CFG_BTN_HEIGHT - - LTEXT STR_ICONSET, - 2001, 13, 40, 100, 8 - COMBOBOX IDC_COMBO_ICON, - 13, 50, 213, 22, - CBS_DROPDOWNLIST | CBS_HASSTRINGS - PUSHBUTTON STR_DEFAULT, IDC_BUTTON_DEFICON, - 162, 64, 60, CFG_BTN_HEIGHT - - AUTOCHECKBOX STR_GLOBAL, IDC_CHECKBOX_GLOBAL, - 13, 82, 217, 8, - WS_DISABLED -END - -DLG_SND_GAIN DIALOG DISCARDABLE 0, 0, 113, 136 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_SND_GAIN -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 57, 7, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 57, 24, 50, CFG_BTN_HEIGHT - - CONTROL STR_GAIN, IDC_SLIDER_GAIN, - "msctls_trackbar32", - TBS_VERT | TBS_BOTH | TBS_AUTOTICKS | WS_TABSTOP, - 15, 20, 20, 109 - CTEXT STR_GAIN,IDT_GAIN, - 10, 7, 32, 9, - SS_CENTERIMAGE -END - -DLG_NEW_FLOPPY DIALOG DISCARDABLE 0, 0, 226, 86 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_NEW_FLOPPY -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 104, 65, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 162, 65, 50, CFG_BTN_HEIGHT - - LTEXT STR_FILE_NAME, IDT_FLP_FILE_NAME, - 7, 6, 44, 12, - SS_CENTERIMAGE - EDITTEXT IDC_EDIT_FILE_NAME, - 53, 5, 150, 14, - ES_AUTOHSCROLL | ES_READONLY - - LTEXT STR_DISK_SIZE, IDT_FLP_DISK_SIZE, - 7, 25, 44, 12, - SS_CENTERIMAGE - COMBOBOX IDC_COMBO_DISK_SIZE, - 53, 25, 166, 14, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "...", IDC_CFILE, - 206, 5, 13, CFG_BTN_HEIGHT - - LTEXT STR_RPM_MODE, IDT_FLP_RPM_MODE, - 7, 45, 44, 12, - SS_CENTERIMAGE - COMBOBOX IDC_COMBO_RPM_MODE, - 53, 45, 166, 14, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_PROGRESS, IDT_FLP_PROGRESS, - 7, 45, 44, 12, - SS_CENTERIMAGE - CONTROL "IMGCreateProgress", IDC_PBAR_IMG_CREATE, - "msctls_progress32", - PBS_SMOOTH | WS_BORDER, - 53, 45, 166, 14 -END - -DLG_SPECIFY_DIM DIALOG DISCARDABLE 0, 0, 175, 66 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_SPECIFY_DIM -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_WIDTH, IDT_WIDTH, - 7, 9, 24, 12 - EDITTEXT IDC_EDIT_WIDTH, - 33, 7, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_WIDTHSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 76, 6, 12, 12 - - LTEXT STR_HEIGHT, IDT_HEIGHT, - 97, 9, 24, 12 - EDITTEXT IDC_EDIT_HEIGHT, - 123, 7, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_HEIGHTSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 166, 6, 12, 12 - - CONTROL STR_LOCK_TO_SIZE,IDC_CHECK_LOCK_SIZE, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 7, 26, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - DEFPUSHBUTTON STR_OK,IDOK, - 30, 45, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 99, 45, 50, CFG_BTN_HEIGHT -END - -DLG_CONFIG DIALOG DISCARDABLE 0, 0, CFG_LIST_WIDTH + CFG_PANE_WIDTH + 18, 256 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_CONFIG -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - CFG_LIST_WIDTH + CFG_PANE_WIDTH - 108, 235, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - CFG_LIST_WIDTH + CFG_PANE_WIDTH - 48 , 235, 50, CFG_BTN_HEIGHT - - CONTROL "List2", IDC_SETTINGSCATLIST, - "SysListView32", - LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, CFG_VMARGIN, CFG_LIST_WIDTH, CFG_LIST_HEIGHT - - CONTROL "",-1, - "Static", SS_BLACKFRAME | SS_SUNKEN, - 1, 226, CFG_LIST_WIDTH + CFG_PANE_WIDTH + 16, 1 -END - -DLG_CFG_MACHINE DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_MACHINE_TYPE,IDT_MACHINE_TYPE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MACHINE_TYPE, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_MACHINE, IDT_MACHINE, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MACHINE, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MACHINE, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_CPU_TYPE, IDT_CPU_TYPE, - CFG_HMARGIN, 47, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CPU_TYPE, - CFG_COMBO_BOX_LEFT, 45, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CPU_SPEED, IDT_CPU_SPEED, - 216, 47, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CPU_SPEED, - 252, 45, 109, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_FPU,IDT_FPU, - CFG_HMARGIN, 66, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FPU, - CFG_COMBO_BOX_LEFT, 64, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_WAIT_STATES, IDT_WAIT_STATES, - CFG_HMARGIN, 85, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_WS, - CFG_COMBO_BOX_LEFT, 83, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_MEMORY, IDT_MEMORY, - CFG_HMARGIN, 104, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - EDITTEXT IDC_MEMTEXT, - CFG_COMBO_BOX_LEFT, 102, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "", IDC_MEMSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 138, 101, 12, 12 - LTEXT STR_MB, IDT_MB, - 148, 104, 12, CFG_PANE_LTEXT_HEIGHT - -#ifdef USE_DYNAREC - CONTROL STR_DYNAREC, IDC_CHECK_DYNAREC, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 120, 120, CFG_CHECKBOX_HEIGHT -#endif - - CONTROL STR_SOFTFLOAT, IDC_CHECK_SOFTFLOAT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 135, 120, CFG_CHECKBOX_HEIGHT - - - GROUPBOX STR_TIME_SYNC, IDC_TIME_SYNC, - CFG_HMARGIN, 150, 110, 56 - - CONTROL STR_DISABLED, IDC_RADIO_TS_DISABLED, - "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, - 14, 162, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_ENABLED_LOCAL, IDC_RADIO_TS_LOCAL, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 176, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_ENABLED_UTC, IDC_RADIO_TS_UTC, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 190, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_VIDEO DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_VIDEO, IDT_VIDEO, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_VIDEO, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_VIDEO_2, IDT_VIDEO_2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_VIDEO_2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID_2, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_VOODOO, IDC_CHECK_VOODOO, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 47, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_VOODOO, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IBM8514, IDC_CHECK_IBM8514, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 66, 199, CFG_CHECKBOX_HEIGHT - - CONTROL STR_XGA, IDC_CHECK_XGA, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 85, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA, - CFG_COMBO_BTN_LEFT, 84, CFG_BTN_WIDTH, CFG_BTN_HEIGHT -END - -DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_MOUSE, IDT_MOUSE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MOUSE, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MOUSE, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_JOYSTICK, IDT_JOYSTICK, - CFG_HMARGIN, 27, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_JOYSTICK, - CFG_COMBO_BOX_LEFT, 25, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - PUSHBUTTON STR_JOY1, IDC_JOY1, - CFG_HMARGIN, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY2, IDC_JOY2, - 96, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY3, IDC_JOY3, - 187, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY4, IDC_JOY4, - 277, 44, 84, CFG_BTN_HEIGHT -END - -DLG_CFG_SOUND DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_SOUND1, IDT_SOUND1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND1, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND2, IDT_SOUND2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND2, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND3, IDT_SOUND3, - CFG_HMARGIN, 48, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND3, - CFG_COMBO_BOX_LEFT, 46, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND3, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND4, IDT_SOUND4, - CFG_HMARGIN, 68, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND4, - CFG_COMBO_BOX_LEFT, 66, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND4, - CFG_COMBO_BTN_LEFT, 65, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_MIDI_OUT, IDT_MIDI_OUT, - CFG_HMARGIN, 88, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MIDI_OUT, - CFG_COMBO_BOX_LEFT, 86, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, - IDC_CONFIGURE_MIDI_OUT, - CFG_COMBO_BTN_LEFT, 85, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_MIDI_IN, IDT_MIDI_IN, - CFG_HMARGIN, 108, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MIDI_IN, - CFG_COMBO_BOX_LEFT, 105, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MIDI_IN, - CFG_COMBO_BTN_LEFT, 105, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_MPU401,IDC_CHECK_MPU401, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 126, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MPU401, - CFG_COMBO_BTN_LEFT, 125, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_FLOAT, IDC_CHECK_FLOAT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 138, 194, CFG_CHECKBOX_HEIGHT - - GROUPBOX STR_FM_DRIVER, IDC_FM_DRIVER, - CFG_HMARGIN, 154, 110, 42 - - CONTROL STR_FM_DRV_NUKED, IDC_RADIO_FM_DRV_NUKED, - "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, - 14, 166, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_FM_DRV_YMFM, IDC_RADIO_FM_DRV_YMFM, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 180, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_NETWORK DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_NET_TYPE, IDT_NET_TYPE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - LTEXT STR_PCAP, IDT_PCAP, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - LTEXT STR_NET, IDT_NET, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - - COMBOBOX IDC_COMBO_NET1_TYPE, - CFG_HMARGIN, 28, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 28, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 28, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 27, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET2_TYPE, - CFG_HMARGIN, 49, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 49, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 49, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 48, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET3_TYPE, - CFG_HMARGIN, 70, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 70, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 70, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 69, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET4_TYPE, - CFG_HMARGIN, 91, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 91, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 91, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 90, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - -END - -DLG_CFG_PORTS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN -/* - LTEXT STR_COM1, IDT_COM1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM2, IDT_COM2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM3, IDT_COM3, - CFG_HMARGIN, 47, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM3, - CFG_COMBO_BOX_LEFT, 45, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM4, IDT_COM4, - CFG_HMARGIN, 66, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM4, - CFG_COMBO_BOX_LEFT, 45, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -*/ - - LTEXT STR_LPT1, IDT_LPT1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT2, IDT_LPT2, - CFG_HMARGIN, 24, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT2, - CFG_COMBO_BOX_LEFT, 22, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT3, IDT_LPT3, - CFG_HMARGIN, 39, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT3, - CFG_COMBO_BOX_LEFT, 37, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT4, IDT_LPT4, - CFG_HMARGIN, 54, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT4, - CFG_COMBO_BOX_LEFT, 52, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_SERIAL1, IDC_CHECK_SERIAL1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 71, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL2, IDC_CHECK_SERIAL2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 86, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL3, IDC_CHECK_SERIAL3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 101, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL4, IDC_CHECK_SERIAL4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 116, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL1, IDC_CHECK_PARALLEL1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 71, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL2, IDC_CHECK_PARALLEL2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 86, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL3, IDC_CHECK_PARALLEL3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 101, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL4, IDC_CHECK_PARALLEL4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 116, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL_PASS1, IDC_CHECK_SERIAL_PASS1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 134, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS1, - CFG_COMBO_BTN_LEFT, 131, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS2, IDC_CHECK_SERIAL_PASS2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 150, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS2, - CFG_COMBO_BTN_LEFT, 147, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS3, IDC_CHECK_SERIAL_PASS3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 165, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS3, - CFG_COMBO_BTN_LEFT, 162, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS4, IDC_CHECK_SERIAL_PASS4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 180, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS4, - CFG_COMBO_BTN_LEFT, 177, CFG_BTN_WIDTH, CFG_BTN_HEIGHT -END - -DLG_CFG_STORAGE DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_HDC, IDT_HDC, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HDC, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_HDC, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_FDC, IDT_FDC, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FDC, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_FDC, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IDE_TER,IDC_CHECK_IDE_TER, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 47, 239, 10 - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_IDE_TER, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IDE_QUA, IDC_CHECK_IDE_QUA, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 66, 239, 10 - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_IDE_QUA, - CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - GROUPBOX STR_SCSI, IDC_GROUP_SCSI, - CFG_HMARGIN, 85, CFG_SYSLISTVIEW32_WIDTH, 93 - - LTEXT STR_SCSI_1, IDT_SCSI_1, - 16, 102, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_1, - CFG_COMBO_BOX_LEFT, 100, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_1, - CFG_COMBO_BTN_LEFT - 10, 99, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SCSI_2, IDT_SCSI_2, - 16, 121, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_2, - CFG_COMBO_BOX_LEFT, 119, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_2, - CFG_COMBO_BTN_LEFT - 10, 118, CFG_BTN_WIDTH,CFG_BTN_HEIGHT - - LTEXT STR_SCSI_3,IDT_SCSI_3, - 16, 140, 64, 10 - COMBOBOX IDC_COMBO_SCSI_3, - CFG_COMBO_BOX_LEFT, 138, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_3, - CFG_COMBO_BTN_LEFT - 10, 137, CFG_BTN_WIDTH,CFG_BTN_HEIGHT - - LTEXT STR_SCSI_4, IDT_SCSI_4, - 16, 159, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_4, - CFG_COMBO_BOX_LEFT, 157, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_4, - CFG_COMBO_BTN_LEFT - 10, 156, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_CASSETTE,IDC_CHECK_CASSETTE, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 185, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_HARD_DISKS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_HDD, IDT_HDD, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_HARD_DISKS, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 18, CFG_SYSLISTVIEW32_WIDTH, 162 - - LTEXT STR_BUS,IDT_BUS, - CFG_HMARGIN, 188, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_BUS, - 33, 186, 40, 12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CHANNEL, - 91, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_CHANNEL, - 131, 186, 40, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE, - 131, 186, 40, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ID, - 91, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_ID, - 131, 186, 70, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_SPEED, IDT_SPEED, - 201, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_SPEED, - 241, 186, 70, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - PUSHBUTTON STR_NEW, IDC_BUTTON_HDD_ADD_NEW, - CFG_HMARGIN, 207, 112, CFG_BTN_HEIGHT - - PUSHBUTTON STR_EXISTING, IDC_BUTTON_HDD_ADD, - 128, 207, 112, CFG_BTN_HEIGHT - - PUSHBUTTON STR_REMOVE, IDC_BUTTON_HDD_REMOVE, - 249, 207, 112, CFG_BTN_HEIGHT - -END - -DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 239, 151 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add Hard Disk" -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_FILE_NAME, IDT_FILE_NAME, - 7, 7, 204, 12 - EDITTEXT IDC_EDIT_HD_FILE_NAME, - 7, 18, 173, 12 - PUSHBUTTON STR_SPECIFY, IDC_CFILE, - 187, 18, 44, CFG_BTN_HEIGHT - - LTEXT STR_CYLS, IDT_CYLS, - 7, 37, 42, 12 - EDITTEXT IDC_EDIT_HD_CYL, - 50, 36, 28, 12 - - LTEXT STR_HEADS, IDT_HEADS, - 86, 37, 29, 12 - EDITTEXT IDC_EDIT_HD_HPC, - 122, 36, 28, 12 - - LTEXT STR_SECTORS, IDT_SECTORS, - 164, 37, 33, 12 - EDITTEXT IDC_EDIT_HD_SPT, - 197, 36, 28, 12 - - LTEXT STR_SIZE_MB, IDT_SIZE_MB, - 7, 56, 48, 12 - EDITTEXT IDC_EDIT_HD_SIZE, - 50, 54, 28, 12 - - LTEXT STR_TYPE, IDT_TYPE, - 86, 56, 24, 12 - COMBOBOX IDC_COMBO_HD_TYPE, - 133, 54, 98, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_BUS,IDT_BUS, - 7, 75, 24, 12 - COMBOBOX IDC_COMBO_HD_BUS, - 43, 73, 58, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CHANNEL, - 109, 75, 34, 12 - COMBOBOX IDC_COMBO_HD_CHANNEL, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ID, - 109, 75, 34, 12 - COMBOBOX IDC_COMBO_HD_ID, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_IMG_FORMAT, IDT_IMG_FORMAT, - 7, 94, 70, 12 - COMBOBOX IDC_COMBO_HD_IMG_FORMAT, - 78, 92, 153, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_BLOCK_SIZE, IDT_BLOCK_SIZE, - 7, 113, 50, 12 - COMBOBOX IDC_COMBO_HD_BLOCK_SIZE, - 58, 111, 153, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_PROGRESS, IDT_PROGRESS, - 7, 7, 204, 12 - CONTROL "IMGCreateProgress", IDC_PBAR_IMG_CREATE, - "msctls_progress32", - PBS_SMOOTH | WS_BORDER, - 7, 16, 204, 12 - - DEFPUSHBUTTON STR_OK, IDOK, - 75, 129, 50, CFG_BTN_HEIGHT - PUSHBUTTON STR_CANCEL, IDCANCEL, - 132, 129, 50, CFG_BTN_HEIGHT -END - -DLG_CFG_FLOPPY_AND_CDROM_DRIVES DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_FLOPPY_DRIVES, IDT_FLOPPY_DRIVES, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_FLOPPY_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 18, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_TYPE, IDT_FDD_TYPE, - CFG_HMARGIN, 87, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FD_TYPE, - 33, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_TURBO, IDC_CHECKTURBO, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 186, 86, 84, CFG_CHECKBOX_HEIGHT - - CONTROL STR_CHECKBPB, IDC_CHECKBPB, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 272, 86, 84, CFG_CHECKBOX_HEIGHT - - LTEXT STR_CDROM_DRIVES, IDT_CD_DRIVES, - CFG_HMARGIN, 107, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_CDROM_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 117, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_CD_BUS, - CFG_HMARGIN, 187, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_BUS, - 33, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CD_CHANNEL, - 181, 187, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_CHANNEL_IDE, - 221, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_CD_ID, - 181, 187, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_ID, - 221, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CD_SPEED, IDT_CD_SPEED, - CFG_HMARGIN, 207, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_SPEED, - 33, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_TYPE, IDT_CD_TYPE, - 181, 207, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_TYPE, - 221, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - -END - -DLG_CFG_OTHER_REMOVABLE_DEVICES DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - - LTEXT STR_MO_DRIVES, IDT_MO_DRIVES, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_MO_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 17, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_MO_BUS, - CFG_HMARGIN, 87, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_BUS, - 33, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_MO_ID, - 181, 87, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_ID, - 221, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_MO_CHANNEL, - 181, 87, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_CHANNEL_IDE, - 221, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_TYPE, IDT_MO_TYPE, - CFG_HMARGIN, 107, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_TYPE, - 33, 105, 328, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ZIP_DRIVES, IDT_ZIP_DRIVES, - CFG_HMARGIN, 127, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_ZIP_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 137, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_ZIP_BUS, - CFG_HMARGIN, 207, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_BUS, - 33, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_ZIP_CHANNEL, - 181, 207, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE, - 221, 205, 105, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ZIP_ID, - 181, 207, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_ID, - 221, 205, 105, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_250, IDC_CHECK250, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 329, 206, 44, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_PERIPHERALS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_ISARTC, IDT_ISARTC, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISARTC, - CFG_COMBO_BOX_LEFT, 7,CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISARTC, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - GROUPBOX STR_ISAMEM, IDC_GROUP_ISAMEM, - CFG_HMARGIN, 28, CFG_SYSLISTVIEW32_WIDTH, 93 - - LTEXT STR_ISAMEM_1, IDT_ISAMEM_1, - 16, 45, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_1, - CFG_COMBO_BOX_LEFT, 43, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_1, - CFG_COMBO_BTN_LEFT - 10, 42, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_2,IDT_ISAMEM_2, - 16, 64, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_2, - CFG_COMBO_BOX_LEFT, 62, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_2, - CFG_COMBO_BTN_LEFT - 10, 61, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_3, IDT_ISAMEM_3, - 16, 83, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_3, - CFG_COMBO_BOX_LEFT, 81, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_3, - CFG_COMBO_BTN_LEFT - 10, 80, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_4, IDT_ISAMEM_4, - 16, 102, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_4, - CFG_COMBO_BOX_LEFT, 100, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_4, - CFG_COMBO_BTN_LEFT - 10, 99, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_BUGGER, IDC_CHECK_BUGGER, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 128, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_POSTCARD,IDC_CHECK_POSTCARD, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 146, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -#undef CFG_CHECKBOX_PRI_WIDTH -#undef CFG_CHECKBOX_HEIGHT -#undef CFG_BTN_WIDTH -#undef CFG_BTN_HEIGHT -#undef CFG_PANE_LTEXT_PRI_WIDTH -#undef CFG_PANE_LTEXT_HEIGHT -#undef CFG_COMBO_BTN_WIDTH -#undef CFG_COMBO_NOBTN_WIDTH -#undef CFG_COMBO_BOX_LEFT -#undef CFG_COMBO_BTN_LEFT -#undef CFG_COMBO_HEIGHT -#undef CFG_LIST_WIDTH -#undef CFG_LIST_HEIGHT -#undef CFG_PANE_TOP -#undef CFG_PANE_LEFT -#undef CFG_PANE_WIDTH -#undef CFG_PANE_HEIGHT -#undef CFG_HMARGIN -#undef CFG_VMARGIN -#undef CFG_SYSLISTVIEW32_WIDTH - - -#undef STR_PREFERENCES -#undef STR_SND_GAIN -#undef STR_NEW_FLOPPY -#undef STR_CONFIG -#undef STR_SPECIFY_DIM - -#undef STR_OK -#undef STR_CANCEL -#undef STR_GLOBAL -#undef STR_DEFAULT -#undef STR_LANGUAGE -#undef STR_ICONSET - -#undef STR_GAIN - -#undef STR_FILE_NAME -#undef STR_DISK_SIZE -#undef STR_RPM_MODE -#undef STR_PROGRESS - -#undef STR_WIDTH -#undef STR_HEIGHT -#undef STR_LOCK_TO_SIZE - -#undef STR_MACHINE_TYPE -#undef STR_MACHINE -#undef STR_CONFIGURE -#undef STR_CPU_TYPE -#undef STR_CPU_SPEED -#undef STR_FPU -#undef STR_WAIT_STATES -#undef STR_MB -#undef STR_MEMORY -#undef STR_TIME_SYNC -#undef STR_DISABLED -#undef STR_ENABLED_LOCAL -#undef STR_ENABLED_UTC -#undef STR_DYNAREC -#undef STR_SOFTFLOAT - -#undef STR_VIDEO -#undef STR_VIDEO_2 -#undef STR_VOODOO -#undef STR_IBM8514 -#undef STR_XGA - -#undef STR_MOUSE -#undef STR_JOYSTICK -#undef STR_JOY1 -#undef STR_JOY2 -#undef STR_JOY3 -#undef STR_JOY4 - -#undef STR_SOUND1 -#undef STR_SOUND2 -#undef STR_SOUND3 -#undef STR_SOUND4 -#undef STR_MIDI_OUT -#undef STR_MIDI_IN -#undef STR_MPU401 -#undef STR_FLOAT -#undef STR_FM_DRIVER -#undef STR_FM_DRV_NUKED -#undef STR_FM_DRV_YMFM - -#undef STR_NET_TYPE -#undef STR_PCAP -#undef STR_NET -#undef STR_NET1 -#undef STR_NET2 -#undef STR_NET3 -#undef STR_NET4 - -#undef STR_COM1 -#undef STR_COM2 -#undef STR_COM3 -#undef STR_COM4 -#undef STR_LPT1 -#undef STR_LPT2 -#undef STR_LPT3 -#undef STR_LPT4 -#undef STR_SERIAL1 -#undef STR_SERIAL2 -#undef STR_SERIAL3 -#undef STR_SERIAL4 -#undef STR_PARALLEL1 -#undef STR_PARALLEL2 -#undef STR_PARALLEL3 -#undef STR_PARALLEL4 -#undef STR_SERIAL_PASS1 -#undef STR_SERIAL_PASS2 -#undef STR_SERIAL_PASS3 -#undef STR_SERIAL_PASS4 - -#undef STR_HDC -#undef STR_FDC -#undef STR_IDE_TER -#undef STR_IDE_QUA -#undef STR_SCSI -#undef STR_SCSI_1 -#undef STR_SCSI_2 -#undef STR_SCSI_3 -#undef STR_SCSI_4 -#undef STR_CASSETTE - -#undef STR_HDD -#undef STR_NEW -#undef STR_EXISTING -#undef STR_REMOVE -#undef STR_BUS -#undef STR_CHANNEL -#undef STR_ID -#undef STR_SPEED - -#undef STR_SPECIFY -#undef STR_SECTORS -#undef STR_HEADS -#undef STR_CYLS -#undef STR_SIZE_MB -#undef STR_TYPE -#undef STR_IMG_FORMAT -#undef STR_BLOCK_SIZE - -#undef STR_FLOPPY_DRIVES -#undef STR_TURBO -#undef STR_CHECKBPB -#undef STR_CDROM_DRIVES -#undef STR_CD_SPEED -#undef STR_EARLY - -#undef STR_MO_DRIVES -#undef STR_ZIP_DRIVES -#undef STR_250 - -#undef STR_ISARTC -#undef STR_ISAMEM -#undef STR_ISAMEM_1 -#undef STR_ISAMEM_2 -#undef STR_ISAMEM_3 -#undef STR_ISAMEM_4 -#undef STR_BUGGER -#undef STR_POSTCARD - -#undef FONT_SIZE -#undef FONT_NAME diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc deleted file mode 100644 index a974b1862..000000000 --- a/src/win/languages/en-GB.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&xit...", IDM_ACTION_EXIT - END - POPUP "&View" - BEGIN - MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filter method" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels (Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA settings" - BEGIN - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - POPUP "VGA screen &type" - BEGIN - MENUITEM "RGB &Colour", IDM_VID_GRAY_RGB - MENUITEM "&RGB Greyscale", IDM_VID_GRAY_MONO - MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN - MENUITEM "&White monitor", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Average", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Enable &Discord integration", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Sound &gain...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Help" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&About 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Record", IDM_CASSETTE_RECORD - MENUITEM "&Play", IDM_CASSETTE_PLAY - MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND - MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Folder...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_ZIP_EJECT - MENUITEM "&Reload previous image", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_MO_EJECT - MENUITEM "&Reload previous image", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Target &framerate" - BEGIN - MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Select shader...", IDM_VID_GL_SHADER - MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferences" -#define STR_SND_GAIN "Sound Gain" -#define STR_NEW_FLOPPY "New Image" -#define STR_CONFIG "Settings" -#define STR_SPECIFY_DIM "Specify Main Window Dimensions" - -#define STR_OK "OK" -#define STR_CANCEL "Cancel" -#define STR_GLOBAL "Save these settings as &global defaults" -#define STR_DEFAULT "&Default" -#define STR_LANGUAGE "Language:" -#define STR_ICONSET "Icon set:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "File name:" -#define STR_DISK_SIZE "Disk size:" -#define STR_RPM_MODE "RPM mode:" -#define STR_PROGRESS "Progress:" - -#define STR_WIDTH "Width:" -#define STR_HEIGHT "Height:" -#define STR_LOCK_TO_SIZE "Lock to this size" - -#define STR_MACHINE_TYPE "Machine type:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configure" -#define STR_CPU_TYPE "CPU type:" -#define STR_CPU_SPEED "Speed:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Wait states:" -#define STR_MB "MB" -#define STR_MEMORY "Memory:" -#define STR_TIME_SYNC "Time synchronization" -#define STR_DISABLED "Disabled" -#define STR_ENABLED_LOCAL "Enabled (local time)" -#define STR_ENABLED_UTC "Enabled (UTC)" -#define STR_DYNAREC "Dynamic Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Sound card #1:" -#define STR_SOUND2 "Sound card #2:" -#define STR_SOUND3 "Sound card #3:" -#define STR_SOUND4 "Sound card #4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" -#define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" - -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Controller:" -#define STR_FDC "FD Controller:" -#define STR_IDE_TER "Tertiary IDE Controller" -#define STR_IDE_QUA "Quaternary IDE Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Hard disks:" -#define STR_NEW "&New..." -#define STR_EXISTING "&Existing..." -#define STR_REMOVE "&Remove" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Channel:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specify..." -#define STR_SECTORS "Sectors:" -#define STR_HEADS "Heads:" -#define STR_CYLS "Cylinders:" -#define STR_SIZE_MB "Size (MB):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Image Format:" -#define STR_BLOCK_SIZE "Block Size:" - -#define STR_FLOPPY_DRIVES "Floppy drives:" -#define STR_TURBO "Turbo timings" -#define STR_CHECKBPB "Check BPB" -#define STR_CDROM_DRIVES "CD-ROM drives:" -#define STR_CD_SPEED "Speed:" - -#define STR_MO_DRIVES "MO drives:" -#define STR_ZIP_DRIVES "ZIP drives:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Memory Expansion" -#define STR_ISAMEM_1 "Card 1:" -#define STR_ISAMEM_2 "Card 2:" -#define STR_ISAMEM_3 "Card 3:" -#define STR_ISAMEM_4 "Card 4:" -#define STR_BUGGER "ISABugger device" -#define STR_POSTCARD "POST card" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Fatal error" - IDS_2051 " - PAUSED" - IDS_2052 "Press Ctrl+Alt+PgDn to return to windowed mode." - IDS_2053 "Speed" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - IDS_2065 "Machine" - IDS_2066 "Display" - IDS_2067 "Input devices" - IDS_2068 "Sound" - IDS_2069 "Network" - IDS_2070 "Ports (COM & LPT)" - IDS_2071 "Storage controllers" - IDS_2072 "Hard disks" - IDS_2073 "Floppy & CD-ROM drives" - IDS_2074 "Other removable devices" - IDS_2075 "Other peripherals" - IDS_2076 "Surface images (*.86F)\0*.86F\0" - IDS_2077 "Click to capture mouse" - IDS_2078 "Press F8+F12 to release mouse" - IDS_2079 "Press F8+F12 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Check BPB" - IDS_2089 "KB" - IDS_2090 "Could not initialize the video renderer." - IDS_2091 "Default" - IDS_2092 "%i Wait state(s)" - IDS_2093 "Type" - IDS_2094 "Failed to set up PCap" - IDS_2095 "No PCap devices found" - IDS_2096 "Invalid PCap device" - IDS_2097 "Standard 2-button joystick(s)" - IDS_2098 "Standard 4-button joystick" - IDS_2099 "Standard 6-button joystick" - IDS_2100 "Standard 8-button joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "None" - IDS_2105 "Unable to load keyboard accelerators." - IDS_2106 "Unable to register raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Are you sure you want to hard reset the emulated machine?" - IDS_2114 "Are you sure you want to exit 86Box?" - IDS_2115 "Unable to initialize Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Welcome to 86Box!" - IDS_2119 "Internal controller" - IDS_2120 "Exit" - IDS_2121 "No ROMs found" - IDS_2122 "Do you want to save the settings?" - IDS_2123 "This will hard reset the emulated machine." - IDS_2124 "Save" - IDS_2125 "About 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2128 "OK" - IDS_2129 "Hardware not available" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2131 "Invalid configuration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 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." - IDS_2135 "Entering fullscreen mode" - IDS_2136 "Don't show this message again" - IDS_2137 "Don't exit" - IDS_2138 "Reset" - IDS_2139 "Don't reset" - IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Device Configuration" - IDS_2143 "Monitor in sleep mode" - IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "OpenGL options" - IDS_2146 "You are loading an unsupported configuration" - IDS_2147 "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." - IDS_2148 "Continue" - IDS_2149 "Cassette: %s" - IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed" - IDS_4100 "Custom..." - IDS_4101 "Custom (large)..." - IDS_4102 "Add New Hard Disk" - IDS_4103 "Add Existing Hard Disk" - IDS_4104 "HDI disk images cannot be larger than 4 GB." - IDS_4105 "Disk images cannot be larger than 127 GB." - IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "Unable to read file" - IDS_4108 "Unable to write file" - IDS_4109 "HDI or HDX images with a sector size other than 512 are not supported." - IDS_4110 "USB is not yet supported" - IDS_4111 "Disk image file already exists" - IDS_4112 "Please specify a valid file name." - IDS_4113 "Disk image created" - IDS_4114 "Make sure the file exists and is readable." - IDS_4115 "Make sure the file is being saved to a writable directory." - IDS_4116 "Disk image too large" - IDS_4117 "Remember to partition and format the newly-created drive." - IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?" - IDS_4119 "Unsupported disk image" - IDS_4120 "Overwrite" - IDS_4121 "Don't overwrite" - IDS_4122 "Raw image (.img)" - IDS_4123 "HDI image (.hdi)" - IDS_4124 "HDX image (.hdx)" - IDS_4125 "Fixed-size VHD (.vhd)" - IDS_4126 "Dynamic-size VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Large blocks (2 MB)" - IDS_4129 "Small blocks (512 KB)" - IDS_4130 "VHD files (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Select the parent VHD" - IDS_4132 "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?" - IDS_4133 "Parent and child disk timestamps do not match" - IDS_4134 "Could not fix VHD timestamp." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabled" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabled" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Perfect RPM" - IDS_6145 "1% below perfect RPM" - IDS_6146 "1.5% below perfect RPM" - IDS_6147 "2% below perfect RPM" - - IDS_7168 "(System Default)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc deleted file mode 100644 index c12fb4a45..000000000 --- a/src/win/languages/en-US.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&xit...", IDM_ACTION_EXIT - END - POPUP "&View" - BEGIN - MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filter method" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels (Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA settings" - BEGIN - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - POPUP "VGA screen &type" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "&RGB Grayscale", IDM_VID_GRAY_MONO - MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN - MENUITEM "&White monitor", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Average", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Enable &Discord integration", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Sound &gain...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Help" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&About 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Record", IDM_CASSETTE_RECORD - MENUITEM "&Play", IDM_CASSETTE_PLAY - MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND - MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Folder...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_ZIP_EJECT - MENUITEM "&Reload previous image", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_MO_EJECT - MENUITEM "&Reload previous image", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Target &framerate" - BEGIN - MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Select shader...", IDM_VID_GL_SHADER - MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferences" -#define STR_SND_GAIN "Sound Gain" -#define STR_NEW_FLOPPY "New Image" -#define STR_CONFIG "Settings" -#define STR_SPECIFY_DIM "Specify Main Window Dimensions" - -#define STR_OK "OK" -#define STR_CANCEL "Cancel" -#define STR_GLOBAL "Save these settings as &global defaults" -#define STR_DEFAULT "&Default" -#define STR_LANGUAGE "Language:" -#define STR_ICONSET "Icon set:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "File name:" -#define STR_DISK_SIZE "Disk size:" -#define STR_RPM_MODE "RPM mode:" -#define STR_PROGRESS "Progress:" - -#define STR_WIDTH "Width:" -#define STR_HEIGHT "Height:" -#define STR_LOCK_TO_SIZE "Lock to this size" - -#define STR_MACHINE_TYPE "Machine type:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configure" -#define STR_CPU_TYPE "CPU type:" -#define STR_CPU_SPEED "Speed:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Wait states:" -#define STR_MB "MB" -#define STR_MEMORY "Memory:" -#define STR_TIME_SYNC "Time synchronization" -#define STR_DISABLED "Disabled" -#define STR_ENABLED_LOCAL "Enabled (local time)" -#define STR_ENABLED_UTC "Enabled (UTC)" -#define STR_DYNAREC "Dynamic Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Sound card #1:" -#define STR_SOUND2 "Sound card #2:" -#define STR_SOUND3 "Sound card #3:" -#define STR_SOUND4 "Sound card #4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" -#define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" - -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Controller:" -#define STR_FDC "FD Controller:" -#define STR_IDE_TER "Tertiary IDE Controller" -#define STR_IDE_QUA "Quaternary IDE Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Hard disks:" -#define STR_NEW "&New..." -#define STR_EXISTING "&Existing..." -#define STR_REMOVE "&Remove" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Channel:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specify..." -#define STR_SECTORS "Sectors:" -#define STR_HEADS "Heads:" -#define STR_CYLS "Cylinders:" -#define STR_SIZE_MB "Size (MB):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Image Format:" -#define STR_BLOCK_SIZE "Block Size:" - -#define STR_FLOPPY_DRIVES "Floppy drives:" -#define STR_TURBO "Turbo timings" -#define STR_CHECKBPB "Check BPB" -#define STR_CDROM_DRIVES "CD-ROM drives:" -#define STR_CD_SPEED "Speed:" - -#define STR_MO_DRIVES "MO drives:" -#define STR_ZIP_DRIVES "ZIP drives:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Memory Expansion" -#define STR_ISAMEM_1 "Card 1:" -#define STR_ISAMEM_2 "Card 2:" -#define STR_ISAMEM_3 "Card 3:" -#define STR_ISAMEM_4 "Card 4:" -#define STR_BUGGER "ISABugger device" -#define STR_POSTCARD "POST card" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Fatal error" - IDS_2051 " - PAUSED" - IDS_2052 "Press Ctrl+Alt+PgDn to return to windowed mode." - IDS_2053 "Speed" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - IDS_2065 "Machine" - IDS_2066 "Display" - IDS_2067 "Input devices" - IDS_2068 "Sound" - IDS_2069 "Network" - IDS_2070 "Ports (COM & LPT)" - IDS_2071 "Storage controllers" - IDS_2072 "Hard disks" - IDS_2073 "Floppy & CD-ROM drives" - IDS_2074 "Other removable devices" - IDS_2075 "Other peripherals" - IDS_2076 "Surface images (*.86F)\0*.86F\0" - IDS_2077 "Click to capture mouse" - IDS_2078 "Press F8+F12 to release mouse" - IDS_2079 "Press F8+F12 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Check BPB" - IDS_2089 "KB" - IDS_2090 "Could not initialize the video renderer." - IDS_2091 "Default" - IDS_2092 "%i Wait state(s)" - IDS_2093 "Type" - IDS_2094 "Failed to set up PCap" - IDS_2095 "No PCap devices found" - IDS_2096 "Invalid PCap device" - IDS_2097 "Standard 2-button joystick(s)" - IDS_2098 "Standard 4-button joystick" - IDS_2099 "Standard 6-button joystick" - IDS_2100 "Standard 8-button joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "None" - IDS_2105 "Unable to load keyboard accelerators." - IDS_2106 "Unable to register raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Are you sure you want to hard reset the emulated machine?" - IDS_2114 "Are you sure you want to exit 86Box?" - IDS_2115 "Unable to initialize Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Welcome to 86Box!" - IDS_2119 "Internal controller" - IDS_2120 "Exit" - IDS_2121 "No ROMs found" - IDS_2122 "Do you want to save the settings?" - IDS_2123 "This will hard reset the emulated machine." - IDS_2124 "Save" - IDS_2125 "About 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2128 "OK" - IDS_2129 "Hardware not available" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2131 "Invalid configuration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 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." - IDS_2135 "Entering fullscreen mode" - IDS_2136 "Don't show this message again" - IDS_2137 "Don't exit" - IDS_2138 "Reset" - IDS_2139 "Don't reset" - IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Device Configuration" - IDS_2143 "Monitor in sleep mode" - IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "OpenGL options" - IDS_2146 "You are loading an unsupported configuration" - IDS_2147 "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." - IDS_2148 "Continue" - IDS_2149 "Cassette: %s" - IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed" - IDS_4100 "Custom..." - IDS_4101 "Custom (large)..." - IDS_4102 "Add New Hard Disk" - IDS_4103 "Add Existing Hard Disk" - IDS_4104 "HDI disk images cannot be larger than 4 GB." - IDS_4105 "Disk images cannot be larger than 127 GB." - IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "Unable to read file" - IDS_4108 "Unable to write file" - IDS_4109 "HDI or HDX images with a sector size other than 512 are not supported." - IDS_4110 "USB is not yet supported" - IDS_4111 "Disk image file already exists" - IDS_4112 "Please specify a valid file name." - IDS_4113 "Disk image created" - IDS_4114 "Make sure the file exists and is readable." - IDS_4115 "Make sure the file is being saved to a writable directory." - IDS_4116 "Disk image too large" - IDS_4117 "Remember to partition and format the newly-created drive." - IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?" - IDS_4119 "Unsupported disk image" - IDS_4120 "Overwrite" - IDS_4121 "Don't overwrite" - IDS_4122 "Raw image (.img)" - IDS_4123 "HDI image (.hdi)" - IDS_4124 "HDX image (.hdx)" - IDS_4125 "Fixed-size VHD (.vhd)" - IDS_4126 "Dynamic-size VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Large blocks (2 MB)" - IDS_4129 "Small blocks (512 KB)" - IDS_4130 "VHD files (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Select the parent VHD" - IDS_4132 "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?" - IDS_4133 "Parent and child disk timestamps do not match" - IDS_4134 "Could not fix VHD timestamp." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabled" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabled" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Perfect RPM" - IDS_6145 "1% below perfect RPM" - IDS_6146 "1.5% below perfect RPM" - IDS_6147 "2% below perfect RPM" - - IDS_7168 "(System Default)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc deleted file mode 100644 index 4888c09f4..000000000 --- a/src/win/languages/es-ES.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Spanish (Spain) resources - -#ifdef _WIN32 -LANGUAGE LANG_SPANISH, SUBLANG_SPANISH -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Acción" - BEGIN - MENUITEM "&Teclado requiere captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &derecho es ALT izquierdo", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Salir...", IDM_ACTION_EXIT - END - POPUP "&Vista" - BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Ventana redimensionable", IDM_VID_RESIZE - MENUITEM "&Recordar tamaño y posición", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "E&specificar dimensiones...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orzar ratio 4:3", IDM_VID_FORCE43 - POPUP "&Factor de escalado de ventana" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Método de filtrado" - BEGIN - MENUITEM "&Más cercano", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineal", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Escalado alta densidad", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Pantalla completa\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Escalado pantalla completa" - BEGIN - MENUITEM "&Estirar", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Píxeles cuadrados (Mant. aspecto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Escalado valor entero", IDM_VID_FS_INT - END - POPUP "&Ajustes EGA/(S)VGA" - BEGIN - MENUITEM "&Monitor VGA invertido", IDM_VID_INVERT - POPUP "&Tipo de pantalla VGA" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "RGB &Grises", IDM_VID_GRAY_MONO - MENUITEM "Monitor &Ámbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &Verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &Blanco", IDM_VID_GRAY_WHITE - END - POPUP "&Conversión a grises" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Cambiar contraste para pantalla &monocroma", IDM_VID_CGACON - END - MENUITEM "&Medios", IDM_MEDIA - POPUP "&Herramientas" - BEGIN - MENUITEM "&Ajustes...", IDM_CONFIG - MENUITEM "&Actualizar iconos en barra de estado", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Tomar c&aptura\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferencias...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Habilitar integración con &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganancia de sonido...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Comenzar traza\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar traza\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ayuda" - BEGIN - MENUITEM "&Documentación...", IDM_DOCS - MENUITEM "&Acerca de 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &Existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagen Existente (&Sólo-lectura)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Grabar", IDM_CASSETTE_RECORD - MENUITEM "&Reproducir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar al inicio", IDM_CASSETTE_REWIND - MENUITEM "&Avance rápido al final", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagen...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar a 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Silenciar", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&xtraer disco", IDM_CDROM_EMPTY - MENUITEM "&Recargar imagen previa", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagen...", IDM_CDROM_IMAGE - MENUITEM "&Carpeta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_ZIP_EJECT - MENUITEM "&Recargar imagen previa", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_MO_EJECT - MENUITEM "&Recargar imagen previa", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Tasa de refresco objetivo" - BEGIN - MENUITEM "&Sincronizar con vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Seleccionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Eliminar shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferencias" -#define STR_SND_GAIN "Ganancia de Sonido" -#define STR_NEW_FLOPPY "Nueva Imagen" -#define STR_CONFIG "Ajustes" -#define STR_SPECIFY_DIM "Especificar Dimensiones de la Ventana Principal" - -#define STR_OK "Aceptar" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Salvar estos ajustes como por &defecto globalmente" -#define STR_DEFAULT "&Por defecto" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Juego de iconos:" - -#define STR_GAIN "Ganancia" - -#define STR_FILE_NAME "Nombre de archivo:" -#define STR_DISK_SIZE "Tamaño de disco:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progreso:" - -#define STR_WIDTH "Ancho:" -#define STR_HEIGHT "Alto:" -#define STR_LOCK_TO_SIZE "Bloquear a este tamaño" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Velocidad:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados en espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronización horaria" -#define STR_DISABLED "Deshabilitado" -#define STR_ENABLED_LOCAL "Habilitado (hora local)" -#define STR_ENABLED_UTC "Habilitado (UTC)" -#define STR_DYNAREC "Recompilador Dinámico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Ratón:" -#define STR_JOYSTICK "Mando:" -#define STR_JOY1 "Mando 1..." -#define STR_JOY2 "Mando 2..." -#define STR_JOY3 "Mando 3..." -#define STR_JOY4 "Mando 4..." - -#define STR_SOUND1 "Tarjeta de sonido 1:" -#define STR_SOUND2 "Tarjeta de sonido 2:" -#define STR_SOUND3 "Tarjeta de sonido 3:" -#define STR_SOUND4 "Tarjeta de sonido 4:" -#define STR_MIDI_OUT "Dispositivo MIDI de salida:" -#define STR_MIDI_IN "Dispositivo MIDI de entrada:" -#define STR_MPU401 "MPU-401 independiente" -#define STR_FLOAT "Usar sonido FLOAT32" -#define STR_FM_DRIVER "Controlador de sintet. FM" -#define STR_FM_DRV_NUKED "Nuked (más preciso)" -#define STR_FM_DRV_YMFM "YMFM (más rápido)" - -#define STR_NET_TYPE "Tipo de red:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de red:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Puerto serie 1" -#define STR_SERIAL2 "Puerto serie 2" -#define STR_SERIAL3 "Puerto serie 3" -#define STR_SERIAL4 "Puerto serie 4" -#define STR_PARALLEL1 "Puerto paralelo 1" -#define STR_PARALLEL2 "Puerto paralelo 2" -#define STR_PARALLEL3 "Puerto paralelo 3" -#define STR_PARALLEL4 "Puerto paralelo 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controladora HD:" -#define STR_FDC "Controladora FD:" -#define STR_IDE_TER "Tercera controladora IDE" -#define STR_IDE_QUA "Cuarta controladora IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controladora 1:" -#define STR_SCSI_2 "Controladora 2:" -#define STR_SCSI_3 "Controladora 3:" -#define STR_SCSI_4 "Controladora 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Discos duros:" -#define STR_NEW "&Nuevo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "E&liminar" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "E&specificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabezas:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamaño (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagen:" -#define STR_BLOCK_SIZE "Tamaño de bloque:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Temporizaciones Turbo" -#define STR_CHECKBPB "Chequear BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Velocidad:" - -#define STR_MO_DRIVES "Unidades MO:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Expansión de Memoria ISA" -#define STR_ISAMEM_1 "Tarjeta 1:" -#define STR_ISAMEM_2 "Tarjeta 2:" -#define STR_ISAMEM_3 "Tarjeta 3:" -#define STR_ISAMEM_4 "Tarjeta 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Tarjeta POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Error fatal" - IDS_2051 " - PAUSED" - IDS_2052 "Pulsa Ctrl+Alt+PgDn para volver a modo ventana." - IDS_2053 "Velocidad" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagenes ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descarga un grupo de imágenes y extráelas en el directorio ""roms""." - IDS_2057 "(vacío)" - IDS_2058 "Imagenes ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "Todas las imagenes (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "La máquina ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una máquina disponible." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La tarjeta de vídeo ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una tarjeta de vídeo disponible." - IDS_2065 "Máquina" - IDS_2066 "Vídeo" - IDS_2067 "Dispositivos de Entrada" - IDS_2068 "Sonido" - IDS_2069 "Red" - IDS_2070 "Puertos (COM y LPT)" - IDS_2071 "Controladoras de Almacenamiento" - IDS_2072 "Discos Duros" - IDS_2073 "Disquetes y unidades de CD-ROM" - IDS_2074 "Otros dispositivos extraíbles" - IDS_2075 "Otros periféricos" - IDS_2076 "Imágenes de superficie (*.86F)\0*.86F\0" - IDS_2077 "Haz click para capturar el ratón" - IDS_2078 "Pulsa F8+F12 para liberar el ratón" - IDS_2079 "Pulsa F8+F12 o el botón central para liberar el ratón" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Archivo" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Chequear BPB" - IDS_2089 "KB" - IDS_2090 "Incapaz de inicializar el renderizador de vídeo." - IDS_2091 "Por defecto" - IDS_2092 "%i estado(s) de Espera" - IDS_2093 "Tipo" - IDS_2094 "Incapaz de configurar PCap" - IDS_2095 "No se encontraron dispositivos PCap" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Mando(s) de 2 botones estándar" - IDS_2098 "Mando de 4 botones estándar" - IDS_2099 "Mando de 6 botones estándar" - IDS_2100 "Mando de 8 botones estándar" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ninguno" - IDS_2105 "Incapaz de cargar aceleradores de teclado." - IDS_2106 "Incapaz de registrar entrada directa." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" - IDS_2114 "¿Seguro que quieres cerrar 86Box?" - IDS_2115 "Incapaz de inicializar Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "¡Bienvenido a 86Box!" - IDS_2119 "Controladora interna" - IDS_2120 "Salir" - IDS_2121 "No se encontraron ROMs" - IDS_2122 "¿Quieres guardar los ajustes?" - IDS_2123 "Se hará hard reset de la máquina emulada." - IDS_2124 "Guardar" - IDS_2125 "Acerca de 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nWith previous core contributions from Sarah Walker, 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." - IDS_2128 "Aceptar" - IDS_2129 "Hardware no disponible" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Asegúrate de que " LIB_NAME_PCAP " está instalado y de que estás en una conexión de red compatible con " LIB_NAME_PCAP "." - IDS_2131 "Configuración inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." - IDS_2135 "Entrando en modo pantalla completa" - IDS_2136 "No mostrar más este mensaje" - IDS_2137 "No salir" - IDS_2138 "Resetear" - IDS_2139 "No resetear" - IDS_2140 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "Imágenes de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Configuración de Dispositivo" - IDS_2143 "Monitor en modo ahorro" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "Opciones OpenGL" - IDS_2146 "Estás cargando una configuración no soportada" - IDS_2147 "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." - IDS_2148 "Continuar" - IDS_2149 "Cassette: %s" - IDS_2150 "Imágenes de Cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imágenes de Cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco duro (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI" - IDS_4100 "A medida..." - IDS_4101 "A medida (grande)..." - IDS_4102 "Añadir Nuevo Disco Duro" - IDS_4103 "Añadir Disco Duro Existente" - IDS_4104 "Las imágenes de disco HDI no pueden superar los 4 GB." - IDS_4105 "Las imágenes de disco no pueden superar los 127 GB." - IDS_4106 "Imágenes de Disco Duro (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "No se pudo leer el archivo" - IDS_4108 "No se pudo escribir el archivo" - IDS_4109 "No se soportan las imágenes HDI o HDX con un tamaño de sector diferente a 512." - IDS_4110 "No se soporta aún el USB" - IDS_4111 "La imagen de disco ya existe" - IDS_4112 "Por favor especifique un nombre de archivo válido." - IDS_4113 "Imagen de disco creada" - IDS_4114 "Asegúrese de que el archivo existe y es leíble." - IDS_4115 "Asegúrese de que el archivo en un directorio con permiso de escritura." - IDS_4116 "Imagen de disco demasiado grande" - IDS_4117 "Recuerde particionar y formatear la nueva unidad." - IDS_4118 "El archivo selecionado será sobreescrito. ¿Está seguro de querer usarlo?" - IDS_4119 "Imagen de disco no soportada" - IDS_4120 "Sobreescribir" - IDS_4121 "No sobreescribir" - IDS_4122 "Imagen plana (.img)" - IDS_4123 "Imagen HDI (.hdi)" - IDS_4124 "Imagen HDX (.hdx)" - IDS_4125 "VHD de tamaño fijo (.vhd)" - IDS_4126 "VHD de tamaño dinámico (.vhd)" - IDS_4127 "VHD diferencial (.vhd)" - IDS_4128 "Bloques grandes (2 MB)" - IDS_4129 "Bloques pequeños (512 KB)" - IDS_4130 "Archivos VHD (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Seleccione el VHD padre" - IDS_4132 "Esto puede deberse a que la imagen padre se modificó después de que la imagen diferencial se crease.\n\nTambién puede ocurrir si las imágenes fueron movidas o copiadas, o por un fallo en el programa que creó este disco.\n\n¿Quiere corregir los registros de tiempo?" - IDS_4133 "Las marcas de tiempo del padre e hijo no coinciden" - IDS_4134 "No se pudo corregir la marca de tiempo del VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deshabilitado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deshabilitado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfectas" - IDS_6145 "1% por debajo de RPM perfectas" - IDS_6146 "1.5% por debajo de RPM perfectas" - IDS_6147 "2% por debajo de RPM perfectas" - - IDS_7168 "(Por defecto del sistema)" -END -#define IDS_LANG_ESES IDS_7168 - -// Spanish (Spain) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc deleted file mode 100644 index 029cce6c0..000000000 --- a/src/win/languages/fi-FI.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Finnish resources - -#ifdef _WIN32 -LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Toiminto" - BEGIN - MENUITEM "&Vaadi näppäimistön kaappaus", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Oikea CTRL on vasen ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Uudelleenkäynnistys (kylmä)...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Tauko", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Poistu...", IDM_ACTION_EXIT - END - POPUP "&Näytä" - BEGIN - MENUITEM "&Piilota tilapalkki", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Piilota &työkalupalkki", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Salli koon muuttaminen", IDM_VID_RESIZE - MENUITEM "&Muista koko ja sijainti", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderöijä" - BEGIN - MENUITEM "&SDL (ohjelmistopohjainen)", IDM_VID_SDL_SW - MENUITEM "SDL (&laitteistokiihdytetty)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Määritä koko...", IDM_VID_SPECIFY_DIM - MENUITEM "Pakota 4:3-näyttösuhde", IDM_VID_FORCE43 - POPUP "&Ikkunan kokokerroin" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Suodatusmetodi" - BEGIN - MENUITEM "&Lähin naapuri", IDM_VID_FILTER_NEAREST - MENUITEM "Li&neaarinen interpolaatio", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Suuri DPI-skaalaus", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Koko näytön tila\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Koko näytön &skaalaustila" - BEGIN - MENUITEM "&Venytä koko näyttöön", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Kokonaislukuskaalaus", IDM_VID_FS_INT - END - POPUP "&EGA/(S)VGA-asetukset" - BEGIN - MENUITEM "&VGA-näyttö käänteisillä väreillä", IDM_VID_INVERT - POPUP "VGA-näytön &tyyppi" - BEGIN - MENUITEM "RGB, &värit", IDM_VID_GRAY_RGB - MENUITEM "&RGB, harmaasävy", IDM_VID_GRAY_MONO - MENUITEM "&Meripihkanvärinen", IDM_VID_GRAY_AMBER - MENUITEM "V&ihreä", IDM_VID_GRAY_GREEN - MENUITEM "V&alkoinen", IDM_VID_GRAY_WHITE - END - POPUP "&Harmaasävymuunnoksen tyyppi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Keskiarvo", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus", IDM_VID_OVERSCAN - MENUITEM "&Muuta harmaavärinäytön kontrastia", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "Työ&kalut" - BEGIN - MENUITEM "&Kokoonpano...", IDM_CONFIG - MENUITEM "&Päivitä tilapalkin kuvakkeita", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Ota &kuvakaappaus\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Sovellusasetukset...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Käytä &Discord-integraatiota", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Äänitasot...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Aloita jäljitys\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Lopeta jäljitys\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ohje" - BEGIN - MENUITEM "&Ohjekirja...", IDM_DOCS - MENUITEM "&Tietoja 86Boxista...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi kasettikuva...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva kasettikuva...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Olemassaoleva kasettikuva (&kirjoitussuojattu)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nauhoita", IDM_CASSETTE_RECORD - MENUITEM "&Toista", IDM_CASSETTE_PLAY - MENUITEM "Kelaa &alkuun", IDM_CASSETTE_REWIND - MENUITEM "Kelaa &loppuun", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Poista kasettipesästä", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&ROM-moduulikuva...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Irrota", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykekuva...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykekuva...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykekuva (&kirjoitussuojattu)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vie 86F-tiedostoon...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mykistä", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Tyhjä", IDM_CDROM_EMPTY - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "L&evykuva...", IDM_CDROM_IMAGE - MENUITEM "&Kansio...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykuva...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_ZIP_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykuva...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_MO_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_MO_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Kuvataajuustavoite" - BEGIN - MENUITEM "&Synkronisoi videoon", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 ruutua/s", IDM_VID_GL_FPS_25 - MENUITEM "&30 ruutua/s", IDM_VID_GL_FPS_30 - MENUITEM "&50 ruutua/s", IDM_VID_GL_FPS_50 - MENUITEM "&60 ruutua/s", IDM_VID_GL_FPS_60 - MENUITEM "&75 ruutua/s", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Valitse varjostin&ohjelma...", IDM_VID_GL_SHADER - MENUITEM "&Poista varjostinohjelma", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Sovellusasetukset" -#define STR_SND_GAIN "Äänen taso" -#define STR_NEW_FLOPPY "Uusi levykuva" -#define STR_CONFIG "Kokoonpano" -#define STR_SPECIFY_DIM "Määritä pääikkunan koko" - -#define STR_OK "OK" -#define STR_CANCEL "Peruuta" -#define STR_GLOBAL "Tallenna nämä asetukset &globaaleiksi oletuksiksi" -#define STR_DEFAULT "&Oletus" -#define STR_LANGUAGE "Kieli:" -#define STR_ICONSET "Kuvakkeet:" - -#define STR_GAIN "Taso" - -#define STR_FILE_NAME "Tiedostonimi:" -#define STR_DISK_SIZE "Levyn koko:" -#define STR_RPM_MODE "Kierroslukutila:" -#define STR_PROGRESS "Edistyminen:" - -#define STR_WIDTH "Leveys:" -#define STR_HEIGHT "Korkeus:" -#define STR_LOCK_TO_SIZE "Lukitse tähän kokoon" - -#define STR_MACHINE_TYPE "Tietokoneen tyyppi:" -#define STR_MACHINE "Tietokone:" -#define STR_CONFIGURE "Määritys" -#define STR_CPU_TYPE "Suorittimen tyyppi:" -#define STR_CPU_SPEED "Nopeus:" -#define STR_FPU "Apusuoritin:" -#define STR_WAIT_STATES "Odotustilat:" -#define STR_MB "Mt" -#define STR_MEMORY "Muisti:" -#define STR_TIME_SYNC "Kellon synkronointi" -#define STR_DISABLED "Ei käytössä" -#define STR_ENABLED_LOCAL "Käytössä (paikallinen)" -#define STR_ENABLED_UTC "Käytössä (UTC)" -#define STR_DYNAREC "Dynaaminen uudelleenkääntäjä" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Näytönohjain:" -#define STR_VIDEO_2 "Näytönohjain 2:" -#define STR_VOODOO "Voodoo-grafiikkasuoritin" -#define STR_IBM8514 "IBM 8514/A-grafiikkasuoritin" -#define STR_XGA "XGA-grafiikkasuoritin" - -#define STR_MOUSE "Hiiri:" -#define STR_JOYSTICK "Peliohjain:" -#define STR_JOY1 "Peliohjain 1..." -#define STR_JOY2 "Peliohjain 2..." -#define STR_JOY3 "Peliohjain 3..." -#define STR_JOY4 "Peliohjain 4..." - -#define STR_SOUND1 "Äänikortti 1:" -#define STR_SOUND2 "Äänikortti 2:" -#define STR_SOUND3 "Äänikortti 3:" -#define STR_SOUND4 "Äänikortti 4:" -#define STR_MIDI_OUT "MIDI-ulostulo:" -#define STR_MIDI_IN "MIDI-sisääntulo:" -#define STR_MPU401 "Erillinen MPU-401" -#define STR_FLOAT "Käytä FLOAT32-ääntä" -#define STR_FM_DRIVER "FM-syntetisaattoriohjain" -#define STR_FM_DRV_NUKED "Nuked (tarkempi)" -#define STR_FM_DRV_YMFM "YMFM (nopeampi)" - -#define STR_NET_TYPE "Verkon tyyppi:" -#define STR_PCAP "PCap-laite:" -#define STR_NET "Verkkokortti:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1-laite:" -#define STR_COM2 "COM2-laite:" -#define STR_COM3 "COM3-laite:" -#define STR_COM4 "COM4-laite:" -#define STR_LPT1 "LPT1-laite:" -#define STR_LPT2 "LPT2-laite:" -#define STR_LPT3 "LPT3-laite:" -#define STR_LPT4 "LPT4-laite:" -#define STR_SERIAL1 "Sarjaportti 1" -#define STR_SERIAL2 "Sarjaportti 2" -#define STR_SERIAL3 "Sarjaportti 3" -#define STR_SERIAL4 "Sarjaportti 4" -#define STR_PARALLEL1 "Rinnakkaisportti 1" -#define STR_PARALLEL2 "Rinnakkaisportti 2" -#define STR_PARALLEL3 "Rinnakkaisportti 3" -#define STR_PARALLEL4 "Rinnakkaisportti 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kiintolevyohjain:" -#define STR_FDC "Levykeohjain:" -#define STR_IDE_TER "Kolmas IDE-ohjain" -#define STR_IDE_QUA "Neljäs IDE-ohjain" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Ohjain 1:" -#define STR_SCSI_2 "Ohjain 2:" -#define STR_SCSI_3 "Ohjain 3:" -#define STR_SCSI_4 "Ohjain 4:" -#define STR_CASSETTE "Kasettiasema" - -#define STR_HDD "Kiintolevyt:" -#define STR_NEW "&Uusi..." -#define STR_EXISTING "&Olemassaoleva..." -#define STR_REMOVE "&Poista" -#define STR_BUS "Väylä:" -#define STR_CHANNEL "Kanava:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Määritä..." -#define STR_SECTORS "Sektorit:" -#define STR_HEADS "Lukupäät:" -#define STR_CYLS "Sylinterit:" -#define STR_SIZE_MB "Koko (Mt):" -#define STR_TYPE "Tyyppi:" -#define STR_IMG_FORMAT "Tiedostomuoto:" -#define STR_BLOCK_SIZE "Lohkon koko:" - -#define STR_FLOPPY_DRIVES "Levykeasemat:" -#define STR_TURBO "Turbo-ajoitukset" -#define STR_CHECKBPB "Tarkista BPB" -#define STR_CDROM_DRIVES "CD-ROM-asemat:" -#define STR_CD_SPEED "Nopeus:" - -#define STR_MO_DRIVES "Magneettisoptiset asemat (MO):" -#define STR_ZIP_DRIVES "ZIP-asemat:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA-RTC (kello):" -#define STR_ISAMEM "ISA-muistilaajennus" -#define STR_ISAMEM_1 "Kortti 1:" -#define STR_ISAMEM_2 "Kortti 2:" -#define STR_ISAMEM_3 "Kortti 3:" -#define STR_ISAMEM_4 "Kortti 4:" -#define STR_BUGGER "ISABugger-laite" -#define STR_POSTCARD "POST-kortti" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Virhe" - IDS_2050 "Vakava virhe" - IDS_2051 " - TAUKO" - IDS_2052 "Paina Ctrl+Alt+PgDn palataksesi ikkunoituun tilaan." - IDS_2053 "Nopeus" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-levykuvat (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit ladata ROM-paketin ja purkaa sen ""roms""-hakemistoon." - IDS_2057 "(tyhjä)" - IDS_2058 "ZIP-levykuvat (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Päällä" - IDS_2061 "Pois" - IDS_2062 "Kaikki levykuvat (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Perussektorilevykuvat (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Pintalevykuvat (*.86F)\0*.86F\0" - IDS_2063 "Konetta ""%hs"" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen koneeseen." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Näytönohjainta ""%hs"" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen näytönohjaimeen." - IDS_2065 "Tietokone" - IDS_2066 "Näyttö" - IDS_2067 "Syöttölaitteet" - IDS_2068 "Ääni" - IDS_2069 "Verkko" - IDS_2070 "Portit (COM & LPT)" - IDS_2071 "Tallennusohjaimet" - IDS_2072 "Kiintolevyt" - IDS_2073 "Levyke ja CD-ROM" - IDS_2074 "Muut tallennuslaitteet" - IDS_2075 "Muut oheislaitteet" - IDS_2076 "Pintalevykuvat (*.86F)\0*.86F\0" - IDS_2077 "Kaappaa hiiri klikkaamalla" - IDS_2078 "Paina F8+F12 vapauttaaksesi hiiren" - IDS_2079 "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Väylä" - IDS_2082 "Tiedosto" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "Mt" - IDS_2087 "Speed" - IDS_2088 "Tarkista BPB" - IDS_2089 "kt" - IDS_2090 "Videorenderöijän alustus epäonnistui" - IDS_2091 "Oletus" - IDS_2092 "%i odotustilaa" - IDS_2093 "Tyyppi" - IDS_2094 "PCap-asennus epäonnistui" - IDS_2095 "PCap-laitteita ei löytynyt" - IDS_2096 "Virheellinen PCap-laite" - IDS_2097 "Standardi 2-painikkeinen peliohjain/-ohjaimet" - IDS_2098 "Standardi 4-painikkeinen peliohjain" - IDS_2099 "Standardi 6-painikkeinen peliohjain" - IDS_2100 "Standardi 8-painikkeinen peliohjain" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ei mikään" - IDS_2105 "Näppäinkiihdyttimien lataus epäonnistui" - IDS_2106 "Raakasyötteen rekisteröinti epäonnistui" - IDS_2107 "%u" - IDS_2108 "%u Mt (CHS: %i, %i, %i)" - IDS_2109 "Levyke %i (%s): %ls" - IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" - IDS_2114 "Haluatko varmasti sulkea 86Boxin?" - IDS_2115 "Ghostscriptin alustus epäonnistui" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2118 "Tervetuloa 86Boxiin!" - IDS_2119 "Sisäinen ohjain" - IDS_2120 "Poistu" - IDS_2121 "ROM-tiedostoja ei löytynyt" - IDS_2122 "Tallennetaanko asetukset?" - IDS_2123 "Tämä käynnistää emuloidun tietokoneen uudelleen." - IDS_2124 "Tallenna" - IDS_2125 "Tietoja 86Box:sta" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." - IDS_2128 "OK" - IDS_2129 "Laitteisto ei ole saatavilla" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Varmista, että " LIB_NAME_PCAP " on asennettu ja että verkkoyhteytesi on " LIB_NAME_PCAP "-yhteensopiva." - IDS_2131 "Virheelliset määritykset" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." - IDS_2135 "Siirrytään koko näytön tilaan" - IDS_2136 "Älä näytä tätä viestiä uudelleen" - IDS_2137 "Älä poistu" - IDS_2138 "Käynnistä uudelleen" - IDS_2139 "Älä käynnistä uudelleen" - IDS_2140 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2141 "CD-ROM-levykuvat (*.ISO;*.CUE)\0*.ISO;*.CUE\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2142 "%hs - Laitteen määritykset" - IDS_2143 "Näyttö lepotilassa" - IDS_2144 "OpenGL-varjostinohjelmat (*.GLSL)\0*.GLSL\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2145 "OpenGL-asetukset" - IDS_2146 "Olet lataamassa ei-tuettuja määrittelyjä" - IDS_2147 "Valittuun tietokoneeseen perustuva suoritintyypin suodatus ei ole käytössä tällä emuloidulla koneella.\n\nTämä mahdollistaa muutoin yhteensopimattoman suorittimen valinnan kyseisen tietokoneen kanssa. Voit kuitenkin kohdata ongelmia tietokoneen BIOS:in tai muun ohjelmiston kanssa.\n\nTämän asetuksen käyttö ei ole virallisesti tuettua ja kaikki tehdyt virheraportit voidaan sulkea epäpätevinä." - IDS_2148 "Jatka" - IDS_2149 "Kasetti: %s" - IDS_2150 "Kasettitiedostot (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2151 "ROM-moduuli %i: %ls" - IDS_2152 "ROM-moduulikuvat (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2153 "Virhe renderöijän alustuksessa" - IDS_2154 "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää." - IDS_2155 "Jatka suoritusta" - IDS_2156 "Pysäytä suoritus" - IDS_2157 "Paina Ctrl+Alt+Del" - IDS_2158 "Paina Ctrl+Alt+Esc" - IDS_2159 "Kylmä uudelleenkäynnistys" - IDS_2160 "ACPI-sammutus" - IDS_2161 "Asetukset" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Kiintolevy (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL- tai ESDI-CD-ROM-asemia ei ole koskaan ollut olemassa" - IDS_4100 "Mukautettu..." - IDS_4101 "Mukautettu (suuri)..." - IDS_4102 "Lisää uusi kiintolevy" - IDS_4103 "Lisää olemassaoleva kiintolevy" - IDS_4104 "HDI-levykuvan suurin mahdollinen koko on 4 Gt." - IDS_4105 "Levykuvien suurin mahdollinen koko on 127 Gt." - IDS_4106 "Kiintolevykuvat (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_4107 "Tiedostoa ei voi lukea" - IDS_4108 "Tiedostoon ei voi kirjoittaa" - IDS_4109 "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512" - IDS_4110 "USB-tukea ei vielä ole" - IDS_4111 "Levykuva on jo olemassa" - IDS_4112 "Anna kelvollinen tiedostonimi." - IDS_4113 "Levykuva luotu" - IDS_4114 "Varmista, että tiedosto on olemassa ja lukukelpoinen" - IDS_4115 "Varmista, että tiedoston tallennuskansioon on kirjoitusoikeus" - IDS_4116 "Liian suuri levykuva" - IDS_4117 "Muista osioida ja alustaa juuri luomasi asema." - IDS_4118 "Valittu tiedosto korvataan. Oletko varma, että haluat käyttää sitä?" - IDS_4119 "Levykuvaa ei tueta" - IDS_4120 "Korvaa" - IDS_4121 "Älä korvaa" - IDS_4122 "Raaka levykuva (.img)" - IDS_4123 "HDI-levykuva (.hdi)" - IDS_4124 "HDX-levykuva (.hdx)" - IDS_4125 "Kiinteä VHD (.vhd)" - IDS_4126 "Dynaaminen VHD (.vhd)" - IDS_4127 "Differentiaalinen VHD (.vhd)" - IDS_4128 "Suuret lohkot (2 Mt)" - IDS_4129 "Pienet lohkot (512 kt)" - IDS_4130 "VHD-tiedostot (*.VHD)\0*.VHD\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_4131 "Valitse ylätason VHD" - IDS_4132 "Tämä saattaa tarkoittaa, että ylätason levykuvaa on muokattu differentiaalisen levykuvan luonnin jälkeen.\n\nNäin voi käydä myös, jos levykuvatiedostoja on siirretty tai kopioitu. Lisäksi syynä voi olla levyn luoneessa sovelluksessa oleva ohjelmistovirhe.\n\nKorjataanko aikaleimat?" - IDS_4133 "Ylä- ja alatason levyjen aikaleimat eivät täsmää" - IDS_4134 "VHD aikaleimaa ei pystytty korjaamaan." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Ei käytössä" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Ei käytössä" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kt" - IDS_5889 "180 kt" - IDS_5890 "320 kt" - IDS_5891 "360 kt" - IDS_5892 "640 kt" - IDS_5893 "720 kt" - IDS_5894 "1.2 Mt" - IDS_5895 "1.25 Mt" - IDS_5896 "1.44 Mt" - IDS_5897 "DMF (lohko 1024)" - IDS_5898 "DMF (lohko 2048)" - IDS_5899 "2.88 Mt" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 Mt (ISO 10090)" - IDS_5903 "3.5"" 230 Mt (ISO 13963)" - IDS_5904 "3.5"" 540 Mt (ISO 15498)" - IDS_5905 "3.5"" 640 Mt (ISO 15498)" - IDS_5906 "3.5"" 1.3 Gt (GigaMO)" - IDS_5907 "3.5"" 2.3 Gt (GigaMO 2)" - IDS_5908 "5.25"" 600 Mt" - IDS_5909 "5.25"" 650 Mt" - IDS_5910 "5.25"" 1 Gt" - IDS_5911 "5.25"" 1.3 Gt" - - IDS_6144 "Täydellinen RPM" - IDS_6145 "1% alle täydellisen RPM:n" - IDS_6146 "1.5% alle täydellisen RPM:n" - IDS_6147 "2% alle täydellisen RPM:n" - - IDS_7168 "(Järjestelmän oletus)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc deleted file mode 100644 index 425656c28..000000000 --- a/src/win/languages/fr-FR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// French (fr-FR) resources - -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Capturer le clavier", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &Droite devient ALT Gauche", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Quitter...", IDM_ACTION_EXIT - END - POPUP "&Vue" - BEGIN - MENUITEM "&Masquer la barre de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "Fenètre &Retaillable", IDM_VID_RESIZE - MENUITEM "S&auvegarder taille && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Moteur de &rendu vidéo" - BEGIN - MENUITEM "&SDL (Logiciel)", IDM_VID_SDL_SW - MENUITEM "SDL (&Materiel)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specifier dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orcer 4:3", IDM_VID_FORCE43 - POPUP "&Echelle facteur" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Methode Filtre" - BEGIN - MENUITEM "&Plus proche", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineaire", IDM_VID_FILTER_LINEAR - END - MENUITEM "Mise à l'échelle Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Plein Ecran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Mode &Elargi plein écran" - BEGIN - MENUITEM "&Plein écran étiré", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "pixels &Carrés(Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Echelle &Entière", IDM_VID_FS_INT - END - POPUP "Réglages E&GA/(S)VGA" - BEGIN - MENUITEM "Moniteur VGA &Inversé", IDM_VID_INVERT - POPUP "&Type Ecran VGA" - BEGIN - MENUITEM "RGB &Couleur", IDM_VID_GRAY_RGB - MENUITEM "&RGB Ton de Gris", IDM_VID_GRAY_MONO - MENUITEM "Moniteur &Ambre", IDM_VID_GRAY_AMBER - MENUITEM "Moniteur &Vert", IDM_VID_GRAY_GREEN - MENUITEM "Moniteur &Blanc", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Moyenne", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Modifier contraste affichage &monochrome", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "Ou&tils" - BEGIN - MENUITEM "&Réglages...", IDM_CONFIG - MENUITEM "Mettre à jour la barre de stat&us", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Copie &Ecran\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Préférences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Activer intégration &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Gain Son...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Démarrer traces\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Finir traces\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Aide" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&A Propos de 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "En®istrer", IDM_CASSETTE_RECORD - MENUITEM "&Jouer", IDM_CASSETTE_PLAY - MENUITEM "&Revenir au debut", IDM_CASSETTE_REWIND - MENUITEM "Aller à la &Fin", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport vers 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Couper", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CDROM_EMPTY - MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Dossier...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_ZIP_EJECT - MENUITEM "&Recharger image précédente", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_MO_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_MO_EJECT - MENUITEM "&Recharger image précédente", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taux de rafraîchissement cible" - BEGIN - MENUITEM "&Synchronisation avec la vidéo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 images par seconde", IDM_VID_GL_FPS_25 - MENUITEM "&30 images par seconde", IDM_VID_GL_FPS_30 - MENUITEM "&50 images par seconde", IDM_VID_GL_FPS_50 - MENUITEM "&60 images par seconde", IDM_VID_GL_FPS_60 - MENUITEM "&75 images par seconde", IDM_VID_GL_FPS_75 - END - MENUITEM "Synchronisation &verticale", IDM_VID_GL_VSYNC - MENUITEM "Sé&lectionnez le shader...", IDM_VID_GL_SHADER - MENUITEM "S&upprimer le shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Préférences" -#define STR_SND_GAIN "Gain son" -#define STR_NEW_FLOPPY "Nouvelle image" -#define STR_CONFIG "Réglages" -#define STR_SPECIFY_DIM "Spécifier le détournement de la fenêtre principale" - -#define STR_OK "OK" -#define STR_CANCEL "Annuler" -#define STR_GLOBAL "Sauvegarder ces paramètres comme valeurs par défaut &globales" -#define STR_DEFAULT "&Défaut" -#define STR_LANGUAGE "Langue:" -#define STR_ICONSET "Ensemble d'icônes:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "Nom fichier:" -#define STR_DISK_SIZE "Taille disque:" -#define STR_RPM_MODE "Mode RPM:" -#define STR_PROGRESS "Progrès:" - -#define STR_WIDTH "Largeur:" -#define STR_HEIGHT "Hauteur:" -#define STR_LOCK_TO_SIZE "Verrouiller à cette taille" - -#define STR_MACHINE_TYPE "Type de machine:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configurer" -#define STR_CPU_TYPE "Type du processeur:" -#define STR_CPU_SPEED "Vitesse:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "États d'attente:" -#define STR_MB "Mo" -#define STR_MEMORY "Mémoire:" -#define STR_TIME_SYNC "Synchronisation du temps" -#define STR_DISABLED "Désactivé" -#define STR_ENABLED_LOCAL "Activé (heure locale)" -#define STR_ENABLED_UTC "Activé (UTC)" -#define STR_DYNAREC "Recompilateur dynamique" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vidéo:" -#define STR_VIDEO_2 "Vidéo 2:" -#define STR_VOODOO "Graphique Voodoo" -#define STR_IBM8514 "Graphique IBM 8514/A" -#define STR_XGA "Graphique XGA" - -#define STR_MOUSE "Souris:" -#define STR_JOYSTICK "Manette de commande:" -#define STR_JOY1 "Manette 1..." -#define STR_JOY2 "Manette 2..." -#define STR_JOY3 "Manette 3..." -#define STR_JOY4 "Manette 4..." - -#define STR_SOUND1 "Carte son 1:" -#define STR_SOUND2 "Carte son 2:" -#define STR_SOUND3 "Carte son 3:" -#define STR_SOUND4 "Carte son 4:" -#define STR_MIDI_OUT "Sortie MIDI:" -#define STR_MIDI_IN "Entrée MIDI:" -#define STR_MPU401 "MPU-401 autonome" -#define STR_FLOAT "Utiliser le son FLOAT32" -#define STR_FM_DRIVER "Pilote de synthétiseur FM" -#define STR_FM_DRV_NUKED "Nuked (plus précis)" -#define STR_FM_DRV_YMFM "YMFM (plus rapide)" - -#define STR_NET_TYPE "Type de réseau:" -#define STR_PCAP "Dispositif PCap:" -#define STR_NET "Adaptateur de réseau:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositif COM1:" -#define STR_COM2 "Dispositif COM2:" -#define STR_COM3 "Dispositif COM3:" -#define STR_COM4 "Dispositif COM4:" -#define STR_LPT1 "Dispositif LPT1:" -#define STR_LPT2 "Dispositif LPT2:" -#define STR_LPT3 "Dispositif LPT3:" -#define STR_LPT4 "Dispositif LPT4:" -#define STR_SERIAL1 "Port série 1" -#define STR_SERIAL2 "Port série 2" -#define STR_SERIAL3 "Port série 3" -#define STR_SERIAL4 "Port série 4" -#define STR_PARALLEL1 "Port parallèle 1" -#define STR_PARALLEL2 "Port parallèle 2" -#define STR_PARALLEL3 "Port parallèle 3" -#define STR_PARALLEL4 "Port parallèle 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Contrôleur HD:" -#define STR_FDC "Contrôleur FD:" -#define STR_IDE_TER "Contrôleur IDE tertiaire" -#define STR_IDE_QUA "Contrôleur IDE quaternair" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Contrôleur 1:" -#define STR_SCSI_2 "Contrôleur 2:" -#define STR_SCSI_3 "Contrôleur 3:" -#define STR_SCSI_4 "Contrôleur 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Disques durs:" -#define STR_NEW "&Nouveau..." -#define STR_EXISTING "&Existant..." -#define STR_REMOVE "&Supprimer" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Spécifier..." -#define STR_SECTORS "Secteurs:" -#define STR_HEADS "Têtes:" -#define STR_CYLS "Cylindres:" -#define STR_SIZE_MB "Taille (Mo):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Format Image:" -#define STR_BLOCK_SIZE "Taille du bloc:" - -#define STR_FLOPPY_DRIVES "Lecteurs de disquettes:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Vérifier BPB" -#define STR_CDROM_DRIVES "Lecterus CD-ROM:" -#define STR_CD_SPEED "Vitesse:" - -#define STR_MO_DRIVES "Lecteurs magnéto-optiques:" -#define STR_ZIP_DRIVES "Lecteurs ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Horloge temps réel ISA:" -#define STR_ISAMEM "Expansion de la mémoire ISA" -#define STR_ISAMEM_1 "Carte 1:" -#define STR_ISAMEM_2 "Carte 2:" -#define STR_ISAMEM_3 "Carte 3:" -#define STR_ISAMEM_4 "Carte 4:" -#define STR_BUGGER "Dispositif ISABugger" -#define STR_POSTCARD "Carte POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erreur" - IDS_2050 "Erreur fatale" - IDS_2051 " - PAUSED" - IDS_2052 "Appuyez sur Ctrl+Alt+PgDn pour revenir au mode fenêtré." - IDS_2053 "Vitesse" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Images ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box n'a pas pu trouver d'images ROM utilisables.\n\nS'il vous plait, téléchargez un ensemble ROM et extrayez-le dans le répertoire ""roms""." - IDS_2057 "(vide)" - IDS_2058 "Images ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Activé" - IDS_2061 "Désactivé" - IDS_2062 "Tous les images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Images basiques du secteur (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Images de la surface (*.86F)\0*.86F\0" - IDS_2063 "La machine ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/machines. Basculer vers une machine disponible." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La carte vidéo ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." - IDS_2065 "Machine" - IDS_2066 "Affichage" - IDS_2067 "Dispositifs d'entrée" - IDS_2068 "Son" - IDS_2069 "Réseau" - IDS_2070 "Ports (COM et LPT)" - IDS_2071 "Contrôleurs de stockage" - IDS_2072 "Disques durs" - IDS_2073 "Lecteurs de disquette et CD-ROM" - IDS_2074 "Autres dispositifs amovibles" - IDS_2075 "Autres périfériques" - IDS_2076 "Images de surface (*.86F)\0*.86F\0" - IDS_2077 "Cliquer pour capturer la souris" - IDS_2078 "Appuyer sur F8+F12 pour libérer la souris" - IDS_2079 "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "T" - IDS_2085 "S" - IDS_2086 "Mo" - IDS_2087 "Speed" - IDS_2088 "Vérifier BPB" - IDS_2089 "Ko" - IDS_2090 "Impossible d'initialiser le moteur de rendu vidéo." - IDS_2091 "Défaut" - IDS_2092 "%i état(s) d'attente" - IDS_2093 "Type" - IDS_2094 "Impossible d'initialiser PCap" - IDS_2095 "Aucun dispositif PCap trouvé" - IDS_2096 "Dispositif PCap non valide" - IDS_2097 "Manette(s) standard avec 2 boutons" - IDS_2098 "Manette standard avec 4 boutons" - IDS_2099 "Manette standard avec 6 boutons" - IDS_2100 "Manette standard avec 6 boutons" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Système de contrôle de vol Thrustmaster" - IDS_2104 "Aucun" - IDS_2105 "Impossible de charger les accélérateurs de clavier." - IDS_2106 "Impossible de charger l'entrée raw." - IDS_2107 "%u" - IDS_2108 "%u Mo (CTS: %i, %i, %i)" - IDS_2109 "Disquette %i (%s): %ls" - IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" - IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" - IDS_2115 "Impossible d'initialiser Ghostscript" - IDS_2116 "Magnéto-optique %i (%ls): %ls" - IDS_2117 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2118 "Bienvenue dans 86Box !" - IDS_2119 "Côntrolleur interne" - IDS_2120 "Sortir" - IDS_2121 "Pas de ROMs trouvées" - IDS_2122 "Voulez-vous sauvegarder les paramètres ?" - IDS_2123 "Cela entraînera la réinitialisation complète de la machine émulée." - IDS_2124 "Sauvegarder" - IDS_2125 "À propos de 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." - IDS_2128 "OK" - IDS_2129 "Matériel non disponible" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." - IDS_2131 "Configuration non valide" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." - IDS_2135 "Entrer en mode plein écran" - IDS_2136 "Ne pas montrer ce message à nouveau" - IDS_2137 "Ne pas sortir" - IDS_2138 "Réinitialiser" - IDS_2139 "Ne pas réinitialiser" - IDS_2140 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2141 "Images CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tous les fichiers (*.*)\0*.*\0" - IDS_2142 "Configuration du dispositif %hs" - IDS_2143 "Moniteur en mode veille" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Tous les fichiers (*.*)\0*.*\0" - IDS_2145 "Options OpenGL" - IDS_2146 "Vous chargez une configuration non prise en charge" - IDS_2147 "La filtrage du type du processeur sur la base de la machine sélectionné est désactivé pur cette machine émulée.\n\nCela permet de sélectionner une processeur que est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activatione de cette configuration non est officiellement prise en charge et tout rapport de bogue peut être fermé comme étant invalide." - IDS_2148 "Continuer" - IDS_2149 "Cassette: %s" - IDS_2150 "Images cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tous les fichiers (*.*)\0*.*\0" - IDS_2151 "Cartouche %i: %ls" - IDS_2152 "Images cartouche (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tous les fichiers (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disque dur (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Les lecteurs de CD-ROM MFM/RLL ou ESDI n'ont jamais existé" - IDS_4100 "Personnalisé..." - IDS_4101 "Personnalisé (grand)..." - IDS_4102 "Ajouter un nouveau disque dur" - IDS_4103 "Ajouter un disque dur existant" - IDS_4104 "Les images de disque HDI ne peuvent pas avoir une taille supériure à Go." - IDS_4105 "Les images de disque ne peuvent pas avoir un taille supérieure à 127 Go." - IDS_4106 "Images de dique dur (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tous les fichiers (*.*)\0*.*\0" - IDS_4107 "Impossible de lire le fichier" - IDS_4108 "Impossible d'écrire le fichier" - IDS_4109 "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." - IDS_4110 "USB n'est pas encore pris en charge." - IDS_4111 "Le fichier de l'image disque existe déjà." - IDS_4112 "Veuillez spécifier un nom de fichier valide." - IDS_4113 "Image de disque créée" - IDS_4114 "Assurez-vous que le fichier existe et est lisible." - IDS_4115 "Assurez-vous que le fichier en cours d'enregistrement se trouve dans un répertoire accessible en écriture." - IDS_4116 "Image disque trop grande" - IDS_4117 "N'oubliez pas de partitionner et de formater le nouveau disque créé." - IDS_4118 "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser?" - IDS_4119 "Image disque non prise en charge" - IDS_4120 "Écraser" - IDS_4121 "Ne pas écraser" - IDS_4122 "Image brute (.img)" - IDS_4123 "Image HDI (.hdi)" - IDS_4124 "Image HDX (.hdx)" - IDS_4125 "VHD à taille fixe (.vhd)" - IDS_4126 "VHD à taille dynamique (.vhd)" - IDS_4127 "VHD à différenciation (.vhd)" - IDS_4128 "Blocs grands (2 Mo)" - IDS_4129 "Blocs petits (512 Ko)" - IDS_4130 "Fichiers VHD (*.VHD)\0*.VHD\0Tous les fichiers (*.*)\0*.*\0" - IDS_4131 "Sélectionnez le VHD parent" - IDS_4132 "Il est possible que l'image parente a été modifié après la création de l'image à différenciation.\n\nIl est même possible que les fichiers de l'mage ont été déplacés ou copiés ou il existe un bogue dans le programme que a créé ce disque.\n\nVoulez-vous réparer l'horodatage?" - IDS_4133 "Les horodatages des disques parent et enfant ne correspondent pas" - IDS_4134 "Impossible de réparer l'horodatage du VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Désactivé" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Désactivé" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 Ko" - IDS_5889 "180 Ko" - IDS_5890 "320 Ko" - IDS_5891 "360 Ko" - IDS_5892 "640 Ko" - IDS_5893 "720 Ko" - IDS_5894 "1.2 Mo" - IDS_5895 "1.25 Mo" - IDS_5896 "1.44 Mo" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 Mo" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 Mo (ISO 10090)" - IDS_5903 "3.5"" 230 Mo (ISO 13963)" - IDS_5904 "3.5"" 540 Mo (ISO 15498)" - IDS_5905 "3.5"" 640 Mo (ISO 15498)" - IDS_5906 "3.5"" 1.3 Go (GigaMO)" - IDS_5907 "3.5"" 2.3 Go (GigaMO 2)" - IDS_5908 "5.25"" 600 Mo" - IDS_5909 "5.25"" 650 Mo" - IDS_5910 "5.25"" 1 Go" - IDS_5911 "5.25"" 1.3 Go" - - IDS_6144 "RPM précis" - IDS_6145 "Précision RPM de moins 1%" - IDS_6146 "Précision RPM de moins 1.5%" - IDS_6147 "Précision RPM de moins 2%" - - IDS_7168 "(Défaut du système)" -END -#define IDS_LANG_ENUS IDS_7168 - -// French (F.R.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc deleted file mode 100644 index f01b2a881..000000000 --- a/src/win/languages/hr-HR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Croatian (hr-HR) resources - -#ifdef _WIN32 -LANGUAGE LANG_CROATIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Radnje" - BEGIN - MENUITEM "&Tipkovnica zahtijeva hvatanje miša", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je lijevi ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Ponovno pokretanje...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Iz&laz...", IDM_ACTION_EXIT - END - POPUP "&Pogled" - BEGIN - MENUITEM "&Sakrij statusni redak", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Sakrij alatni redak", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Prozor s promjenjivim veličinama", IDM_VID_RESIZE - MENUITEM "&Zapamtite veličinu i položaj", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderer" - BEGIN - MENUITEM "&SDL (Softver)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardver)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 jezgra)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Odrediti veličinu...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 omjer prikaza", IDM_VID_FORCE43 - POPUP "&Faktor skaliranja prozora" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda filtriranja" - BEGIN - MENUITEM "&Najbliža", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR - END - MENUITEM "&HiDPI skaliranje", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Cijelozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Način cijelozaslonskog rastezanja" - BEGIN - MENUITEM "&Razvuci na cijeli zaslona", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kvadratni pikseli (zadrži omjer)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Cijelobrojno skaliranje", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA postavke" - BEGIN - MENUITEM "&Obrni boje zaslona VGA", IDM_VID_INVERT - POPUP "&Tip zaslona VGA" - BEGIN - MENUITEM "RGB u &boji", IDM_VID_GRAY_RGB - MENUITEM "&RGB u nijansama sive boje", IDM_VID_GRAY_MONO - MENUITEM "&Jantarni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "&Bijeli zaslon", IDM_VID_GRAY_WHITE - END - POPUP "&Vrsta konverzije nijansa sive boje" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Prosjek", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Višak slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Promjeni kontrast za crno-bijeli zaslon", IDM_VID_CGACON - END - MENUITEM "&Mediji", IDM_MEDIA - POPUP "&Alati" - BEGIN - MENUITEM "&Opcije...", IDM_CONFIG - MENUITEM "&Ažuriraj ikone statusnog redka", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Napravi &snimku zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Postavke...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Omogući integraciju sa programom &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Pojačanje zvuka...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Z&apočni praćenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Svrši praćenje\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoć" - BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Snimi", IDM_CASSETTE_RECORD - MENUITEM "&Pokreni", IDM_CASSETTE_PLAY - MENUITEM "P&remotaj na početak", IDM_CASSETTE_REWIND - MENUITEM "&Preskoči do kraja", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Slika...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izvozi u 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Isključi zvuk", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Prazno", IDM_CDROM_EMPTY - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_ZIP_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_MO_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Ciljni broj okvira u sekundi" - BEGIN - MENUITEM "&Sinkroniziraj s videom", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Odaberi shader...", IDM_VID_GL_SHADER - MENUITEM "&Ukloni shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Postavke" -#define STR_SND_GAIN "Pojačavanje zvuka" -#define STR_NEW_FLOPPY "Nova slika" -#define STR_CONFIG "Opcije" -#define STR_SPECIFY_DIM "Odredite glavne dimenzije prozora" - -#define STR_OK "U redu" -#define STR_CANCEL "Otkaži" -#define STR_GLOBAL "Spremite ove postavke kao &globalne zadane postavke" -#define STR_DEFAULT "Zadano" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Paket ikona:" - -#define STR_GAIN "Pojačavanje" - -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Veličina diska:" -#define STR_RPM_MODE "Način broja okretaja:" -#define STR_PROGRESS "Napredak:" - -#define STR_WIDTH "Širina:" -#define STR_HEIGHT "Visina:" -#define STR_LOCK_TO_SIZE "Zaključajte na ovu veličinu" - -#define STR_MACHINE_TYPE "Tip sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Namjesti" -#define STR_CPU_TYPE "Tip procesora:" -#define STR_CPU_SPEED "Brzina:" -#define STR_FPU "FPU uređaj:" -#define STR_WAIT_STATES "Stanja čekanja:" -#define STR_MB "MB" -#define STR_MEMORY "Memorija:" -#define STR_TIME_SYNC "Sinkronizacija vremena" -#define STR_DISABLED "Isključeno" -#define STR_ENABLED_LOCAL "Uključeno (lokalno vrijeme)" -#define STR_ENABLED_UTC "Uključeno (UTC)" -#define STR_DYNAREC "Dinamički rekompilator" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/A grafika" -#define STR_XGA "XGA grafika" - -#define STR_MOUSE "Miš:" -#define STR_JOYSTICK "Palica za igru:" -#define STR_JOY1 "Palica za igru 1..." -#define STR_JOY2 "Palica za igru 2..." -#define STR_JOY3 "Palica za igru 3..." -#define STR_JOY4 "Palica za igru 4..." - -#define STR_SOUND1 "Zvučna kartica 1:" -#define STR_SOUND2 "Zvučna kartica 2:" -#define STR_SOUND3 "Zvučna kartica 3:" -#define STR_SOUND4 "Zvučna kartica 4:" -#define STR_MIDI_OUT "Izlazni uređaj MIDI:" -#define STR_MIDI_IN "Ulazni uređaj MIDI:" -#define STR_MPU401 "Samostalni MPU-401" -#define STR_FLOAT "Koristi FLOAT32 za zvuk" -#define STR_FM_DRIVER "Drajver za FM sintisajzer" -#define STR_FM_DRV_NUKED "Nuked (precizniji)" -#define STR_FM_DRV_YMFM "YMFM (brži)" - -#define STR_NET_TYPE "Tip mreže:" -#define STR_PCAP "Uređaj PCap:" -#define STR_NET "Mrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Uređaj COM1:" -#define STR_COM2 "Uređaj COM2:" -#define STR_COM3 "Uređaj COM3:" -#define STR_COM4 "Uređaj COM4:" -#define STR_LPT1 "Uređaj LPT1:" -#define STR_LPT2 "Uređaj LPT2:" -#define STR_LPT3 "Uređaj LPT3:" -#define STR_LPT4 "Uređaj LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kontroler tvrdog diska:" -#define STR_FDC "Kontroler diskete:" -#define STR_IDE_TER "Tercijarni IDE kontroler" -#define STR_IDE_QUA "Kvaternarni IDE kontroler" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontroler 1:" -#define STR_SCSI_2 "Kontroler 2:" -#define STR_SCSI_3 "Kontroler 3:" -#define STR_SCSI_4 "Kontroler 4:" -#define STR_CASSETTE "Audio kaseta" - -#define STR_HDD "Tvrdi diskovi:" -#define STR_NEW "&Novi..." -#define STR_EXISTING "&Postojeći..." -#define STR_REMOVE "&Ukloni" -#define STR_BUS "Sabirnica:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Odredi..." -#define STR_SECTORS "Sektori:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Veličina (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Veličina slike:" - -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo vrijemena" -#define STR_CHECKBPB "Provjeraj BPB" -#define STR_CDROM_DRIVES "CD-ROM pogoni:" -#define STR_CD_SPEED "Brzina:" - -#define STR_MO_DRIVES "MO pogoni:" -#define STR_ZIP_DRIVES "ZIP pogoni:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Sat stvarnog vremena (RTC):" -#define STR_ISAMEM "Proširenje memorije ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" -#define STR_BUGGER "Uređaj ISABugger" -#define STR_POSTCARD "Kartica POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Greška" - IDS_2050 "Fatalna greška" - IDS_2051 " - PAUSED" - IDS_2052 "Pritisnite Ctrl+Alt+PgDn za povratak u prozorski način rada." - IDS_2053 "Brzina" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nije mogao pronaći upotrebljive ROM datoteke.\n\nMolimte posjetite sknite paket s ROM datotekama i ekstrahirajte paket u ""roms"" mapu." - IDS_2057 "(prazno)" - IDS_2058 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Sve datoteke (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Uključeno" - IDS_2061 "Isključeno" - IDS_2062 "Sve slike (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0BOsnovne sektorske slike (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Površinske slike (*.86F)\0*.86F\0" - IDS_2063 "Sistem ""%hs"" nije dostupan jer ne postoje potrebni ROM-ovi u mapu roms/machines. Prebacivanje na dostupno računalo." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video kartica ""%hs"" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Prebacivanje na dostupnu video karticu." - IDS_2065 "Sistem" - IDS_2066 "Video" - IDS_2067 "Ulazni uređaji" - IDS_2068 "Zvuk" - IDS_2069 "Mreža" - IDS_2070 "Vrata (COM & LPT)" - IDS_2071 "Kontroleri za diskove" - IDS_2072 "Tvrdi diskovi" - IDS_2073 "Floppy & CD-ROM pogoni" - IDS_2074 "Ostali uklonjivi uređaji" - IDS_2075 "Ostali periferni uređaji" - IDS_2076 "Površinske slike (*.86F)\0*.86F\0" - IDS_2077 "Kliknite da uhvatite miš" - IDS_2078 "Pritisnite F8+F12 za otpustanje miša" - IDS_2079 "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Datoteka" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Provjeri BPB" - IDS_2089 "KB" - IDS_2090 "Nije moguće inicijalizirati renderer." - IDS_2091 "Standard" - IDS_2092 "%i stanje čekanja" - IDS_2093 "Tip" - IDS_2094 "Postavljanje PCap-a nije uspjelo" - IDS_2095 "Nema PCap uređaja" - IDS_2096 "Nevažeći PCap uređaj" - IDS_2097 "Standardna palica za igru s 2 tipke" - IDS_2098 "Standardna palica za igru s 4 tipke" - IDS_2099 "Standardna palica za igru s 6 tipke" - IDS_2100 "Standardna palica za igru s 8 tipke" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Bez" - IDS_2105 "Nije moguće učitati ubrzivače tipkovnice." - IDS_2106 "Nije moguće registrirati neobrađeni unos." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketa %i (%s): %ls" - IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" - IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" - IDS_2115 "Nije moguće inicijalizirati GhostScript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Svi datoteke (*.*)\0*.*\0" - IDS_2118 "Dobrodošli u 86Box!" - IDS_2119 "Uunutarnji kontroler" - IDS_2120 "Izlazi" - IDS_2121 "Nisu pronađene ROM datoteke" - IDS_2122 "Želite li spremiti postavke?" - IDS_2123 "Ovo će napraviti hard resetiranje emuliranog sistema." - IDS_2124 "Spremaj" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box verzija " EMU_VERSION - - IDS_2127 "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." - IDS_2128 "U redu" - IDS_2129 "Hardver nije dostupan" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Provjerite je li " LIB_NAME_PCAP " instaliran i jeste li na mreži, kompadibilnoj s " LIB_NAME_PCAP "." - IDS_2131 "Nevažeća konfiguracija" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." - IDS_2135 "Ulazim u cijelozaslonski način" - IDS_2136 "Ne pokazi više ovu poruku" - IDS_2137 "Ne izlazi" - IDS_2138 "Resetiraj" - IDS_2139 "Ne resetiraj" - IDS_2140 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Sve datoteke (*.*)\0*.*\0" - IDS_2141 "CD-ROM slike (*.ISO;*.CUE)\0*.ISO;*.CUE\0Sve datoteke (*.*)\0*.*\0" - IDS_2142 "Konfiguracija uređaja %hs " - IDS_2143 "Ekran u stanju mirovanja" - IDS_2144 "OpenGL shaderi (*.GLSL)\0*.GLSL\0Sve datoteke (*.*)\0*.*\0" - IDS_2145 "OpenGL opcije" - IDS_2146 "Učitavate nepodržanu konfiguraciju" - IDS_2147 "Filtriranje tipa CPU-a na temelju odabranog sistema onemogućeno je za ovaj emulirani sistem.\n\nOvo omogućuje odabir procesora koji inače nisu kompatibilne s odabranog sistem. Međutim, možete naići na na nekompatibilnosti s BIOS-om sustava ili drugim softverom.\n\nOmogućavanje ove postavke nije službeno podržano i sva prijava o greškama mogu biti zatvorena kao ""invalid""." - IDS_2148 "Nastavi" - IDS_2149 "Audio kaseta: %s" - IDS_2150 "Slike audio kasete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Sve datoteke (*.*)\0*.*\0" - IDS_2151 "Kaseta %i: %ls" - IDS_2152 "Slike kasete (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Sve datoteke (*.*)\0*.*\0" - IDS_2153 "Nije moguće inicijalizirati renderer" - IDS_2154 "Nije moguće inicijalizirati OpenGL (3.0 jezgra) renderer. Molimte koristite drugi renderer." - IDS_2155 "Nastavi" - IDS_2156 "Pauziraj" - IDS_2157 "Stisni Ctrl+Alt+Del" - IDS_2158 "Stisni Ctrl+Alt+Esc" - IDS_2159 "Ponovno pokretanje" - IDS_2160 "ACPI bazirano gašenje" - IDS_2161 "Postavke" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Tvrdi disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL ili ESDI CD-ROM pogoni nisu nikada postojali" - IDS_4100 "Prilagođeno..." - IDS_4101 "Prilagođeno (veliko)..." - IDS_4102 "Dodajte novi tvrdi disk" - IDS_4103 "Dodajte postojeći tvrdi disk" - IDS_4104 "HDI disk image datoteke ne mogu biti veće od 4 GB." - IDS_4105 "Slike tvrdog diska ne mogu biti veće od 127 GB." - IDS_4106 "Slike za tvrde diskove (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Sve datoteke (*.*)\0*.*\0" - IDS_4107 "Nije moguće pročitati datoteku" - IDS_4108 "Nije moguće napisati datoteku" - IDS_4109 "HDI ili HDX slike s veličinom sektora koja nije 512 kB nisu podržane." - IDS_4110 "USB nije još podržano" - IDS_4111 "Slika diska već postoji" - IDS_4112 "Molimte unesite važeći naziv datoteke." - IDS_4113 "Slika je stvorena" - IDS_4114 "Provjerite je li postoji datoteka i je li čitljiva." - IDS_4115 "Provjerite je li se datoteka sprema u mapu s dopuštenjima za pisanje." - IDS_4116 "Slika diska je prevelika" - IDS_4117 "Ne zaboravite stvoriti particije i formatirati ih na novom disku." - IDS_4118 "Odabrana datoteka bit će prebrisana. Jeste li sigurni da želite koristiti ovu daoteku?" - IDS_4119 "Nepodržana slika diska" - IDS_4120 "Prepiši" - IDS_4121 "Ne prepiši" - IDS_4122 "Slika neobrađenih podataka (.img)" - IDS_4123 "HDI slika (.hdi)" - IDS_4124 "HDX slika (.hdx)" - IDS_4125 "VHD fiksne veličine (.vhd)" - IDS_4126 "VHD dinamičke veličine (.vhd)" - IDS_4127 "Različiti VHD (.vhd)" - IDS_4128 "Veliki blokovi (2 MB)" - IDS_4129 "Mali blokovi (512 KB)" - IDS_4130 "VHD slike (*.VHD)\0*.VHD\0Sve datoteke (*.*)\0*.*\0" - IDS_4131 "Izaberi matičnu sliku VHD" - IDS_4132 "To bi moglo značiti da je matična slika promijenjena nakon što je stvorena različita slika.\n\nTo se također može dogoditi ako su slike premještene ili kopirane, ili greška u programu koji je stvorio ovaj disk.\n\nŽelite li popraviti vremenske oznake?" - IDS_4133 "Vremenske ozanke matične i poređenog diska ne odgovaraju." - IDS_4134 "Ne mogu popraviti vremensku oznaku slike VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deaktivirano" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deaktivirano" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (1024 clusteri)" - IDS_5898 "DMF (2048 clusteri)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3,5"" 128 MB (ISO 10090)" - IDS_5903 "3,5"" 230 MB (ISO 13963)" - IDS_5904 "3,5"" 540 MB (ISO 15498)" - IDS_5905 "3,5"" 640 MB (ISO 15498)" - IDS_5906 "3,5"" 1.3 GB (GigaMO)" - IDS_5907 "3,5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5,25"" 600 MB" - IDS_5909 "5,25"" 650 MB" - IDS_5910 "5,25"" 1 GB" - IDS_5911 "5,25"" 1.3 GB" - - IDS_6144 "Savršeni broj okretaja u minuti" - IDS_6145 "1% ispod savršenog broja okretaja" - IDS_6146 "1,5% ispod savršenog broja okretaja" - IDS_6147 "2% ispod savršenog broja okretaja" - - IDS_7168 "(Zadana postavka operativnog sustava)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Croatian (hr-HR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc deleted file mode 100644 index 52189426a..000000000 --- a/src/win/languages/hu-HU.rc +++ /dev/null @@ -1,640 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Hungarian resources -// -// Translated by Laci bá', 2021 -// - -//#define TRANSLATORS_NAME "Laci bá'" - -#ifdef _WIN32 -LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Művelet" - BEGIN - MENUITEM "A &billentyűzet elfogást igényel", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "A &jobb oldali CTRL a bal ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "Hardveres &újraindítás...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Szüneteltetés", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Kilépés...", IDM_ACTION_EXIT - END - POPUP "&Nézet" - BEGIN - MENUITEM "Állapotsor &elrejtése", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Átméretezhető ablak", IDM_VID_RESIZE - MENUITEM "Méret és pozíció &megjegyzése", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Megjelenítő" - BEGIN - MENUITEM "&SDL (Szoftveres)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardveres)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Méretek kézi megadása...", IDM_VID_SPECIFY_DIM - MENUITEM "&Rögzített 4:3 képarány", IDM_VID_FORCE43 - POPUP "&Ablak méretezési tényező" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Szűrési mód" - BEGIN - MENUITEM "&Szomszédos", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineáris", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI méretezés", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Teljes képernyő\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Teljes képernyős &méretezés" - BEGIN - MENUITEM "&Nyújtás a teljes képernyőre", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Négyzetes képpontok (aránytartás)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Egész tényezős nagyítás", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA beállítások" - BEGIN - MENUITEM "&Invertált VGA kijelző", IDM_VID_INVERT - POPUP "VGA képernyő &típusa" - BEGIN - MENUITEM "RGB &színes", IDM_VID_GRAY_RGB - MENUITEM "&RGB szürkeárnyalatos", IDM_VID_GRAY_MONO - MENUITEM "&Gyömbér kijelző", IDM_VID_GRAY_AMBER - MENUITEM "&Zöld kijelző", IDM_VID_GRAY_GREEN - MENUITEM "&Fehér kijelző", IDM_VID_GRAY_WHITE - END - POPUP "Szürkéskála &konzerziós eljárás" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Átlag szerint", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA túlpásztázás", IDM_VID_OVERSCAN - MENUITEM "Kontraszt illesztése &monokróm kijelzőhöz", IDM_VID_CGACON - END - MENUITEM "&Média", IDM_MEDIA - POPUP "&Eszközök" - BEGIN - MENUITEM "&Konfigurálás...", IDM_CONFIG - MENUITEM "Állapotsori ikonok &frissítése", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Képernyőkép készítése\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Beállítások...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord integráció engedélyezése", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Hangerőszabályzó...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Nyomkövetés megkezdése\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Nyomkövetés befejezése\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Súgó" - BEGIN - MENUITEM "&Dokumentáció...", IDM_DOCS - MENUITEM "A 86Box &névjegye...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Felvétel", IDM_CASSETTE_RECORD - MENUITEM "&Lejátszás", IDM_CASSETTE_PLAY - MENUITEM "&Visszatekerés az elejére", IDM_CASSETTE_REWIND - MENUITEM "&Előretekerés a végére", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "Kép&fájl...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportálás 86F formátumba...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Némítás", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CDROM_EMPTY - MENUITEM "Előző képfájl &újratöltése", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_CDROM_IMAGE - MENUITEM "&Mappa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_ZIP_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_MO_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_MO_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Cél &képkockasebesség" - BEGIN - MENUITEM "&Szinkronizálás a videóval ", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Shader &kiválasztása...", IDM_VID_GL_SHADER - MENUITEM "Shader &eltávolítása", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Beállítások" -#define STR_SND_GAIN "Hangerőszabályzó" -#define STR_NEW_FLOPPY "Új képfájl létrehozása" -#define STR_CONFIG "Konfigurálás" -#define STR_SPECIFY_DIM "Főablak méreteinek megadása" - -#define STR_OK "OK" -#define STR_CANCEL "Mégse" -#define STR_GLOBAL "Beállítások mentése &globális alapértékként" -#define STR_DEFAULT "&Alapértelmezett" -#define STR_LANGUAGE "Nyelv:" -#define STR_ICONSET "Ikonkészlet:" - -#define STR_GAIN "Hangerő" - -#define STR_FILE_NAME "Fájlnév:" -#define STR_DISK_SIZE "Méret:" -#define STR_RPM_MODE "RPM-mód:" -#define STR_PROGRESS "Folyamat:" - -#define STR_WIDTH "Szélesség:" -#define STR_HEIGHT "Magasság:" -#define STR_LOCK_TO_SIZE "Rögzítés a megadott méretre" - -#define STR_MACHINE_TYPE "Géptípus:" -#define STR_MACHINE "Számítógép:" -#define STR_CONFIGURE "Beállítások..." -#define STR_CPU_TYPE "Processzor:" -#define STR_CPU_SPEED "Seb.:" -#define STR_FPU "FPU-egység:" -#define STR_WAIT_STATES "Várak. ciklusok:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Idő szinkronizáció" -#define STR_DISABLED "Letiltva" -#define STR_ENABLED_LOCAL "Engedélyezve (helyi idő)" -#define STR_ENABLED_UTC "Engedélyezve (UTC)" -#define STR_DYNAREC "Dinamikus újrafordítás" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Videokártya:" -#define STR_VIDEO_2 "Videokártya 2:" -#define STR_VOODOO "Voodoo-gyorsítókártya" -#define STR_IBM8514 "IBM 8514/A-gyorsítókártya" -#define STR_XGA "XGA-gyorsítókártya" - -#define STR_MOUSE "Egér:" -#define STR_JOYSTICK "Játékvezérlő:" -#define STR_JOY1 "Játékvez. 1..." -#define STR_JOY2 "Játékvez. 2..." -#define STR_JOY3 "Játékvez. 3..." -#define STR_JOY4 "Játékvez. 4..." - -#define STR_SOUND1 "Hangkártya 1:" -#define STR_SOUND2 "Hangkártya 2:" -#define STR_SOUND3 "Hangkártya 3:" -#define STR_SOUND4 "Hangkártya 4:" -#define STR_MIDI_OUT "MIDI-kimenet:" -#define STR_MIDI_IN "MIDI-bemenet:" -#define STR_MPU401 "Különálló MPU-401" -#define STR_FLOAT "FLOAT32 használata" -#define STR_FM_DRIVER "FM szintetizátor meghajtó" -#define STR_FM_DRV_NUKED "Nuked (pontosabb)" -#define STR_FM_DRV_YMFM "YMFM (gyorsabb)" - -#define STR_NET_TYPE "Hálózati típusa:" -#define STR_PCAP "PCap eszköz:" -#define STR_NET "Hálózati kártya:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 eszköz:" -#define STR_COM2 "COM2 eszköz:" -#define STR_COM3 "COM3 eszköz:" -#define STR_COM4 "COM4 eszköz:" -#define STR_LPT1 "LPT1 eszköz:" -#define STR_LPT2 "LPT2 eszköz:" -#define STR_LPT3 "LPT3 eszköz:" -#define STR_LPT4 "LPT4 eszköz:" -#define STR_SERIAL1 "Soros port 1" -#define STR_SERIAL2 "Soros port 2" -#define STR_SERIAL3 "Soros port 3" -#define STR_SERIAL4 "Soros port 4" -#define STR_PARALLEL1 "Párhuzamos port 1" -#define STR_PARALLEL2 "Párhuzamos port 2" -#define STR_PARALLEL3 "Párhuzamos port 3" -#define STR_PARALLEL4 "Párhuzamos port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Merevl.-vezérlő:" -#define STR_FDC "Floppy-vezérlő:" -#define STR_IDE_TER "Harmadlagos IDE-vezérlő" -#define STR_IDE_QUA "Negyedleges IDE-vezérlő" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Gazdaadapt. 1:" -#define STR_SCSI_2 "Gazdaadapt. 2:" -#define STR_SCSI_3 "Gazdaadapt. 3:" -#define STR_SCSI_4 "Gazdaadapt. 4:" -#define STR_CASSETTE "Magnókazetta" - -#define STR_HDD "Merevlemezek:" -#define STR_NEW "&Új..." -#define STR_EXISTING "&Megnyitás..." -#define STR_REMOVE "&Eltávolítás" -#define STR_BUS "Busz:" -#define STR_CHANNEL "Csatorna:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Kiválasztás..." -#define STR_SECTORS "Szektor:" -#define STR_HEADS "Fej:" -#define STR_CYLS "Cilinder:" -#define STR_SIZE_MB "Méret (MB):" -#define STR_TYPE "Típus:" -#define STR_IMG_FORMAT "Formátum:" -#define STR_BLOCK_SIZE "Blokkméret:" - -#define STR_FLOPPY_DRIVES "Floppy-meghajtók:" -#define STR_TURBO "Turbó időzítés" -#define STR_CHECKBPB "BPB ellenőrzés" -#define STR_CDROM_DRIVES "CD-ROM meghajtók:" -#define STR_CD_SPEED "Seb.:" - -#define STR_MO_DRIVES "MO-meghajtók:" -#define STR_ZIP_DRIVES "ZIP-meghajtók:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC (óra):" -#define STR_ISAMEM "ISA memóriabővítők" -#define STR_ISAMEM_1 "Kártya 1:" -#define STR_ISAMEM_2 "Kártya 2:" -#define STR_ISAMEM_3 "Kártya 3:" -#define STR_ISAMEM_4 "Kártya 4:" -#define STR_BUGGER "ISABugger eszköz" -#define STR_POSTCARD "POST kártya" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Hiba" - IDS_2050 "Végzetes hiba" - IDS_2051 " - PAUSED" - IDS_2052 "Használja a Ctrl+Alt+PgDn gombokat az ablakhoz való visszatéréshez." - IDS_2053 "Sebesség" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-lemezképek (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "A 86Box nem talált használható ROM-képeket\n\nKérem töltse le a ROM készletet és bontsa ki a ""roms"" könyvtárba." - IDS_2057 "(üres)" - IDS_2058 "ZIP-lemezképek (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Minden fájl (*.*)\0*.*\0" - IDS_2059 "Turbó" - IDS_2060 "Bekapcsolva" - IDS_2061 "Kikapcsolva" - IDS_2062 "Minden képfájl (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Alapvető szektor képfájlok (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Felületi képfájlok (*.86F)\0*.86F\0" - IDS_2063 "A számítógép ""%hs"" nem elérhető a ""roms/machines"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik gép kerül futtatásra." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A videokártya ""%hs"" nem elérhető a ""roms/video"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik kártya kerül futtatásra." - IDS_2065 "Számítógép" - IDS_2066 "Megjelenítő" - IDS_2067 "Beviteli eszközök" - IDS_2068 "Hang" - IDS_2069 "Hálózat" - IDS_2070 "Portok (COM és LPT)" - IDS_2071 "Tárolóvezérlők" - IDS_2072 "Merevlemezek" - IDS_2073 "Floppy és CD-ROM meghajtók" - IDS_2074 "Egyéb cserélhető tárolók" - IDS_2075 "Egyéb perifériák" - IDS_2076 "Felületi képfájlok (*.86F)\0*.86F\0" - IDS_2077 "Kattintson az egér elfogásához" - IDS_2078 "Nyomja meg az F8+F12-t az egér elengédéséhez" - IDS_2079 "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Busz" - IDS_2082 "Fájl" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB ellenőrzése" - IDS_2089 "KB" - IDS_2090 "Nem sikerült inicializálni a videó megjelenítőt." - IDS_2091 "Alapértelmezett" - IDS_2092 "%i várakozási ciklus(ok)" - IDS_2093 "Típus" - IDS_2094 "Nem sikerült a PCap beállítása" - IDS_2095 "Nem találhatóak PCap eszközök" - IDS_2096 "Érvénytelen PCap eszköz" - IDS_2097 "Szabványos 2-gombos játékvezérlő(k)" - IDS_2098 "Szabványos 4-gombos játékvezérlő" - IDS_2099 "Szabványos 6-gombos játékvezérlő" - IDS_2100 "Szabványos 8-gombos játékvezérlő" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nincs" - IDS_2105 "Nem lehet betölteni a billentyűzetgyorsítókat." - IDS_2106 "A közvetlen nyers bevitel regisztrálása nem sikerült." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" - IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" - IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2118 "Üdvözli önt az 86Box!" - IDS_2119 "Integrált vezérlő" - IDS_2120 "Kilépés" - IDS_2121 "Nem találhatóak meg a ROM-képek" - IDS_2122 "Szeretné menteni a beállításokat?" - IDS_2123 "Ezzel hardveresen újraindítja az emulált gépet." - IDS_2124 "Mentés" - IDS_2125 "A 86Box névjegye" - IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." - IDS_2128 "OK" - IDS_2129 "Hardver nem elérhető" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Győződjön meg hogy a(z) " LIB_NAME_PCAP " telepítve van és jelenleg a " LIB_NAME_PCAP "-kompatibilis kapcsolatot használja." - IDS_2131 "Érvénytelen konfiguráció" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." - IDS_2135 "Teljes képernyős módra váltás" - IDS_2136 "Ne jelenítse meg újra ezt az üzenetet " - IDS_2137 "Ne lépjen ki" - IDS_2138 "Újraindítás" - IDS_2139 "Ne indítsa újra" - IDS_2140 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2141 "CD-ROM-képek (*.ISO;*.CUE)\0*.ISO;*.CUE\0Minden fájl (*.*)\0*.*\0" - IDS_2142 "%hs eszközkonfiguráció" - IDS_2143 "Képernyő alvó módban" - IDS_2144 "OpenGL Shaderek (*.GLSL)\0*.GLSL\0Minden fájl (*.*)\0*.*\0" - IDS_2145 "OpenGL beállítások" - IDS_2146 "Egy nem támogatott konfigurációt tölt be" - IDS_2147 "A kiválasztott gépen alapuló CPU-típusszűrés le van tiltva ezen az emulált gépen.\n\nEz lehetővé teszi olyan CPU kiválasztását, amely egyébként nem kompatibilis a kiválasztott géppel. Előfordulhat azonban, hogy nem kompatibilis a gép BIOS-ával vagy más szoftverekkel.\n\nA beállítás engedélyezése hivatalosan nem támogatott, és a benyújtott hibajelentéseket érvénytelenként lezárhatjuk." - IDS_2148 "Folytatás" - IDS_2149 "Magnókazetta: %s" - IDS_2150 "Magnókazetta-képek (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Minden fájl (*.*)\0*.*\0" - IDS_2151 "ROM-kazetta %i: %ls" - IDS_2152 "ROM-kazetta képek (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Minden fájl (*.*)\0*.*\0" - IDS_2153 "Hiba történt a renderelő inicializálásakor" - IDS_2154 "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Merevlemez (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL vagy ESDI CD-ROM meghajtók soha nem léteztek" - IDS_4100 "Egyéni..." - IDS_4101 "Egyéni (nagy)..." - IDS_4102 "Új merevlemez hozzáadása" - IDS_4103 "Meglévő merevlemez hozzáadása" - IDS_4104 "A HDI lemezképek nem lehetnek nagyobbak 4 GB-nál." - IDS_4105 "A lemezképek mérete nem haladhatja meg a 127 GB-ot." - IDS_4106 "Merevlemez-képfájlok (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Minden fájl (*.*)\0*.*\0" - IDS_4107 "A fájl nem olvasható" - IDS_4108 "A fájl nem írható" - IDS_4109 "Az 512-től eltérő szektorméretű HDI vagy HDX képek nem támogatottak." - IDS_4110 "Az USB még nem támogatott" - IDS_4111 "A lemezképfájl már létezik" - IDS_4112 "Adjon meg egy érvényes fájlnevet." - IDS_4113 "A lemezképfájl létrehozásra került" - IDS_4114 "Győződjön meg arról, hogy a fájl létezik és olvasható." - IDS_4115 "Győződjön meg arról, hogy a fájlt egy írható könyvtárba menti." - IDS_4116 "A lemezképfájl túl nagy" - IDS_4117 "Ne felejtse el particionálni és formázni az újonnan létrehozott meghajtót." - IDS_4118 "A kiválasztott fájl felülírásra kerül. Biztos, hogy ezt kívánja használni?" - IDS_4119 "Nem támogatott lemezkép" - IDS_4120 "Felülírás" - IDS_4121 "Ne írja felül" - IDS_4122 "Nyers lemezkép (.img)" - IDS_4123 "HDI-lemezkép (.hdi)" - IDS_4124 "HDX-lemezkép (.hdx)" - IDS_4125 "Rögzített méretű VHD (.vhd)" - IDS_4126 "Dinamikusan bővülő VHD (.vhd)" - IDS_4127 "Különbség-VHD (.vhd)" - IDS_4128 "Nagy blokkméret (2 MB)" - IDS_4129 "Kis blokkméret (512 KB)" - IDS_4130 "VHD fájlok (*.VHD)\0*.VHD\0Minden fájl (*.*)\0*.*\0" - IDS_4131 "Válassza ki a szülő VHD-t" - IDS_4132 "Ez azt jelentheti, hogy a szülőkép módosult az eltérő kép létrehozása után.\n\nEz akkor is előfordulhat, ha a képfájlokat áthelyezték vagy másolták, vagy a lemezt létrehozó program hibája miatt.\n\nSzeretné kijavítani az időbélyegeket?" - IDS_4133 "A szülő- és a gyermeklemez időbélyegei nem egyeznek" - IDS_4134 "Nem sikerült kijavítani a VHD időbélyegét." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Letiltva" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Letiltva" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 klaszter)" - IDS_5898 "DMF (2048 klaszter)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Tökéletes RPM" - IDS_6145 "1%-kal a tökéletes RPM alatt" - IDS_6146 "1.5%-kal a tökéletes RPM alatt" - IDS_6147 "2%-kal a tökéletes RPM alatt" - - IDS_7168 "(A rendszer nyelve)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Hungarian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc deleted file mode 100644 index e5868caa0..000000000 --- a/src/win/languages/it-IT.rc +++ /dev/null @@ -1,637 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Italian (IT-it) resources - -#ifdef _WIN32 -LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN -#pragma code_page(65001) -#endif //_WIN32 - -// explorerdotexe -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Azione" - BEGIN - MENUITEM "&Tastiera richiede la cattura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&CTRL destro è ALT sinistro", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Riavvia...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&sci...", IDM_ACTION_EXIT - END - POPUP "&Visualizza" - BEGIN - MENUITEM "&Nascondi barra di stato", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Finestra ridimensionabile", IDM_VID_RESIZE - MENUITEM "R&icorda dimensioni e posizione", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specifica dimensioni...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orza display 4:3", IDM_VID_FORCE43 - POPUP "&Fattore scalare della finestra" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metodo filtro" - BEGIN - MENUITEM "&Dal più vicino", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineare", IDM_VID_FILTER_LINEAR - END - MENUITEM "Scala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Schermo intero\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modalità adattamento &schermo intero" - BEGIN - MENUITEM "&Adatta a schermo intero", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Pixel quadrati (mantiene l'aspetto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Scala intera", IDM_VID_FS_INT - END - POPUP "Impostazioni E&GA/(S)VGA" - BEGIN - MENUITEM "&Invertire monitor VGA", IDM_VID_INVERT - POPUP "Schermi VGA &" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "&RGB Monocroma", IDM_VID_GRAY_MONO - MENUITEM "&Monitor ambra", IDM_VID_GRAY_AMBER - MENUITEM "&Monitor verde", IDM_VID_GRAY_GREEN - MENUITEM "&Monitor bianco", IDM_VID_GRAY_WHITE - END - POPUP "Conversione &scala grigia" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&AMedia", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Sovrascansione CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Cambia il contrasto per &display monocromatici", IDM_VID_CGACON - END - MENUITEM "&Dispositivi", IDM_MEDIA - POPUP "&Strumenti" - BEGIN - MENUITEM "&Impostazioni...", IDM_CONFIG - MENUITEM "&Aggiorna icone della barra di stato", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Cattura schermata\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferenze...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Abilita &integrazione Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Guadagno &suono...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Inizia traccia\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Ferma traccia\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&?" - BEGIN - MENUITEM "&Documentazione...", IDM_DOCS - MENUITEM "&Informazioni su 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Registra", IDM_CASSETTE_RECORD - MENUITEM "R&iproduci", IDM_CASSETTE_PLAY - MENUITEM "Ri&avvolgi all'inizio", IDM_CASSETTE_REWIND - MENUITEM "A&vanti veloce alla fine", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Immagine...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&sporta in 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Muto", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CDROM_EMPTY - MENUITEM "&Ricarica l'immagine precedente", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Immagine...", IDM_CDROM_IMAGE - MENUITEM "&Cartella...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_ZIP_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_MO_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Imposta obiettivo &fotogrammi" - BEGIN - MENUITEM "&Sincronizza col video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 FPS", IDM_VID_GL_FPS_25 - MENUITEM "&30 FPS", IDM_VID_GL_FPS_30 - MENUITEM "&50 FPS", IDM_VID_GL_FPS_50 - MENUITEM "&60 FPS", IDM_VID_GL_FPS_60 - MENUITEM "&75 FPS", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Seleziona shader...", IDM_VID_GL_SHADER - MENUITEM "&Rimuovi shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferenze" -#define STR_SND_GAIN "Guadagno del suono" -#define STR_NEW_FLOPPY "Nuova immagine" -#define STR_CONFIG "Impostazioni" -#define STR_SPECIFY_DIM "Specifica dimensioni della finestra principale" - -#define STR_OK "OK" -#define STR_CANCEL "Annulla" -#define STR_GLOBAL "Salva queste impostazioni come &predefinite globali" -#define STR_DEFAULT "&Predefinito" -#define STR_LANGUAGE "Lingua:" -#define STR_ICONSET "Pacchetto di icone:" - -#define STR_GAIN "Guadagno" - -#define STR_FILE_NAME "Nome file:" -#define STR_DISK_SIZE "Dimensioni disco:" -#define STR_RPM_MODE "Modalità RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Larghezza:" -#define STR_HEIGHT "Altezza:" -#define STR_LOCK_TO_SIZE "Blocca in queste dimensioni" - -#define STR_MACHINE_TYPE "Tipo di piastra madre:" -#define STR_MACHINE "Piastra madre:" -#define STR_CONFIGURE "Configura" -#define STR_CPU_TYPE "Tipo del CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Stati di attesa:" -#define STR_MB "MB" -#define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronizzazione dell'ora" -#define STR_DISABLED "Disabilitata" -#define STR_ENABLED_LOCAL "Abilitata (ora locale)" -#define STR_ENABLED_UTC "Abilitata (UTC)" -#define STR_DYNAREC "Ricompilatore dinamico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Grafica Voodoo" -#define STR_IBM8514 "Grafica IBM 8514/A" -#define STR_XGA "Grafica XGA" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Scheda audio 1:" -#define STR_SOUND2 "Scheda audio 2:" -#define STR_SOUND3 "Scheda audio 3:" -#define STR_SOUND4 "Scheda audio 4:" -#define STR_MIDI_OUT "Uscita MIDI:" -#define STR_MIDI_IN "Entrata MIDI:" -#define STR_MPU401 "MPU-401 autonomo" -#define STR_FLOAT "Usa suono FLOAT32" -#define STR_FM_DRIVER "Driver sint. FM" -#define STR_FM_DRV_NUKED "Nuked (più accurato)" -#define STR_FM_DRV_YMFM "YMFM (più veloce)" - -#define STR_NET_TYPE "Tipo di rete:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Scheda di rete:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta seriale 1" -#define STR_SERIAL2 "Porta seriale 2" -#define STR_SERIAL3 "Porta seriale 3" -#define STR_SERIAL4 "Porta seriale 4" -#define STR_PARALLEL1 "Porta parallela 1" -#define STR_PARALLEL2 "Porta parallela 2" -#define STR_PARALLEL3 "Porta parallela 3" -#define STR_PARALLEL4 "Porta parallela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controller HD:" -#define STR_FDC "Controller FD:" -#define STR_IDE_TER "Controller IDE terziario" -#define STR_IDE_QUA "Controller IDE quaternario" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassetta" - -#define STR_HDD "Hard disk:" -#define STR_NEW "&Nuovo..." -#define STR_EXISTING "&Esistente..." -#define STR_REMOVE "&Rimouvi" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canale:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specifica..." -#define STR_SECTORS "Settori:" -#define STR_HEADS "Testine:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Dimensioni (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato immagine:" -#define STR_BLOCK_SIZE "Dimensioni blocco:" - -#define STR_FLOPPY_DRIVES "Unità floppy:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verifica BPB" -#define STR_CDROM_DRIVES "Unità CD-ROM:" -#define STR_CD_SPEED "Veloc.:" - -#define STR_MO_DRIVES "Unità magneto-ottiche:" -#define STR_ZIP_DRIVES "Unità ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "RTC ISA:" -#define STR_ISAMEM "Espansione memoria ISA" -#define STR_ISAMEM_1 "Scheda 1:" -#define STR_ISAMEM_2 "Scheda 2:" -#define STR_ISAMEM_3 "Scheda 3:" -#define STR_ISAMEM_4 "Scheda 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Scheda POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Errore" - IDS_2050 "Errore fatale" - IDS_2051 " - PAUSED" - IDS_2052 "Usa Ctrl+Alt+PgDn per tornare alla modalità finestra." - IDS_2053 "Velocità" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Immagini ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box non può trovare immagini ROM utilizzabili.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "Immagini ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Tutti i file (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Acceso" - IDS_2061 "Spento" - IDS_2062 "Tutte le immagini (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Immagini di settori base (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Immagini di superficie (*.86F)\0*.86F\0" - IDS_2063 "La macchina ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/machines. Cambiando ad una macchina disponibile." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La scheda video ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Cambiando ad una scheda video disponibile." - IDS_2065 "Piastra madre" - IDS_2066 "Schermo" - IDS_2067 "Dispositivi di entrata" - IDS_2068 "Audio" - IDS_2069 "Rete" - IDS_2070 "Porte (COM & LPT)" - IDS_2071 "Controller memoria" - IDS_2072 "Hard disk" - IDS_2073 "Unità CD-ROM e Floppy" - IDS_2074 "Altri dispositivi rimuovibili" - IDS_2075 "Altre periferiche" - IDS_2076 "Immagini di superficie (*.86F)\0*.86F\0" - IDS_2077 "Fare clic per catturare mouse" - IDS_2078 "Premi F8+F12 per rilasciare il mouse" - IDS_2079 "Premi F8+F12 o pulsante centrale per rilasciare il mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Verifica BPB" - IDS_2089 "KB" - IDS_2090 "Impossibile inizializzare il renderer video." - IDS_2091 "Predefinito" - IDS_2092 "%i stati d'attesa" - IDS_2093 "Tipo" - IDS_2094 "Impossibile impostare PCap" - IDS_2095 "Nessun dispositivo PCap trovato" - IDS_2096 "Dispositivo PCap invalido" - IDS_2097 "Joystick comune da 2 pulsanti" - IDS_2098 "Joystick comune da 4 pulsanti" - IDS_2099 "Joystick comune da 6 pulsanti" - IDS_2100 "Joystick comune da 8 pulsanti" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nessuno" - IDS_2105 "Impossibile caricare gli acceleratori da tastiera." - IDS_2106 "Impossibile registrare input raw." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" - IDS_2114 "Sei sicuro di voler uscire da 86Box?" - IDS_2115 "Impossibile inizializzare Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2118 "Benvenuti in 86Box!" - IDS_2119 "Controller interno" - IDS_2120 "Esci" - IDS_2121 "Nessune immagini ROM trovate" - IDS_2122 "Vuole salvare queste impostazioni?" - IDS_2123 "Questo riavvierà la macchina emulata." - IDS_2124 "Salva" - IDS_2125 "Informazioni su 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." - IDS_2128 "OK" - IDS_2129 "Hardware non disponibile" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Controlla se " LIB_NAME_PCAP " è installato e che tu sia connesso ad una connessione " LIB_NAME_PCAP " compatibile." - IDS_2131 "Configurazione invalida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" - IDS_2135 "Entrando nella modalità schermo intero" - IDS_2136 "Non mostrare più questo messaggio" - IDS_2137 "Non uscire" - IDS_2138 "Riavvia" - IDS_2139 "Non riavviare" - IDS_2140 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2141 "Immagini CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tutti i file (*.*)\0*.*\0" - IDS_2142 "Configurazione del dispositivo %hs" - IDS_2143 "Monitor in modalità riposo" - IDS_2144 "Shader OpenGL (*.GLSL)\0*.GLSL\0Tutti i file (*.*)\0*.*\0" - IDS_2145 "Impostazioni OpenGL" - IDS_2146 "Stai caricando una configurazione non supportata" - IDS_2147 "Il filtraggio della tipologia di CPU è disabilitato per la macchina selezionata.\n\nQuesto lo rende possibile scegliere un CPU che è altrimenti incompatibile con la macchina selezionata. Tuttavia, portresti incorrere in incompatibilità con il BIOS della macchina o altri programmi. \n\nL'abilitare di questa impostazione non è ufficialmente supportato e tutte le segnalazioni di errori saranno considerate invalide." - IDS_2148 "Continua" - IDS_2149 "Cassetta: %s" - IDS_2150 "Immagini cassetta (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tutti i file (*.*)\0*.*\0" - IDS_2151 "Cartuccia %i: %ls" - IDS_2152 "Immagini cartuccia (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tutti i file (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Le unità CD-ROM MFM/RLL o ESDI non sono mai esistite." - IDS_4100 "Personalizzata..." - IDS_4101 "Personalizzata (grande)..." - IDS_4102 "Aggiungi un nuovo disco rigido" - IDS_4103 "Aggiungi un disco rigido esistente" - IDS_4104 "Le immagini HDI non possono essere più grandi di 4 GB." - IDS_4105 "Le immmagini disco non possono essere più grandi di 127 GB." - IDS_4106 "Immagini disco rigido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tutti i file (*.*)\0*.*\0" - IDS_4107 "Impossibile leggere il file" - IDS_4108 "Impossibile scrivere al file" - IDS_4109 "Le immagini HDI o HDX con settori di dimensioni diverse da 512 non sono supportati." - IDS_4110 "USB non è ancora supportato" - IDS_4111 "Immagine disco già esiste" - IDS_4112 "Specifica un nome file valido." - IDS_4113 "Immagine disco creata" - IDS_4114 "Controlla che il file esiste e che sia leggibile." - IDS_4115 "Controlla che il file viene salvato ad un percorso con diritti di scrittura" - IDS_4116 "Immagine disco troppo grande" - IDS_4117 "Ricordati di partizionare e formattare il disco appena creato." - IDS_4118 "Il file selezionato sarà sovrascritto, sei sicuro di volerlo usare?" - IDS_4119 "Immagine disco non supportata" - IDS_4120 "Sovrascrivi" - IDS_4121 "Non sovrascrivere" - IDS_4122 "Immagine raw (.img)" - IDS_4123 "Immagine HDI (.hdi)" - IDS_4124 "Immagine HDX (.hdx)" - IDS_4125 "VHD di dimensioni fisse (.vhd)" - IDS_4126 "VHD di dimensioni dinamiche (.vhd)" - IDS_4127 "VHD differenziato (.vhd)" - IDS_4128 "Blocchi larghi (2 MB)" - IDS_4129 "Blocchi piccoli (512 KB)" - IDS_4130 "File VHD (*.VHD)\0*.VHD\0Tutti i file (*.*)\0*.*\0" - IDS_4131 "Seleziona il VHD padre." - IDS_4132 "Questo potrebbe significare che l'immagine padre sia stata modificata dopo la creazione dell'immagine di differenziazione.\n\nPuò anche succedere se i file immagini sono stati spostati o copiati, o da un errore nel programma che ha creato questo disco.\n\nVuoi aggiustare le marcature di tempo?" - IDS_4133 "Le marcature di tempo padre e figlio non corrispondono" - IDS_4134 "Impossibile aggiustare marcature di tempo VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabilitato" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabilitato" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfette" - IDS_6145 "RPM 1% sotto perfezione" - IDS_6146 "RPM 1.5% sotto perfezione" - IDS_6147 "RPM 2% sotto perfezione" - - IDS_7168 "(Predefinito del sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Italian (IT-it) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc deleted file mode 100644 index 74ae06092..000000000 --- a/src/win/languages/ja-JP.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Japanese resources - -#ifdef _WIN32 -LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "操作(&A)" - BEGIN - MENUITEM "キーボードはキャプチャが必要(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "右CTRLを左ALTへ変換(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "ハード リセット(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "一時停止(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "終了(&X)...", IDM_ACTION_EXIT - END - POPUP "表示(&V)" - BEGIN - MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "プライマリ以外のモニターを表示(&S)", IDM_VID_MONITORS - MENUITEM "ウィンドウのサイズを変更可能(&R)", IDM_VID_RESIZE - MENUITEM "ウィンドウのサイズと位置を保存(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "レンダラー(&N)" - BEGIN - MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "ディメンションを指定...", IDM_VID_SPECIFY_DIM - MENUITEM "4:3の縦横比を強制表示(&O)", IDM_VID_FORCE43 - POPUP "ウィンドウの表示倍率(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "フィルター方式" - BEGIN - MENUITEM "最近傍補間(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線形補間(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPIスケーリング(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全画面表示(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全画面の拡大表示モード(&S)" - BEGIN - MENUITEM "ストレッチ モード(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "正方形ピクセル(アスペクト比を維持)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数倍(&I)", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGAの設定" - BEGIN - MENUITEM "色反転(&I)", IDM_VID_INVERT - POPUP "画面タイプ(&T)" - BEGIN - MENUITEM "RGB(カラー)(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB(グレースケール)(&R)", IDM_VID_GRAY_MONO - MENUITEM "モニター(黄色)(&A)", IDM_VID_GRAY_AMBER - MENUITEM "モニター(緑色)(&G)", IDM_VID_GRAY_GREEN - MENUITEM "モニター(白色)(&W)", IDM_VID_GRAY_WHITE - END - POPUP "グレースケール変換タイプ(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGAオーバースキャン(&G)", IDM_VID_OVERSCAN - MENUITEM "単色モニター用コントラストを変更(&M)", IDM_VID_CGACON - END - MENUITEM "メディア(&M)", IDM_MEDIA - POPUP "ツール(&T)" - BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "ステータスバーのアイコンを更新(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "スクリーンショットを撮る(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "環境設定(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Discord連携機能(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量調整(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "トレース開始\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "トレース終了\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "ヘルプ(&H)" - BEGIN - MENUITEM "文書(&D)...", IDM_DOCS - MENUITEM "86Boxのバージョン情報(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "記録(&R)", IDM_CASSETTE_RECORD - MENUITEM "再生(&P)", IDM_CASSETTE_PLAY - MENUITEM "先頭まで巻き戻す(&R)", IDM_CASSETTE_REWIND - MENUITEM "最後まで早送り(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "イメージ(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "86Fイメージにエクスポート(&X)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "ミュート(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空(&M)", IDM_CDROM_EMPTY - MENUITEM "前のイメージを再読み込み(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "イメージ(&I)...", IDM_CDROM_IMAGE - MENUITEM "フォルダ(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_ZIP_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_MO_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目標フレームレート(&F)" - BEGIN - MENUITEM "ビデオと同期(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同期(VSync)(&V)", IDM_VID_GL_VSYNC - MENUITEM "シェーダーを選択(&S)...", IDM_VID_GL_SHADER - MENUITEM "シェーダーを削除(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "環境設定" -#define STR_SND_GAIN "音量調整" -#define STR_NEW_FLOPPY "新規のイメージ" -#define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "メイン ウィンドウのサイズ指定" - -#define STR_OK "OK" -#define STR_CANCEL "キャンセル" -#define STR_GLOBAL "これらの設定をグローバル既定値として保存(&G)" -#define STR_DEFAULT "既定値(&D)" -#define STR_LANGUAGE "言語:" -#define STR_ICONSET "アイコン セット:" - -#define STR_GAIN "音量" - -#define STR_FILE_NAME "ファイル名:" -#define STR_DISK_SIZE "ディスク サイズ:" -#define STR_RPM_MODE "RPMモード:" -#define STR_PROGRESS "進行状況:" - -#define STR_WIDTH "幅:" -#define STR_HEIGHT "高さ:" -#define STR_LOCK_TO_SIZE "サイズを固定" - -#define STR_MACHINE_TYPE "マシン タイプ:" -#define STR_MACHINE "マシン:" -#define STR_CONFIGURE "設定" -#define STR_CPU_TYPE "CPUタイプ:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "ウェイト ステート:" -#define STR_MB "MB" -#define STR_MEMORY "メモリ:" -#define STR_TIME_SYNC "時刻同期機能" -#define STR_DISABLED "無効" -#define STR_ENABLED_LOCAL "有効(現地時間)" -#define STR_ENABLED_UTC "有効(UTC)" -#define STR_DYNAREC "動的再コンパイル" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "ビデオカード:" -#define STR_VIDEO_2 "ビデオカード2:" -#define STR_VOODOO "Voodooグラフィック" -#define STR_IBM8514 "IBM 8514/Aグラフィック" -#define STR_XGA "XGAグラフィック" - -#define STR_MOUSE "マウス:" -#define STR_JOYSTICK "ジョイスティック:" -#define STR_JOY1 "ジョイスティック1..." -#define STR_JOY2 "ジョイスティック2..." -#define STR_JOY3 "ジョイスティック3..." -#define STR_JOY4 "ジョイスティック4..." - -#define STR_SOUND1 "サウンド カード1:" -#define STR_SOUND2 "サウンド カード2:" -#define STR_SOUND3 "サウンド カード3:" -#define STR_SOUND4 "サウンド カード4:" -#define STR_MIDI_OUT "MIDI出力デバイス:" -#define STR_MIDI_IN "MIDI入力デバイス:" -#define STR_MPU401 "独立型MPU-401" -#define STR_FLOAT "FLOAT32サウンドを使用" -#define STR_FM_DRIVER "FMシンセドライバー" -#define STR_FM_DRV_NUKED "Nuked(高精度化)" -#define STR_FM_DRV_YMFM "YMFM(より速く)" - -#define STR_NET_TYPE "ネットワークタイプ:" -#define STR_PCAP "PCapデバイス:" -#define STR_NET "ネットワークアダプター:" -#define STR_NET1 "ネットワーク カード1:" -#define STR_NET2 "ネットワーク カード2:" -#define STR_NET3 "ネットワーク カード3:" -#define STR_NET4 "ネットワーク カード4:" - -#define STR_COM1 "COM1デバイス:" -#define STR_COM2 "COM2デバイス:" -#define STR_COM3 "COM3デバイス:" -#define STR_COM4 "COM4デバイス:" -#define STR_LPT1 "LPT1デバイス:" -#define STR_LPT2 "LPT2デバイス:" -#define STR_LPT3 "LPT3デバイス:" -#define STR_LPT4 "LPT4デバイス:" -#define STR_SERIAL1 "シリアル ポート1" -#define STR_SERIAL2 "シリアル ポート2" -#define STR_SERIAL3 "シリアル ポート3" -#define STR_SERIAL4 "シリアル ポート4" -#define STR_PARALLEL1 "パラレル ポート1" -#define STR_PARALLEL2 "パラレル ポート2" -#define STR_PARALLEL3 "パラレル ポート3" -#define STR_PARALLEL4 "パラレル ポート4" -#define STR_SERIAL_PASS1 "シリアル ポート パススルー対応1" -#define STR_SERIAL_PASS2 "シリアル ポート パススルー対応2" -#define STR_SERIAL_PASS3 "シリアル ポート パススルー対応3" -#define STR_SERIAL_PASS4 "シリアル ポート パススルー対応4" - -#define STR_HDC "HDDコントローラー:" -#define STR_FDC "FDDコントローラー:" -#define STR_IDE_TER "第三IDEコントローラー" -#define STR_IDE_QUA "第四IDEコントローラー" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "コントローラー1:" -#define STR_SCSI_2 "コントローラー2:" -#define STR_SCSI_3 "コントローラー3:" -#define STR_SCSI_4 "コントローラー4:" -#define STR_CASSETTE "カセット" - -#define STR_HDD "ハード ディスク:" -#define STR_NEW "新規(&N)..." -#define STR_EXISTING "既定(&E)..." -#define STR_REMOVE "除去(&R)" -#define STR_BUS "バス:" -#define STR_CHANNEL "チャンネル:" -#define STR_ID "ID:" -#define STR_SPEED "速度:" - -#define STR_SPECIFY "参照(&S)..." -#define STR_SECTORS "セクター:" -#define STR_HEADS "ヘッド:" -#define STR_CYLS "シリンダー:" -#define STR_SIZE_MB "サイズ(MB):" -#define STR_TYPE "タイプ:" -#define STR_IMG_FORMAT "イメージ形式:" -#define STR_BLOCK_SIZE "ブロック サイズ:" - -#define STR_FLOPPY_DRIVES "フロッピー ドライブ:" -#define STR_TURBO "高速タイミング" -#define STR_CHECKBPB "BPBチェック" -#define STR_CDROM_DRIVES "CD-ROMドライブ:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "光磁気ドライブ:" -#define STR_ZIP_DRIVES "ZIPドライブ:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTCカード:" -#define STR_ISAMEM "ISAメモリ拡張カード" -#define STR_ISAMEM_1 "カード1:" -#define STR_ISAMEM_2 "カード2:" -#define STR_ISAMEM_3 "カード3:" -#define STR_ISAMEM_4 "カード4:" -#define STR_BUGGER "ISABuggerデバイス" -#define STR_POSTCARD "POSTカード" - -#define FONT_SIZE 9 -#define FONT_NAME "Meiryo UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "エラー" - IDS_2050 "致命的なエラー" - IDS_2051 " - 一時停止" - IDS_2052 "Ctrl+Alt+PgDnでウィンドウモードに戻ります。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Boxで使用可能なROMイメージが見つかりません。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" - IDS_2057 "(空)" - IDS_2058 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2059 "高速" - IDS_2060 "オン" - IDS_2061 "オフ" - IDS_2062 "すべてのイメージ (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0ベーシック セクター イメージ (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0サーフェス イメージ (*.86F)\0*.86F\0" - IDS_2063 "roms/machines ディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "roms/video ディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" - IDS_2065 "マシン" - IDS_2066 "ディスプレイ" - IDS_2067 "入力デバイス" - IDS_2068 "サウンド" - IDS_2069 "ネットワーク" - IDS_2070 "ポート (COM/LPT)" - IDS_2071 "ストレージ コントローラ" - IDS_2072 "ハード ディスク" - IDS_2073 "フロッピー/CD-ROMドライブ" - IDS_2074 "他のリムーバブル デバイス" - IDS_2075 "他の周辺デバイス" - IDS_2076 "サーフェス イメージ (*.86F)\0*.86F\0" - IDS_2077 "左クリックでマウスをキャプチャします" - IDS_2078 "F8+F12キーを押してマウスを解放します" - IDS_2079 "F8+F12キーまたは中クリックでマウスを解放します" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "バス" - IDS_2082 "ファイル" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPBチェック" - IDS_2089 "KB" - IDS_2090 "ビデオレンダラーが初期化できません。" - IDS_2091 "既定値" - IDS_2092 "%iつのウェイト ステート" - IDS_2093 "タイプ" - IDS_2094 "PCapのセットアップに失敗しました" - IDS_2095 "PCapデバイスがありません" - IDS_2096 "不正なPCapデバイス" - IDS_2097 "標準ジョイスティック(2ボタン)" - IDS_2098 "標準ジョイスティック(4ボタン)" - IDS_2099 "標準ジョイスティック(6ボタン)" - IDS_2100 "標準ジョイスティック(8ボタン)" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinderパッド" - IDS_2103 "Thrustmaster飛行制御システム" - IDS_2104 "なし" - IDS_2105 "キーボード アクセラレータを読み込めません。" - IDS_2106 "生入力が登録できません。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS値: %i、%i、%i)" - IDS_2109 "フロッピー %i (%s): %ls" - IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスド セクター イメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0ベーシック セクター イメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0サーフェス イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2113 "使用中のマシンをハードリ セットしますか?" - IDS_2114 "86Boxを終了しますか?" - IDS_2115 "Ghostscriptが初期化できません" - IDS_2116 "光磁気 %i (%ls): %ls" - IDS_2117 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2118 "86Boxへようこそ!" - IDS_2119 "内蔵コントローラー" - IDS_2120 "終了" - IDS_2121 "ROMが見つかりません" - IDS_2122 "設定を保存しますか?" - IDS_2123 "使用中のマシンがハードリ セットされます。" - IDS_2124 "保存" - IDS_2125 "86Boxのバージョン情報" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" - IDS_2128 "OK" - IDS_2129 "ハードウェアが利用できません" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" - IDS_2131 "無効な設定" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" - IDS_2135 "全画面モードを入力" - IDS_2136 "今後、このメッセージを表示しない" - IDS_2137 "終了しない" - IDS_2138 "リセット" - IDS_2139 "リセットしない" - IDS_2140 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2141 "CD-ROMイメージ (*.ISO;*.CUE)\0*.ISO;*.CUE\0すべてのファイル (*.*)\0*.*\0" - IDS_2142 "%hs のデバイス設定" - IDS_2143 "モニターのスリープ モード" - IDS_2144 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" - IDS_2145 "OpenGL設定" - IDS_2146 "読み込んでいる設定がサポートされません" - IDS_2147 "選択したマシンに基づくCPUタイプのフィルター機能は、使用中のマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。しかし、マシンのBIOSや他のソフトウェアと互換性がない場合があります。\n\nこの設定を有効にすることは公式にはサポートされておらず、バグレポートは無効として中止される可能性があります。" - IDS_2148 "続行" - IDS_2149 "カセット: %s" - IDS_2150 "カセット イメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" - IDS_2151 "カートリッジ %i: %ls" - IDS_2152 "カートリッジ イメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" - IDS_2153 "レンダラーの初期化エラー" - IDS_2154 "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" - IDS_2155 "実行を再開" - IDS_2156 "実行を一時停止" - IDS_2157 "Ctrl+Alt+DELを押す" - IDS_2158 "Ctrl+Alt+Escを押す" - IDS_2159 "ハードリセット" - IDS_2160 "ACPIシャットダウン" - IDS_2161 "設定" - IDS_2162 "タイプ" - IDS_2163 "動的再コンパイル禁止" - IDS_2164 "旧型の動的再コンパイル" - IDS_2165 "新型の動的再コンパイル" - IDS_2166 "「roms/video」ディレクトリにROMがないため、ビデオカード#2「%hs」は使用できません。2枚目のビデオカードを無効にします。" - IDS_2167 "ネットワーク ドライバの初期化に失敗しました。" - IDS_2168 "ネットワーク設定がヌル ドライバに切り替えられます" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "ハード ディスク (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLLやESDI CD-ROMドライブが存在しません" - IDS_4100 "カスタム..." - IDS_4101 "カスタム (大容量)..." - IDS_4102 "新規のディスクを追加" - IDS_4103 "既定のディスクを追加" - IDS_4104 "HDIディスク イメージは4GBを超えることはできません。" - IDS_4105 "ディスク イメージは127GBを超えることはできません。" - IDS_4106 "ハード ディスク イメージ (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0すべてのファイル (*.*)\0*.*\0" - IDS_4107 "ファイルの読み込みができません" - IDS_4108 "ファイルの書き込みができません" - IDS_4109 "512以外のセクタ サイズを持つHDIまたはHDXイメージは対応していません。" - IDS_4110 "USBはまだ非対応です" - IDS_4111 "ディスク イメージ ファイルが既に存在します" - IDS_4112 "有効なファイル名を指定してください。" - IDS_4113 "ディスク イメージが作成されました" - IDS_4114 "ファイルが存在し、読み取り可能であることを確認してください。" - IDS_4115 "ファイルが書き込み可能なディレクトリに保存されていることを確認してください。" - IDS_4116 "ディスク イメージのサイズが大きすぎます" - IDS_4117 "新規ドライブをパーティション分割し、フォーマットを必ずしといてください。" - IDS_4118 "選択したファイルは上書きされます。よろしいですか?" - IDS_4119 "非対応のディスク イメージ" - IDS_4120 "上書き" - IDS_4121 "上書きしない" - IDS_4122 "Rawイメージ (.img)" - IDS_4123 "HDIイメージ (.hdi)" - IDS_4124 "HDXイメージ (.hdx)" - IDS_4125 "VHD (容量固定) (.vhd)" - IDS_4126 "VHD (容量可変) (.vhd)" - IDS_4127 "VHD (差分) (.vhd)" - IDS_4128 "大型ブロック (2 MB)" - IDS_4129 "小型ブロック (512 KB)" - IDS_4130 "VHDファイル (*.VHD)\0*.VHD\0すべてのファイル (*.*)\0*.*\0" - IDS_4131 "親VHDの選択" - IDS_4132 "親イメージが差分イメージの作成の後に変更される可能性があります。\n\nイメージ ファイルが移動またはコピーされたか、イメージ ファイルを作成したプログラムにバグが発生した可能性があります。\n\nタイム スタンプを修正しますか?" - IDS_4133 "親ディスクと子ディスクのタイム スタンプが一致しません" - IDS_4134 "VHD のタイム スタンプを修正できません。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "使用しない" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "使用しない" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (クラスター1024)" - IDS_5898 "DMF (クラスター2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "既定RPM" - IDS_6145 "1%低いRPM" - IDS_6146 "1.5%低いRPM" - IDS_6147 "2%低いRPM" - - IDS_7168 "(システム既定値)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Japanese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc deleted file mode 100644 index a63090c9b..000000000 --- a/src/win/languages/ko-KR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Korean resources - -#ifdef _WIN32 -LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "동작(&A)" - BEGIN - MENUITEM "키보드는 캡쳐가 필요함(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "우측 CTRL로 좌측 ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "재시작(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "일시정지(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "끝내기(&X)...", IDM_ACTION_EXIT - END - POPUP "표시(&V)" - BEGIN - MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "툴바 숨기기", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "기본 모니터가 아닌 모니터 표시", IDM_VID_MONITORS - MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE - MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "렌더러(&N)" - BEGIN - MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "창 크기 지정하기...", IDM_VID_SPECIFY_DIM - MENUITEM "화면 비율을 4:3으로 맞추기(&O)", IDM_VID_FORCE43 - POPUP "창 표시 배율(&W)" - BEGIN - MENUITEM "0.5배(&0)", IDM_VID_SCALE_1X - MENUITEM "1배(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5배(&5)", IDM_VID_SCALE_3X - MENUITEM "2배(&2)", IDM_VID_SCALE_4X - MENUITEM "&3배", IDM_VID_SCALE_5X - MENUITEM "&4배", IDM_VID_SCALE_6X - MENUITEM "&5배", IDM_VID_SCALE_7X - MENUITEM "&6배", IDM_VID_SCALE_8X - MENUITEM "&7배", IDM_VID_SCALE_9X - MENUITEM "&8배", IDM_VID_SCALE_10X - END - POPUP "필터 형식" - BEGIN - MENUITEM "최근방 이웃 보간법(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "선형 보간법(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 스케일링(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "전체 화면(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "전체 화면 비율(&S)" - BEGIN - MENUITEM "전체 화면으로 확대(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "정사각형 픽셀 (비율 유지)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "정수배 확대(&I)", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA 설정" - BEGIN - MENUITEM "색상 반전된 VGA 모니터(&I)", IDM_VID_INVERT - POPUP "VGA 화면 종류(&T)" - BEGIN - MENUITEM "RGB 천연색(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 회색조(&R)", IDM_VID_GRAY_MONO - MENUITEM "주황색 모니터(&A)", IDM_VID_GRAY_AMBER - MENUITEM "녹색 모니터(&G)", IDM_VID_GRAY_GREEN - MENUITEM "흰색 모니터(&W)", IDM_VID_GRAY_WHITE - END - POPUP "회색조 표현방식(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "평균값(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 오버스캔(&G)", IDM_VID_OVERSCAN - MENUITEM "흑백 표시를 위한 밝기 조정(&M)", IDM_VID_CGACON - END - MENUITEM "미디어(&M)", IDM_MEDIA - POPUP "도구(&T)" - BEGIN - MENUITEM "설정(&S)...", IDM_CONFIG - MENUITEM "상태 바 아이콘 갱신하기(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "스크린샷 찍기(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "환경설정(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "디스코드 연동 활성화하기(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "음량 증폭(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "추적 시작하기\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "추적 끝내기\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "도움말(&H)" - BEGIN - MENUITEM "문서(&D)...", IDM_DOCS - MENUITEM "86Box에 대해(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "녹음하기(&R)", IDM_CASSETTE_RECORD - MENUITEM "재생하기(&P)", IDM_CASSETTE_PLAY - MENUITEM "맨앞으로 되감기(&R)", IDM_CASSETTE_REWIND - MENUITEM "맨끝으로 빨리감기(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "이미지(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "86F로 보내기(&X)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "음소거(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "비었음(&M)", IDM_CDROM_EMPTY - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "이미지(&I)...", IDM_CDROM_IMAGE - MENUITEM "폴더(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_ZIP_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_MO_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "목표 프레임 레이트(&F)" - BEGIN - MENUITEM "비디오와 동기(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "수직 동기화(&V)", IDM_VID_GL_VSYNC - MENUITEM "쉐이더 불러오기(&S)...", IDM_VID_GL_SHADER - MENUITEM "쉐이더 끄기(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "환경설정" -#define STR_SND_GAIN "음량 증폭" -#define STR_NEW_FLOPPY "새 이미지" -#define STR_CONFIG "설정" -#define STR_SPECIFY_DIM "창 크기 지정" - -#define STR_OK "확인" -#define STR_CANCEL "취소" -#define STR_GLOBAL "이 설정들을 전역 기본값으로 저장하기(&G)" -#define STR_DEFAULT "기본값(&D)" -#define STR_LANGUAGE "언어:" -#define STR_ICONSET "아이콘셋:" - -#define STR_GAIN "증가값" - -#define STR_FILE_NAME "파일명:" -#define STR_DISK_SIZE "디스크 용량:" -#define STR_RPM_MODE "RPM 모드:" -#define STR_PROGRESS "진행:" - -#define STR_WIDTH "가로:" -#define STR_HEIGHT "세로:" -#define STR_LOCK_TO_SIZE "크기 고정" - -#define STR_MACHINE_TYPE "머신 종류:" -#define STR_MACHINE "기종:" -#define STR_CONFIGURE "설정" -#define STR_CPU_TYPE "CPU 종류:" -#define STR_CPU_SPEED "속도:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "대기 상태:" -#define STR_MB "MB" -#define STR_MEMORY "메모리:" -#define STR_TIME_SYNC "시간 동기화" -#define STR_DISABLED "사용하지 않음" -#define STR_ENABLED_LOCAL "사용 (현지 시간)" -#define STR_ENABLED_UTC "사용 (UTC)" -#define STR_DYNAREC "동적 재컴파일" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "비디오 카드:" -#define STR_VIDEO_2 "비디오 카드 2:" -#define STR_VOODOO "Voodoo 그래픽" -#define STR_IBM8514 "IBM 8514/A 그래픽" -#define STR_XGA "XGA 그래픽" - -#define STR_MOUSE "마우스:" -#define STR_JOYSTICK "조이스틱:" -#define STR_JOY1 "조이스틱 1..." -#define STR_JOY2 "조이스틱 2..." -#define STR_JOY3 "조이스틱 3..." -#define STR_JOY4 "조이스틱 4..." - -#define STR_SOUND1 "사운드 카드 1:" -#define STR_SOUND2 "사운드 카드 2:" -#define STR_SOUND3 "사운드 카드 3:" -#define STR_SOUND4 "사운드 카드 4:" -#define STR_MIDI_OUT "MIDI 출력 장치:" -#define STR_MIDI_IN "MIDI 입력 장치:" -#define STR_MPU401 "MPU-401 단독 사용" -#define STR_FLOAT "FLOAT32 사운드 사용" -#define STR_FM_DRIVER "FM 신디사이저 드라이버" -#define STR_FM_DRV_NUKED "Nuked (더 정확한)" -#define STR_FM_DRV_YMFM "YMFM (더 빠르게)" - -#define STR_NET_TYPE "네트워크 종류:" -#define STR_PCAP "PCap 장치:" -#define STR_NET "네트워크 어댑터:" -#define STR_NET1 "네트워크 카드 1:" -#define STR_NET2 "네트워크 카드 2:" -#define STR_NET3 "네트워크 카드 3:" -#define STR_NET4 "네트워크 카드 4:" - -#define STR_COM1 "COM1 장치:" -#define STR_COM2 "COM2 장치:" -#define STR_COM3 "COM3 장치:" -#define STR_COM4 "COM4 장치:" -#define STR_LPT1 "LPT1 장치:" -#define STR_LPT2 "LPT2 장치:" -#define STR_LPT3 "LPT3 장치:" -#define STR_LPT4 "LPT4 장치:" -#define STR_SERIAL1 "직렬 포트 1" -#define STR_SERIAL2 "직렬 포트 2" -#define STR_SERIAL3 "직렬 포트 3" -#define STR_SERIAL4 "직렬 포트 4" -#define STR_PARALLEL1 "병렬 포트 1" -#define STR_PARALLEL2 "병렬 포트 2" -#define STR_PARALLEL3 "병렬 포트 3" -#define STR_PARALLEL4 "병렬 포트 4" -#define STR_SERIAL_PASS1 "직렬 포트 패스쓰루 1" -#define STR_SERIAL_PASS2 "직렬 포트 패스쓰루 2" -#define STR_SERIAL_PASS3 "직렬 포트 패스쓰루 3" -#define STR_SERIAL_PASS4 "직렬 포트 패스쓰루 4" - -#define STR_HDC "HD 컨트롤러:" -#define STR_FDC "FD 컨트롤러:" -#define STR_IDE_TER "제3의 IDE 컨트롤러" -#define STR_IDE_QUA "제4의 IDE 컨트롤러" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "컨트롤러 1:" -#define STR_SCSI_2 "컨트롤러 2:" -#define STR_SCSI_3 "컨트롤러 3:" -#define STR_SCSI_4 "컨트롤러 4:" -#define STR_CASSETTE "카세트 테이프" - -#define STR_HDD "하드 디스크:" -#define STR_NEW "새로 만들기(&N)..." -#define STR_EXISTING "불러오기(&E)..." -#define STR_REMOVE "목록에서 제거(&R)" -#define STR_BUS "버스:" -#define STR_CHANNEL "채널:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "열기(&S)..." -#define STR_SECTORS "섹터:" -#define STR_HEADS "헤드:" -#define STR_CYLS "실린더:" -#define STR_SIZE_MB "용량(MB):" -#define STR_TYPE "형식:" -#define STR_IMG_FORMAT "이미지 포맷:" -#define STR_BLOCK_SIZE "블록 크기:" - -#define STR_FLOPPY_DRIVES "플로피 드라이브:" -#define STR_TURBO "고속 동작" -#define STR_CHECKBPB "BPB 확인" -#define STR_CDROM_DRIVES "CD-ROM 드라이브:" -#define STR_CD_SPEED "속도:" - -#define STR_MO_DRIVES "광자기 드라이브:" -#define STR_ZIP_DRIVES "ZIP 드라이브:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC 카드:" -#define STR_ISAMEM "ISA 메모리 확장 카드" -#define STR_ISAMEM_1 "카드 1:" -#define STR_ISAMEM_2 "카드 2:" -#define STR_ISAMEM_3 "카드 3:" -#define STR_ISAMEM_4 "카드 4:" -#define STR_BUGGER "ISABugger 장치" -#define STR_POSTCARD "POST 카드" - -#define FONT_SIZE 9 -#define FONT_NAME "Malgun Gothic" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "오류" - IDS_2050 "치명적인 오류" - IDS_2051 " - 일시중지" - IDS_2052 "Ctrl+Alt+PgDn 키를 누르면 창 모드로 전환합니다." - IDS_2053 "속도" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 이미지 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box에서 사용 가능한 ROM 이미지를 찾을 수 없습니다.\n\nROM 세트를다운로드 후 ""roms"" 디렉토리에 압축을 풀어 주세요." - IDS_2057 "(비었음)" - IDS_2058 "ZIP 이미지 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0모든 파일 (*.*)\0*.*\0" - IDS_2059 "터보" - IDS_2060 "켜짐" - IDS_2061 "꺼짐" - IDS_2062 "모든 이미지 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0기본 섹터 이미지 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0표면 이미지 (*.86F)\0*.86F\0" - IDS_2063 "roms/machines 디렉토리에 필요한 롬파일이 없어 기종 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." - IDS_2065 "기종" - IDS_2066 "디스플레이" - IDS_2067 "입력 장치" - IDS_2068 "사운드" - IDS_2069 "네트워크" - IDS_2070 "포트 (COM & LPT)" - IDS_2071 "장치 컨트롤러" - IDS_2072 "하드 디스크" - IDS_2073 "플로피 / CD-ROM" - IDS_2074 "기타 이동식 저장장치" - IDS_2075 "기타 주변기기" - IDS_2076 "표면 이미지 (*.86F)\0*.86F\0" - IDS_2077 "이 창을 클릭하면 마우스를 사용합니다" - IDS_2078 "F12+F8키를 누르면 마우스를 해제합니다" - IDS_2079 "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "버스" - IDS_2082 "파일" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB 확인" - IDS_2089 "KB" - IDS_2090 "비디오 렌더러를 초기화할 수 없습니다." - IDS_2091 "기본값" - IDS_2092 "%i 대기 상태" - IDS_2093 "형식" - IDS_2094 "PCap 설정에 실패했습니다" - IDS_2095 "PCap 장치가 없습니다" - IDS_2096 "PCap 장치가 올바르지 않습니다" - IDS_2097 "표준 2버튼 조이스틱" - IDS_2098 "표준 4버튼 조이스틱" - IDS_2099 "표준 6버튼 조이스틱" - IDS_2100 "표준 8버튼 조이스틱" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "없음" - IDS_2105 "키보드 가속기를 불러올 수 없습니다." - IDS_2106 "Raw 입력을 등록할 수 없습니다." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "플로피 %i (%s): %ls" - IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2113 "실행중인 머신을 재시작하시겠습니까?" - IDS_2114 "86Box를 끝내시겠습니까?" - IDS_2115 "Ghostscript를 초기화할 수 없습니다" - IDS_2116 "광자기 %i (%ls): %ls" - IDS_2117 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2118 "86Box에 어서오세요!" - IDS_2119 "내부 컨트롤러" - IDS_2120 "끝내기" - IDS_2121 "ROM을 불러올 수 없습니다" - IDS_2122 "설정을 저장하시겠습니까?" - IDS_2123 "사용중인 머신이 재부팅됩니다." - IDS_2124 "저장" - IDS_2125 "86Box에 대해" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." - IDS_2128 "확인" - IDS_2129 "하드웨어를 이용할 수 없습니다" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 LIB_NAME_PCAP "이 설치되었는지 " LIB_NAME_PCAP "에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." - IDS_2131 "올바르지 않은 설정입니다" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." - IDS_2135 "전체 화면으로 전환" - IDS_2136 "이 메시지 그만 보기" - IDS_2137 "끝내지 않기" - IDS_2138 "재시작" - IDS_2139 "재시작 안함" - IDS_2140 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2141 "CD-ROM 이미지 (*.ISO;*.CUE)\0*.ISO;*.CUE\0모든 파일 (*.*)\0*.*\0" - IDS_2142 "%hs 장치 설정" - IDS_2143 "모니터 절전 모드" - IDS_2144 "OpenGL 쉐이더 (*.GLSL)\0*.GLSL\0모든 파일 (*.*)\0*.*\0" - IDS_2145 "OpenGL 설정" - IDS_2146 "지원하지 않는 설정입니다" - IDS_2147 "이 에뮬레이트된 기종에 대해 선택한 기종을 기반으로 하는 CPU 종류 필터링이 사용되지 않도록 설정되었습니다.\n\n따라서 선택된 머신과 호환되지 않는 CPU를 선택하실 수 있습니다. 하지만 BIOS 또는 다른 소프트웨어와 호환되지 않을 수 있습니다.\n\n이 설정을 활성화하는 것은 공식적으로 지원되지 않으며, 제출된 버그 보고서는 유효하지 않음으로 닫힐 수 있습니다." - IDS_2148 "계속" - IDS_2149 "카세트: %s" - IDS_2150 "카세트 이미지 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0모든 파일 (*.*)\0*.*\0" - IDS_2151 "카트리지 %i: %ls" - IDS_2152 "카트리지 이미지 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0모든 파일 (*.*)\0*.*\0" - IDS_2153 "렌더러 초기화 오류" - IDS_2154 "OpenGL (3.0 Core) 렌더러를 초기화할 수 없습니다. 다른 렌더러를 사용하십시오." - IDS_2155 "실행 재개" - IDS_2156 "실행 일시 중지" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "재시작" - IDS_2160 "ACPI 종료" - IDS_2161 "설정" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "두번째 비디오카드 ""%hs""는 roms/video 디렉토리에서 ROM이 누락되어 사용할 수 없습니다. 두번째 비디오 카드를 비활성화 합니다." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "하드 디스크 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL 또는 ESDI CD-ROM 드라이브가 존재하지 않습니다" - IDS_4100 "사용자 설정..." - IDS_4101 "사용자 설정 (대용량)..." - IDS_4102 "새로 생성" - IDS_4103 "기존 이미지 사용" - IDS_4104 "HDI 디스크 이미지는 4GB 이상으로 지정할 수 없습니다" - IDS_4105 "디스크 이미지는 127GB 이상으로 지정할 수 없습니다" - IDS_4106 "하드 디스크 이미지 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0모든 파일 (*.*)\0*.*\0" - IDS_4107 "파일을 읽을 수 없습니다" - IDS_4108 "파일을 저장할 수 없습니다" - IDS_4109 "512 바이트 이외의 섹터 크기를 가진 HDI 또는 HDX 형식의 이미지를 생성할 수 없습니다" - IDS_4110 "USB는 아직 지원하지 않습니다" - IDS_4111 "디스크 이미지 파일이 이미 존재합니다" - IDS_4112 "올바른 파일명을 지정해 주세요." - IDS_4113 "디스크 이미지가 생성되었습니다" - IDS_4114 "파일이 존재하며 읽을 수 있는지 확인합니다." - IDS_4115 "파일이 쓰기 가능한 디렉토리에 저장되고 있는지 확인합니다." - IDS_4116 "디스크 이미지가 너무 큽니다" - IDS_4117 "새로 생성한 드라이브의 파티션 설정과 포맷을 꼭 해주세요." - IDS_4118 "선택하신 파일을 덮어씌웁니다. 사용하시겠습니까?" - IDS_4119 "지원하지 않는 디스크 이미지입니다" - IDS_4120 "덮어쓰기" - IDS_4121 "덮어쓰지 않음" - IDS_4122 "Raw 이미지 (.img)" - IDS_4123 "HDI 이미지 (.hdi)" - IDS_4124 "HDX 이미지 (.hdx)" - IDS_4125 "고정 사이즈 VHD (.vhd)" - IDS_4126 "동적 사이즈 VHD (.vhd)" - IDS_4127 "디퍼런싱 VHD (.vhd)" - IDS_4128 "대형 블록 (2 MB)" - IDS_4129 "소형 블록 (512 KB)" - IDS_4130 "VHD 파일 (*.VHD)\0*.VHD\0모든 파일 (*.*)\0*.*\0" - IDS_4131 "부모 VHD 선택" - IDS_4132 "이는 디퍼런싱 이미지가 생성된 후 부모 이미지가 수정되었음을 의미할 수 있습니다.\n\n이미지 파일이 이동 또는 복사된 경우 또는 이 디스크를 만든 프로그램의 버그로 인해 발생할 수도 있습니다.\n\n타임스탬프를 수정하시겠습니까?" - IDS_4133 "부모 디스크와 자식 디스크의 타임스탬프가 일치하지 않습니다" - IDS_4134 "VHD 타임스탬프를 고칠 수 없습니다" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "사용하지 않음" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "사용하지 않음" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (클러스터 1024)" - IDS_5898 "DMF (클러스터 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "완벽한 회전수" - IDS_6145 "1% 낮은 회전수" - IDS_6146 "1.5% 낮은 회전수" - IDS_6147 "2% 낮은 회전수" - - IDS_7168 "(시스템 기본값)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Korean resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc deleted file mode 100644 index 623415045..000000000 --- a/src/win/languages/pl-PL.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Polish (pl-PL) resources - -#ifdef _WIN32 -LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Akcje" - BEGIN - MENUITEM "&Klawaitura wymaga przechwytu myszy", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Prawy CTRL to lewy Alt", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Twardy reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "W&yjdź...", IDM_ACTION_EXIT - END - POPUP "&Widok" - BEGIN - MENUITEM "&Ukryj pasek statusu", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ukryj &pasek narzędzi", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Okno o zmiennym rozmiarze", IDM_VID_RESIZE - MENUITEM "P&amiętaj rozmiar &i pozycję", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Określ rozmiary...", IDM_VID_SPECIFY_DIM - MENUITEM "&Wymuś proporcje wyświetlania 4:3", IDM_VID_FORCE43 - POPUP "&Czynnik skalowania okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda filtrowania" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Skalowanie Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Pełny ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Tryb rozciągania na pełnym ekranie", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kwadratowe piksele (Zachowaj proporcje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Skalowanie całkowite", IDM_VID_FS_INT - END - POPUP "Ustawienia E&GA/(S)VGA" - BEGIN - MENUITEM "&Odwrócony monitor VGA", IDM_VID_INVERT - POPUP "Rodzaj ekranu &VGA" - BEGIN - MENUITEM "RGB - &Kolorowy", IDM_VID_GRAY_RGB - MENUITEM "&RGB - Skala szarości", IDM_VID_GRAY_MONO - MENUITEM "&Bursztynowy monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Zielony monitor", IDM_VID_GRAY_GREEN - MENUITEM "&Biały monitor", IDM_VID_GRAY_WHITE - END - POPUP "Typ konwersji &w skali szarości" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Średni", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Zmień kontrast dla &monochromatycznego ekranu", IDM_VID_CGACON - END - MENUITEM "&Nośnik", IDM_MEDIA - POPUP "&Narzędzia" - BEGIN - MENUITEM "&Ustawienia...", IDM_CONFIG - MENUITEM "&Aktualizuj ikony na pasku statusu", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Zrób &zrzut ekranu\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferencje...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Włącz integrację z &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Wzmocnienie &dźwięku...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Rozpocznij śledzenie\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Zakończ śledzenie\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoc" - BEGIN - MENUITEM "&Dokumentacja...", IDM_DOCS - MENUITEM "&O 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nagraj", IDM_CASSETTE_RECORD - MENUITEM "&Odtwórz", IDM_CASSETTE_PLAY - MENUITEM "&Przewiń do początku", IDM_CASSETTE_REWIND - MENUITEM "&Przewiń do końca", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ksportuj do 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Ścisz", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "P&usty", IDM_CDROM_EMPTY - MENUITEM "&Przeładuj poprzedni obraz", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Teczka...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_ZIP_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_MO_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_MO_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Docelowa &liczba klatek na sekundę" - BEGIN - MENUITEM "&Zsynchronizuj z wideo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Wybierz shader...", IDM_VID_GL_SHADER - MENUITEM "&Usuń shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferencje" -#define STR_SND_GAIN "Wzmocnienie dźwięku" -#define STR_NEW_FLOPPY "Nowy obraz" -#define STR_CONFIG "Ustawienia" -#define STR_SPECIFY_DIM "Określ rozmiary okna" - -#define STR_OK "OK" -#define STR_CANCEL "Anuluj" -#define STR_GLOBAL "Zapisz ustawienia jako &globalne ustawienia domyślne" -#define STR_DEFAULT "&Domyślny" -#define STR_LANGUAGE "Język:" -#define STR_ICONSET "Zestaw ikon:" - -#define STR_GAIN "Wzmacniacz" - -#define STR_FILE_NAME "Nazwa pliku:" -#define STR_DISK_SIZE "Rozmiar dysku:" -#define STR_RPM_MODE "Tryb RPM:" -#define STR_PROGRESS "Postęp:" - -#define STR_WIDTH "Szerokość:" -#define STR_HEIGHT "Wysokość:" -#define STR_LOCK_TO_SIZE "Stały rozmiar" - -#define STR_MACHINE_TYPE "Rodzaj maszyny:" -#define STR_MACHINE "Maszyna:" -#define STR_CONFIGURE "Konfiguruj" -#define STR_CPU_TYPE "Rodzaj procesora:" -#define STR_CPU_SPEED "Szybkość:" -#define STR_FPU "Jednostka FPU:" -#define STR_WAIT_STATES "Stany oczekiwania:" -#define STR_MB "MB" -#define STR_MEMORY "Pamięć:" -#define STR_TIME_SYNC "Synchronizacja czasu" -#define STR_DISABLED "Wyłączona" -#define STR_ENABLED_LOCAL "Włączona (czas lokalny)" -#define STR_ENABLED_UTC "Włączona (UTC)" -#define STR_DYNAREC "Dynamiczny rekompilator" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Wideo:" -#define STR_VIDEO_2 "Wideo 2:" -#define STR_VOODOO "Grafika Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/A" -#define STR_XGA "Grafika XGA" - -#define STR_MOUSE "Mysz:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Karta dźwiękowa 1:" -#define STR_SOUND2 "Karta dźwiękowa 2:" -#define STR_SOUND3 "Karta dźwiękowa 3:" -#define STR_SOUND4 "Karta dźwiękowa 4:" -#define STR_MIDI_OUT "Urządzenie wyjściowe MIDI:" -#define STR_MIDI_IN "Urządzenie wejściowe MIDI:" -#define STR_MPU401 "Samodzielne urządzenie MPU-401" -#define STR_FLOAT "Użyj dźwięku FLOAT32" -#define STR_FM_DRIVER "Sterownik syntezy FM" -#define STR_FM_DRV_NUKED "Nuked (dokładniejszy)" -#define STR_FM_DRV_YMFM "YMFM (szybszy)" - -#define STR_NET_TYPE "Rodzaj sieci:" -#define STR_PCAP "Urządzenie PCap:" -#define STR_NET "Karta sieciowa:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Urządzenie COM1:" -#define STR_COM2 "Urządzenie COM2:" -#define STR_COM3 "Urządzenie COM3:" -#define STR_COM4 "Urządzenie COM4:" -#define STR_LPT1 "Urządzenie LPT1:" -#define STR_LPT2 "Urządzenie LPT2:" -#define STR_LPT3 "Urządzenie LPT3:" -#define STR_LPT4 "Urządzenie LPT4:" -#define STR_SERIAL1 "Port szeregowy 1" -#define STR_SERIAL2 "Port szeregowy 2" -#define STR_SERIAL3 "Port szeregowy 3" -#define STR_SERIAL4 "Port Szeregowy 4" -#define STR_PARALLEL1 "Port równoległy 1" -#define STR_PARALLEL2 "Port równoległy 2" -#define STR_PARALLEL3 "Port równoległy 3" -#define STR_PARALLEL4 "Port równoległy 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kontroler dysku twardego:" -#define STR_FDC "Kontroler dyskietek:" -#define STR_IDE_TER "Trzeciorzędowy kontroler IDE" -#define STR_IDE_QUA "Czwartorzędowy kontroler IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontroler 1:" -#define STR_SCSI_2 "Kontroler 2:" -#define STR_SCSI_3 "Kontroler 3:" -#define STR_SCSI_4 "Kontroler 4:" -#define STR_CASSETTE "Kaseta" - -#define STR_HDD "Dyski twarde:" -#define STR_NEW "&Nowy..." -#define STR_EXISTING "&Istniejący..." -#define STR_REMOVE "&Usuń" -#define STR_BUS "Magistrala:" -#define STR_CHANNEL "Kanał:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Określ..." -#define STR_SECTORS "Sektory:" -#define STR_HEADS "Głowice:" -#define STR_CYLS "Cylindry:" -#define STR_SIZE_MB "Rozmiar (MB):" -#define STR_TYPE "Rodzaj:" -#define STR_IMG_FORMAT "Format obrazu:" -#define STR_BLOCK_SIZE "Rozmiar bloku:" - -#define STR_FLOPPY_DRIVES "Napędy dyskietek:" -#define STR_TURBO "Rozrządy Turbo" -#define STR_CHECKBPB "Sprawdzaj BPB" -#define STR_CDROM_DRIVES "Napędy CD-ROM:" -#define STR_CD_SPEED "Szybkość:" - -#define STR_MO_DRIVES "Napędy MO:" -#define STR_ZIP_DRIVES "Napędy ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Rozszerzenie pamięci ISA" -#define STR_ISAMEM_1 "Karta 1:" -#define STR_ISAMEM_2 "Karta 2:" -#define STR_ISAMEM_3 "Karta 3:" -#define STR_ISAMEM_4 "Karta 4:" -#define STR_BUGGER "Urządzenie ISABugger" -#define STR_POSTCARD "Karta POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Błąd" - IDS_2050 "Fatalny błąd" - IDS_2051 " - PAUSED" - IDS_2052 "Naciśnij klawisze Ctrl+Alt+PgDn aby wrócić to trybu okna." - IDS_2053 "Szybkość" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Obrazy ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nie może znaleźć obrazów ROM nadających się do użytku.\n\nProszę pobrać zestaw obrazów ROM ze strony download, i rozpakować je do katalogu ""roms""." - IDS_2057 "(pusty)" - IDS_2058 "Obrazy ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Włącz" - IDS_2061 "Wyłącz" - IDS_2062 "Wszystkie obrazy (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Podstawowe obrazy sektorów(*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Obrazy powierzchniowe (*.86F)\0*.86F\0" - IDS_2063 "Maszyna ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/machines. Przełączanie na dostępną maszynę." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Karta wideo ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Przełączanie na dostępną kartę wideo." - IDS_2065 "Maszyna" - IDS_2066 "Ekran" - IDS_2067 "Urządzenia wejściowe" - IDS_2068 "Dźwięk" - IDS_2069 "Sieć" - IDS_2070 "Porty (COM & LPT)" - IDS_2071 "Kontrolery pamięci" - IDS_2072 "Dyski twarde" - IDS_2073 "Napędy dyskietek i CD-ROM" - IDS_2074 "Inne urządzenia wymienne" - IDS_2075 "Inne urządzenia peryferyjne" - IDS_2076 "Obrazy powierzchniowe (*.86F)\0*.86F\0" - IDS_2077 "Kliknij w celu przechwycenia myszy" - IDS_2078 "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" - IDS_2079 "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Magistrala" - IDS_2082 "Plik" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Sprawdzaj BPB" - IDS_2089 "KB" - IDS_2090 "Nie można zainicjować renderera wideo." - IDS_2091 "Domyślny" - IDS_2092 "%i Stany oczekiwania" - IDS_2093 "Rodzaj" - IDS_2094 "Nie udało się ustawić PCap" - IDS_2095 "Nie znaleziono urządzeń PCap" - IDS_2096 "Nieprawidłowe urządzenie PCap" - IDS_2097 "Standardowe joysticki 2-przyciskowe" - IDS_2098 "Standardowy joystick 4-przyciskowy" - IDS_2099 "Standardowy joystick 6-przyciskowy" - IDS_2100 "Standardowy joystick 8-przyciskowy" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Żaden" - IDS_2105 "Nie można załadować akceleratorów klawiaturowych." - IDS_2106 "Nie można zarejestrować surowych danych wejściowych." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Dyskietka %i (%s): %ls" - IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" - IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" - IDS_2115 "Nie można zainicjować Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Witamy w 86Box!" - IDS_2119 "Kontroler wewnętrzny" - IDS_2120 "Zakończ" - IDS_2121 "Nie znaleziono obrazów ROM" - IDS_2122 "Czy chcesz zapisać ustawienia?" - IDS_2123 "To spowoduje twardy reset wirtualnej maszyny." - IDS_2124 "Zapisz" - IDS_2125 "O 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i inni.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." - IDS_2128 "OK" - IDS_2129 "Sprzęt niedostępny" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Sprawdź, czy " LIB_NAME_PCAP " jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z " LIB_NAME_PCAP "." - IDS_2131 "Nieprawidłowa konfiguracja" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." - IDS_2135 "Przechodzenie do trybu pełnoekranowego" - IDS_2136 "Nie pokazuj więcej tego komunikatu" - IDS_2137 "Nie kończ" - IDS_2138 "Przywróć" - IDS_2139 "Nie przywracaj" - IDS_2140 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "Obrazy CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "Konfiguracja urządzenia %hs" - IDS_2143 "Monitor w trybie czuwania" - IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2145 "Opcje OpenGL" - IDS_2146 "Ładujesz nieobsługiwaną konfigurację" - IDS_2147 "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." - IDS_2148 "Kontynuuj" - IDS_2149 "Kaseta: %s" - IDS_2150 "Obrazy kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2151 "Kartrydż %i: %ls" - IDS_2152 "Obrazy kartrydżu (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2153 "Błąd inicjalizacji renderera" - IDS_2154 "Nie można zainicjować renderera OpenGL (3.0 Core). Użyj innego." - IDS_2155 "Wznów wykonywanie" - IDS_2156 "Zatrzymaj wykonywanie" - IDS_2157 "Naciśnij Ctrl+Alt+Del" - IDS_2158 "Naciśnij Ctrl+Alt+Esc" - IDS_2159 "Twardy reset" - IDS_2160 "Wyłączenie ACPI" - IDS_2161 "Ustawienia" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Dysk twardy (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Napędy CD-ROM MFM/RLL lub ESDI nigdy nie istniały" - IDS_4100 "Niestandardowy..." - IDS_4101 "Niestandardowy (duży)..." - IDS_4102 "Dodaj nowy dysk twardy" - IDS_4103 "Dodaj istniejący dysk twardy" - IDS_4104 "Obrazy dysków HDI nie mogą być większe niż 4 GB." - IDS_4105 "Obrazy dysków nie mogą być większe niż 127 GB." - IDS_4106 "Obrazy dysku twardego (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Wszystkie pliki (*.*)\0*.*\0" - IDS_4107 "Nie można odczytać pliku" - IDS_4108 "Nie można zapisać pliku" - IDS_4109 "Obrazy HDI lub HDX z rozmiarem sektora innym niż 512 nie są wspierane." - IDS_4110 "USB nie jest jeszcze wspierane" - IDS_4111 "Plik obrazu dysku już istnieje" - IDS_4112 "Określ prawidłową nazwę pliku." - IDS_4113 "Utworzono obraz dysku" - IDS_4114 "Sprawdź, czy plik istnieje i nadaje się do odczytu." - IDS_4115 "Sprawdź, czy plik jest zapiyswany w katalogu z możliwością zapisu." - IDS_4116 "Obraz dysku jest za duży" - IDS_4117 "Nie zapomnij o partycjonowaniu i sformatowaniu nowo utworzego dysku" - IDS_4118 "Wybrany plik zostanie nadpisany. Czy na pewno chcesz użyć tego pliku?" - IDS_4119 "Niewspierany obraz dysku" - IDS_4120 "Nadpisz" - IDS_4121 "Nie nadpisuj" - IDS_4122 "Obraz surowy (.img)" - IDS_4123 "Obraz HDI (.hdi)" - IDS_4124 "Obraz HDX (.hdx)" - IDS_4125 "VHD o stałym rozmiarze (.vhd)" - IDS_4126 "VHD o dynamicznym rozmiarze (.vhd)" - IDS_4127 "VHD różnicujący (.vhd)" - IDS_4128 "Duże bloki (2 MB)" - IDS_4129 "Małe bloki (512 KB)" - IDS_4130 "Pliki VHD (*.VHD)\0*.VHD\0Wszystkie pliki (*.*)\0*.*\0" - IDS_4131 "Wybierz nadrzędny plik VHD" - IDS_4132 "Może to oznaczać, że obraz nadrzędny został zmodyfikowany po utworzeniu obrazu różnicującego.\n\nMoże się to również zdarzyć, jeśli pliki obrazów zostały przeniesione lub skopiowane, lub wystąpił błąd w programie, który utworzył ten dysk\n\nCzy chcesz naprawić sygnatury czasowe?" - IDS_4133 "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" - IDS_4134 "Nie można naprawić sygnatury czasowej VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Wyłączony" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Wyłączony" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (klaster 1024)" - IDS_5898 "DMF (klaster 2048)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1,3 GB (GigaMO)" - IDS_5907 "3.5"" 2,3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1,3 GB" - - IDS_6144 "Idealne obroty" - IDS_6145 "1% poniżej idealnych obrotów" - IDS_6146 "1.5% poniżej idealnych obrotów" - IDS_6147 "2% poniżej idealnych obrotów" - - IDS_7168 "(Domyślne ustawienie systemowe)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Polish (pl-PL) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc deleted file mode 100644 index 4f72a41a4..000000000 --- a/src/win/languages/pt-BR.rc +++ /dev/null @@ -1,639 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Portuguese (pt-BR) resources -// -// Translated by Altieres Lima da Silva, 2021 -// - -#ifdef _WIN32 -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Ação" - BEGIN - MENUITEM "&Teclado requer captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &direito é o ALT esquerdo", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Reinicialização completa...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausar", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT - END - POPUP "&Exibir" - BEGIN - MENUITEM "&Ocultar barra de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ocultar &barra de ferramenta", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Mostrar monitores não-primários", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Especificar as dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orçar proporção de tela em 4:3", IDM_VID_FORCE43 - POPUP "&Fator de redimensionamento da janela" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Método de filtragem" - BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Tela cheia\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modo de &redimensionamento da tela cheia" - BEGIN - MENUITEM "&Tela cheia esticada", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "Pixel&s quadrados (manter proporção)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Redimensionamento com valores inteiros", IDM_VID_FS_INT - END - POPUP "Configurações E&GA/(S)VGA" - BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT - POPUP "&Tipo de tela VGA" - BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO - MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE - END - POPUP "Tipo de &conversão de tons de cinza" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Média", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan do CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Alterar contraste para exibição &monocromática", IDM_VID_CGACON - END - MENUITEM "&Mídia", IDM_MEDIA - POPUP "&Ferramentas" - BEGIN - MENUITEM "&Configurações...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de status", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Capturar &tela\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Ativar integração com o &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Inicio do rastreamento\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Fim do rastreamento\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ajuda" - BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Sobre o 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar até o começo", IDM_CASSETTE_REWIND - MENUITEM "&Avançar até o fim", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Sem som", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taxa de quadro pretendida" - BEGIN - MENUITEM "&Sincronizar com vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 qps", IDM_VID_GL_FPS_25 - MENUITEM "&30 qps", IDM_VID_GL_FPS_30 - MENUITEM "&50 qps", IDM_VID_GL_FPS_50 - MENUITEM "&60 qps", IDM_VID_GL_FPS_60 - MENUITEM "&75 qps", IDM_VID_GL_FPS_75 - END - MENUITEM "Sincronização &vertical", IDM_VID_GL_VSYNC - MENUITEM "&Selecionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Remover shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem de disquete" -#define STR_CONFIG "Configurações" -#define STR_SPECIFY_DIM "Especifique as dimensões da janela principal" - -#define STR_OK "OK" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Usar estas configurações como &padrões globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" - -#define STR_GAIN "Ganho" - -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Largura:" -#define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Travar nesse tamanho" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativar" -#define STR_ENABLED_LOCAL "Ativar (hora local)" -#define STR_ENABLED_UTC "Ativar (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/A" -#define STR_XGA "Gráficos XGA" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Placa de som 1:" -#define STR_SOUND2 "Placa de som 2:" -#define STR_SOUND3 "Placa de som 3:" -#define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" -#define STR_MPU401 "MPU-401 autônomo" -#define STR_FLOAT "Usar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais preciso)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" - -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de rede:" -#define STR_NET1 "Placa de rede 1:" -#define STR_NET2 "Placa de rede 2:" -#define STR_NET3 "Placa de rede 3:" -#define STR_NET4 "Placa de rede 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta serial 1" -#define STR_SERIAL2 "Porta serial 2" -#define STR_SERIAL3 "Porta serial 3" -#define STR_SERIAL4 "Porta serial 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Encaminhamento de porta serial 1" -#define STR_SERIAL_PASS2 "Encaminhamento de porta serial 2" -#define STR_SERIAL_PASS3 "Encaminhamento de porta serial 3" -#define STR_SERIAL_PASS4 "Encaminhamento de porta serial 4" - -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controlador 1:" -#define STR_SCSI_2 "Controlador 2:" -#define STR_SCSI_3 "Controlador 3:" -#define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" - -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "&Remover" -#define STR_BUS "Bar.:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Velocidade:" - -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Setores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato:" -#define STR_BLOCK_SIZE "Blocos:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Veloc.:" - -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "RTC ISA:" -#define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa de diagnóstico" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erro" - IDS_2050 "Erro fatal" - IDS_2051 " - PAUSADO" - IDS_2052 "Use Ctrl+Alt+PgDn para retornar ao modo janela" - IDS_2053 "Velocidade" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "O 86Box não conseguiu encontrar nenhuma imagem de ROM utilizável.\n\nPor favor, baixe um conjunto de ROM e extraia no diretório ""roms""." - IDS_2057 "(vazio)" - IDS_2058 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Lig." - IDS_2061 "Desl." - IDS_2062 "Todas as imagens (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Imagens de setor básico (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Imagens de superfície (*.86F)\0*.86F\0" - IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs no diretório roms/machines. Mudando para uma máquina disponível." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A placa de vídeo ""%hs"" não está disponível devido à falta de ROMs no diretório roms/video. Mudando para uma placa de vídeo disponível." - IDS_2065 "Máquina" - IDS_2066 "Vídeo" - IDS_2067 "Dispositivos de entrada" - IDS_2068 "Som" - IDS_2069 "Rede" - IDS_2070 "Portas (COM & LPT)" - IDS_2071 "Controladores de armaz." - IDS_2072 "Discos rígidos" - IDS_2073 "Disquete & CD-ROM" - IDS_2074 "Dispos. removíveis" - IDS_2075 "Outros periféricos" - IDS_2076 "Imagens de superfície (*.86F)\0*.86F\0" - IDS_2077 "Clique para capturar o mouse" - IDS_2078 "Aperte F8+F12 para liberar o mouse" - IDS_2079 "Aperte F8+F12 ou botão do meio para liberar o mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Barramento" - IDS_2082 "Arquivo" - IDS_2083 "CI" - IDS_2084 "CA" - IDS_2085 "SE" - IDS_2086 "MB" - IDS_2087 "Velocidade" - IDS_2088 "Verificar BPB" - IDS_2089 "KB" - IDS_2090 "Não foi possível inicializar o renderizador de vídeo." - IDS_2091 "Padrão" - IDS_2092 "%i estado(s) de espera" - IDS_2093 "Tipo" - IDS_2094 "Não foi possível configurar o PCap" - IDS_2095 "Nenhum dispositivo PCap encontrado" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Joystick padrão de 2 botões" - IDS_2098 "Joystick padrão de 4 botões" - IDS_2099 "Joystick padrão de 6 botões" - IDS_2100 "Joystick padrão de 8 botões" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Sistema de Controle de Voo Thrustmaster" - IDS_2104 "Nada" - IDS_2105 "Não foi possível carregar os aceleradores do teclado." - IDS_2106 "Não foi possível registrar a entrada bruta." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" - IDS_2114 "Tem certeza de que deseja sair do 86Box?" - IDS_2115 "Não é possível inicializar o Ghostscript" - IDS_2116 "Magneto-óptico %i (%ls): %ls" - IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2118 "Bem-vindo ao 86Box!" - IDS_2119 "Controlador interno" - IDS_2120 "Sair" - IDS_2121 "Nenhum ROM encontrada" - IDS_2122 "Você deseja salvar as configurações?" - IDS_2123 "Isto fará com que a máquina emulada seja reinicializada." - IDS_2124 "Salvar" - IDS_2125 "Sobre o 86Box" - IDS_2126 "86Box versão" EMU_VERSION - - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." - IDS_2128 "OK" - IDS_2129 "Hardware não disponível" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Certifique-se de que " LIB_NAME_PCAP " esteja instalado e que você tenha uma conexão de rede compatível com " LIB_NAME_PCAP "." - IDS_2131 "Configuração inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." - IDS_2135 "Entrando no modo de tela cheia" - IDS_2136 "Não exibir esta mensagem novamente" - IDS_2137 "Não sair" - IDS_2138 "Reiniciar" - IDS_2139 "Não reiniciar" - IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2141 "Imagens de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os arquivos (*.*)\0*.*\0" - IDS_2142 "Configuração do dispositivo %hs" - IDS_2143 "Monitor em modo de suspensão" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os arquivos (*.*)\0*.*\0" - IDS_2145 "Opções do OpenGL" - IDS_2146 "Você está carregando uma configuração não suportada" - IDS_2147 "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." - IDS_2148 "Continuar" - IDS_2149 "Cassete: %s" - IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os arquivos (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os arquivos (*.*)\0*.*\0" - IDS_2153 "Erro ao inicializar o renderizador" - IDS_2154 "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." - IDS_2155 "Continuar a execução" - IDS_2156 "Pausar a execução" - IDS_2157 "Pressionar Ctrl+Alt+Del" - IDS_2158 "Pressionar Ctrl+Alt+Esc" - IDS_2159 "Reinicialização completa" - IDS_2160 "Desligamento por ACPI" - IDS_2161 "Configurações" - IDS_2162 "Tipo" - IDS_2163 "Sem recompilador dinâmico" - IDS_2164 "Recompilador dinâmico antigo" - IDS_2165 "Novo recompilador dinâmico" - IDS_2166 "A placa de vídeo #2 ""%hs"" não está disponível devido à ausência de ROMs no diretório roms/video. Desabilitando a segunda placa de vídeo." - IDS_2167 "Falha ao inicializar o driver de rede" - IDS_2168 "A configuração de rede será alterada para o driver nulo" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco rígido (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "As unidades de CD-ROM MFM/RLL ou ESDI nunca existiram" - IDS_4100 "Personalizado..." - IDS_4101 "Personalizado (grande)..." - IDS_4102 "Adicionar novo disco rígido" - IDS_4103 "Adicionar disco rígido existente" - IDS_4104 "As imagens de disco HDI não podem ser maiores do que 4GB." - IDS_4105 "As imagens de disco não podem ser maiores do que 127GB." - IDS_4106 "Imagens de disco rígido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Todos os arquivos (*.*)\0*.*\0" - IDS_4107 "Não foi possível ler o arquivo" - IDS_4108 "Não foi possível escrever o arquivo" - IDS_4109 "Imagens HDI ou HDX com um tamanho de setor que não seja 512 não são suportadas." - IDS_4110 "O USB ainda não é suportado" - IDS_4111 "Esta imagem existe" - IDS_4112 "Digite um nome de arquivo válido." - IDS_4113 "A imagem foi criada com sucesso" - IDS_4114 "Certifique-se de que o arquivo existe e é legível." - IDS_4115 "Certifique-se de que o arquivo está sendo salvo em um diretório gravável." - IDS_4116 "A imagem do disco é muito grande" - IDS_4117 "Lembre-se de particionar e formatar a unidade recém-criada." - IDS_4118 "O arquivo selecionado será sobrescrito. Você tem certeza de que deseja usá-lo?" - IDS_4119 "Imagem de disco sem suporte" - IDS_4120 "Sobrescrever" - IDS_4121 "Não sobrescrever" - IDS_4122 "Imagem bruta (.img)" - IDS_4123 "Imagem HDI (.hdi)" - IDS_4124 "Imagem HDX (.hdx)" - IDS_4125 "VHD de tamanho fixo (.vhd)" - IDS_4126 "VHD de tamanho dinâmico (.vhd)" - IDS_4127 "VHD diferencial (.vhd)" - IDS_4128 "Blocos grandes (2 MB)" - IDS_4129 "Blocos pequenos (512 KB)" - IDS_4130 "Arquivos VHD (*.VHD)\0*.VHD\0Todos os arquivos (*.*)\0*.*\0" - IDS_4131 "Selecione o VHD pai" - IDS_4132 "Isto pode significar que a imagem de origem foi modificada após a criação da imagem diferencial.\n\nTambém pode acontecer caso os arquivos de imagem tenham sido movidos ou copiados, ou por um erro no programa que criou este disco.\n\nVocê quer consertar os marcadores de tempo?" - IDS_4133 "A data/hora dos arquivos de pais e filhos não correspondem" - IDS_4134 "Não foi possível consertar o carimbo de data/hora da VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Desativado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Desativado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfeita" - IDS_6145 "1% abaixo das RPM perfeita" - IDS_6146 "1.5% abaixo das RPM perfeita" - IDS_6147 "2% abaixo das RPM perfeita" - - IDS_7168 "(Padrão do sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Portuguese (pt-BR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc deleted file mode 100644 index c17cfe362..000000000 --- a/src/win/languages/pt-PT.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Portuguese (Portugal) resources - -#ifdef _WIN32 -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Ação" - BEGIN - MENUITEM "&Teclado requere captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&CTRL direito é ALT esquerdo",IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Reinicialização completa...",IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT - END - POPUP "&Ver" - BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Especificar dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "&Forçar rácio de visualização 4:3", IDM_VID_FORCE43 - POPUP "F&actor de escala de janela" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Método de filtragem" - BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "E&crã cheio\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modo &de estiramento em ecrã cheio" - BEGIN - MENUITEM "&Estiramento em ecrã cheio", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "Pixels &quadrados (Manter rácio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Escala &inteira", IDM_VID_FS_INT - END - POPUP "Definições E&GA/(S)VGA" - BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT - POPUP "&Tipo de ecrã VGA" - BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "&RGB em escala de cinzentos", IDM_VID_GRAY_MONO - MENUITEM "Monitor âmb&ar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE - END - POPUP "Tipo de &conversão para escala de cinzentos" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Mudar &contraste para ecrã monocromático", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Ferramentas" - BEGIN - MENUITEM "&Definições...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de estado", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Gravar imagem de ecrã\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Ativar integração com &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Iniciar o rastreio\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar o rastreio\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ajuda" - BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Acerca do 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "Re&bobinar para o início", IDM_CASSETTE_REWIND - MENUITEM "&Avanço rápido para o fim", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&CDROM vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taxa de quadros de destino" - BEGIN - MENUITEM "&Sincronizar com vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 q/s", IDM_VID_GL_FPS_25 - MENUITEM "&30 q/s", IDM_VID_GL_FPS_30 - MENUITEM "&50 q/s", IDM_VID_GL_FPS_50 - MENUITEM "&60 q/s", IDM_VID_GL_FPS_60 - MENUITEM "&75 q/s", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Selecionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Remover shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem" -#define STR_CONFIG "Definições" -#define STR_SPECIFY_DIM "Especificar dimensões da janela principal" - -#define STR_OK "OK" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Guardar estas definições como padrões &globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" - -#define STR_GAIN "Ganho" - -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Largura:" -#define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Fixar neste tamanho" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo do CPU:" -#define STR_CPU_SPEED "Velocidade:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativada" -#define STR_ENABLED_LOCAL "Ativada (hora local)" -#define STR_ENABLED_UTC "Ativada (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "Gráficos Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/A" -#define STR_XGA "Gráficos XGA" - -#define STR_MOUSE "Rato:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Placa de som 1:" -#define STR_SOUND2 "Placa de som 2:" -#define STR_SOUND3 "Placa de som 3:" -#define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" -#define STR_MPU401 "MPU-401 autónomo" -#define STR_FLOAT "Utilizar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais exacto)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" - -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Placa de rede:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta de série 1" -#define STR_SERIAL2 "Porta de série 2" -#define STR_SERIAL3 "Porta de série 3" -#define STR_SERIAL4 "Porta de série 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controlador 1:" -#define STR_SCSI_2 "Controlador 2:" -#define STR_SCSI_3 "Controlador 3:" -#define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" - -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "&Remover" -#define STR_BUS "Barram.:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagem:" -#define STR_BLOCK_SIZE "Tamanho de bloco:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Velocidade turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades CD-ROM:" -#define STR_CD_SPEED "Velocidade:" - -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erro" - IDS_2050 "Erro fatal" - IDS_2051 " - PAUSED" - IDS_2052 "Pressione Ctrl+Alt+PgDn para voltar ao modo de janela." - IDS_2053 "Velocidade" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá a href=""https://github.com/86Box/roms/releases/latest"">descarregue um pacote ROM e instale-o na pasta ""roms""." - IDS_2057 "(empty)" - IDS_2058 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Ativado" - IDS_2061 "Desativado" - IDS_2062 "Todas as imagens (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Imagens básicas de sector (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Imagens de superfície (*.86F)\0*.86F\0" - IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs na pasta roms/machines. A mudar para uma máquina disponível." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A placa vídeo ""%hs"" não está disponível devido à falta de ROMs na pasta roms/video. A mudar para uma placa vídeo disponível." - IDS_2065 "Máquina" - IDS_2066 "Apresentação" - IDS_2067 "Dispositivos de entrada" - IDS_2068 "Som" - IDS_2069 "Rede" - IDS_2070 "Portas (COM e LPT)" - IDS_2071 "Dispositivos de armazenamento" - IDS_2072 "Discos rígidos" - IDS_2073 "Unidades de disquete e CD-ROM" - IDS_2074 "Outros dispostivos removíveis" - IDS_2075 "Outros dispositivos" - IDS_2076 "Imagens de superfície (*.86F)\0*.86F\0" - IDS_2077 "Clique para capturar o rato" - IDS_2078 "Pressione F8+F12 para soltar o rato" - IDS_2079 "Pressione F8+F12 ou tecla média para soltar o rato" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Barramento" - IDS_2082 "Ficheiro" - IDS_2083 "C" - IDS_2084 "C" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Verificar BPB" - IDS_2089 "KB" - IDS_2090 "Não foi possível inicializar o renderizador vídeo." - IDS_2091 "Padrão" - IDS_2092 "%i estado(s) de espera" - IDS_2093 "Tipo" - IDS_2094 "Falha na configuração de PCap" - IDS_2095 "Não foi encontrado um dispositivo PCap" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Joystick(s) standard de 2 botões" - IDS_2098 "Joystick(s) standard de 4 botões" - IDS_2099 "Joystick(s) standard de 6 botões" - IDS_2100 "Joystick(s) standard de 8 botões" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nenhum" - IDS_2105 "Não foi possível inicializar os aceleradores de teclado." - IDS_2106 "Não foi possível registar a entrada bruta." - IDS_2107 "%u" - IDS_2108 "%u MB (CCS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" - IDS_2114 "Tem a certeza de que quer sair do 86Box?" - IDS_2115 "Não foi possível inicializar o Ghostscript" - IDS_2116 "Magneto-óptico %i (%ls): %ls" - IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todas as imagens (*.*)\0*.*\0" - IDS_2118 "Bem-vindos ao 86Box!" - IDS_2119 "Controlador interno" - IDS_2120 "Sair" - IDS_2121 "Não foi encontrada nenhuma ROM" - IDS_2122 "Deseja guardar as definições?" - IDS_2123 "Isto irá causar um reinício completo da máquina emulada." - IDS_2124 "Guardar" - IDS_2125 "Acerca do 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." - IDS_2128 "OK" - IDS_2129 "Hardware não disponível" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Certifique-se de que a biblioteca " LIB_NAME_PCAP " está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca " LIB_NAME_PCAP "." - IDS_2131 "Configuração inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." - IDS_2135 "A entrar no modo de ecrã cheio" - IDS_2136 "Não mostrar mais esta mensagem" - IDS_2137 "Não sair" - IDS_2138 "Reiniciar" - IDS_2139 "Não reiniciar" - IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2141 "Imagens CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2142 "Configuração de dispositivo %hs" - IDS_2143 "Ecrã em modo de sono" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2145 "Opções de OpenGL" - IDS_2146 "Está a carregar uma configuração sem suporte!" - IDS_2147 "A filtragem do tipo de CPU baseada na máquina escolhida está desativada para esta máquina emulada.\n\nIsto torna possível escolher um CPU que, de outra forma, não seria compatível com a máquina escolhida. No entanto, pode não ser compatível com a BIOS da máquina ou outros programas.\n\nA activação desta definição não tem suporte oficial e qualquer relatório de erros pode ser fechado como inválido." - IDS_2148 "Continuar" - IDS_2149 "Cassete: %s" - IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2153 "Erro na inicialização do renderizador" - IDS_2154 "Não foi possível inicializar o renderizador OpenGL (3.0 Core). Utilize outro renderizador." - IDS_2155 "Retomar execução" - IDS_2156 "Pausar execução" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "Reinicialização completa" - IDS_2160 "Encerramento ACPI" - IDS_2161 "Definições" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco rígido (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" - IDS_4100 "Personalizado..." - IDS_4101 "Personalizado (grande)..." - IDS_4102 "Adicionar novo disco rígido" - IDS_4103 "Adicionar disco rígido existente" - IDS_4104 "As imagens de disco HDI não podem ter mais de 4 GB." - IDS_4105 "As imagens de disco não podem ter mais de 127 GB." - IDS_4106 "Imagens de disco rígido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Todos os ficheiros (*.*)\0*.*\0" - IDS_4107 "Não foi possível ler o ficheiro" - IDS_4108 "Não foi possível escrever o ficheiro" - IDS_4109 "Imagens HDI ou HDX com um tamanho de sector diferente de 512 não são suportadas." - IDS_4110 "O barramento USB ainda não tem suporte" - IDS_4111 "A imagem de disco já existe" - IDS_4112 "Por favor, especifique um nome de ficheiro válido." - IDS_4113 "Imagem de disco criada" - IDS_4114 "Certifique-se de que o ficheiro existe e é legível." - IDS_4115 "Certifique-se de que o ficheiro está a ser guardado numa pasta editável." - IDS_4116 "Imagem de disco muito grande" - IDS_4117 "Lembre-se de particionar e formatar o novo disco criado." - IDS_4118 "O ficheiro selecionado será sobrescrito. Tem a certeza de que quer utilizá-lo?" - IDS_4119 "Imagem de disco sem suporte" - IDS_4120 "Sobrescrever" - IDS_4121 "Não sobrescrever" - IDS_4122 "Imagem bruta (.img)" - IDS_4123 "Imagem HDI (.hdi)" - IDS_4124 "Imagem HDX (.hdx)" - IDS_4125 "VHD com tamanho fixo (.vhd)" - IDS_4126 "VHD com tamanho dinâmico (.vhd)" - IDS_4127 "VHD diferenciador (.vhd)" - IDS_4128 "Blocos grandes (2 MB)" - IDS_4129 "Blocos pequenos (512 KB)" - IDS_4130 "Ficheiros VHD (*.VHD)\0*.VHD\0Todos os ficheiros (*.*)\0*.*\0" - IDS_4131 "Seleccione o VHD pai" - IDS_4132 "Isto pode significar que a imagem pai foi modificada depois da criação da imagem diferenciadora.\n\nTambém pode acontecer se os ficheiros da imagem foram movidos ou copiados ou por causa de um erro no programa que criou este disco.\n\nQuer corrigir os carimbos de data/hora?" - IDS_4133 "Os carimbos de data/hora dos discos pai e filho não correspondem!" - IDS_4134 "Não foi possível corrigir o carimbo de data/hora do VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Desativado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Desativado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfeito" - IDS_6145 "RPM 1% abaixo do RPM perfeito" - IDS_6146 "RPM 1.5% abaixo do RPM perfeito" - IDS_6147 "RPM 2% abaixo do RPM perfeito" - - IDS_7168 "(Padrão do sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Portuguese (Portugal) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc deleted file mode 100644 index 719dd5a35..000000000 --- a/src/win/languages/ru-RU.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Russian resources - -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Действие" - BEGIN - MENUITEM "&Клавиатура требует захвата", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правый CTRL - это левый ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Холодная перезагрузка...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Выход...", IDM_ACTION_EXIT - END - POPUP "&Вид" - BEGIN - MENUITEM "&Скрыть строку состояния", IDM_VID_HIDE_STATUS_BAR - MENUITEM "С&крыть панель инструментов", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE - MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Рендеринг" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Указать размеры...", IDM_VID_SPECIFY_DIM - MENUITEM "У&становить соотношение сторон 4:3", IDM_VID_FORCE43 - POPUP "&Масштаб окна" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Метод фильтрации" - BEGIN - MENUITEM "&Ближайший", IDM_VID_FILTER_NEAREST - MENUITEM "&Линейный", IDM_VID_FILTER_LINEAR - END - MENUITEM "Масштабирование Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Полноэкранный режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Растягивание в полноэкранном режиме" - BEGIN - MENUITEM "&На весь экран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Квадратные пиксели (сохранить соотношение)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Целочисленное масштабирование", IDM_VID_FS_INT - END - POPUP "Настройки E&GA/(S)VGA" - BEGIN - MENUITEM "&Инвертировать цвета VGA", IDM_VID_INVERT - POPUP "&Тип экрана VGA" - BEGIN - MENUITEM "RGB &цветной", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромный", IDM_VID_GRAY_MONO - MENUITEM "&Янтарный оттенок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелёный оттенок", IDM_VID_GRAY_GREEN - MENUITEM "&Белый оттенок", IDM_VID_GRAY_WHITE - END - POPUP "Тип монохромного &конвертирования" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усреднённый", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Вылеты развёртки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Изменить контрастность &монохромного дисплея", IDM_VID_CGACON - END - MENUITEM "&Носители", IDM_MEDIA - POPUP "&Инструменты" - BEGIN - MENUITEM "&Настройки машины...", IDM_CONFIG - MENUITEM "&Обновление значков строки состояния", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Сделать с&криншот\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Параметры...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Включить интеграцию &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Усиление звука...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Начать трассировку\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершить трассировку\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Помощь" - BEGIN - MENUITEM "&Документация...", IDM_DOCS - MENUITEM "&О программе 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Запись", IDM_CASSETTE_RECORD - MENUITEM "&Воспроизведение", IDM_CASSETTE_PLAY - MENUITEM "&Перемотка на начало", IDM_CASSETTE_REWIND - MENUITEM "&Перемотка в конец", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Э&кспорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "О&тключить звук", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "П&устой", IDM_CDROM_EMPTY - MENUITEM "&Снова загрузить предыдущий образ", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Папка...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_ZIP_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_MO_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Целевая &частота кадров" - BEGIN - MENUITEM "&Синхронизация с видео", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 кадров в секунду", IDM_VID_GL_FPS_25 - MENUITEM "&30 кадров в секунду", IDM_VID_GL_FPS_30 - MENUITEM "&50 кадров в секунду", IDM_VID_GL_FPS_50 - MENUITEM "&60 кадров в секунду", IDM_VID_GL_FPS_60 - MENUITEM "&75 кадров в секунду", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Выбрать шейдер...", IDM_VID_GL_SHADER - MENUITEM "&Удалить шейдер", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Параметры" -#define STR_SND_GAIN "Усиление звука" -#define STR_NEW_FLOPPY "Новый образ" -#define STR_CONFIG "Настройки" -#define STR_SPECIFY_DIM "Указать размеры главного окна" - -#define STR_OK "OK" -#define STR_CANCEL "Отмена" -#define STR_GLOBAL "Сохранить эти параметры как &глобальные по умолчанию" -#define STR_DEFAULT "&По умолчанию" -#define STR_LANGUAGE "Язык:" -#define STR_ICONSET "Набор иконок:" - -#define STR_GAIN "Усиление" - -#define STR_FILE_NAME "Имя файла:" -#define STR_DISK_SIZE "Размер диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогресс:" - -#define STR_WIDTH "Ширина:" -#define STR_HEIGHT "Высота:" -#define STR_LOCK_TO_SIZE "Зафиксировать размер" - -#define STR_MACHINE_TYPE "Тип машины:" -#define STR_MACHINE "Системная плата:" -#define STR_CONFIGURE "Настройка" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Скорость:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Циклы ожидания:" -#define STR_MB "МБ" -#define STR_MEMORY "Память:" -#define STR_TIME_SYNC "Синхронизация времени" -#define STR_DISABLED "Отключить" -#define STR_ENABLED_LOCAL "Включить (местное)" -#define STR_ENABLED_UTC "Включить (UTC)" -#define STR_DYNAREC "Динамический рекомпилятор" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Видеокарта:" -#define STR_VIDEO_2 "Видеокарта 2:" -#define STR_VOODOO "Ускоритель Voodoo" -#define STR_IBM8514 "Ускоритель IBM 8514/A" -#define STR_XGA "Ускоритель XGA" - -#define STR_MOUSE "Мышь:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." - -#define STR_SOUND1 "Звуковая карта 1:" -#define STR_SOUND2 "Звуковая карта 2:" -#define STR_SOUND3 "Звуковая карта 3:" -#define STR_SOUND4 "Звуковая карта 4:" -#define STR_MIDI_OUT "MIDI Out устр-во:" -#define STR_MIDI_IN "MIDI In устр-во:" -#define STR_MPU401 "Отдельный MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (более точный)" -#define STR_FM_DRV_YMFM "YMFM (быстрей)" - -#define STR_NET_TYPE "Тип сети:" -#define STR_PCAP "Устройство PCap:" -#define STR_NET "Сетевая карта:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Устройство COM1:" -#define STR_COM2 "Устройство COM2:" -#define STR_COM3 "Устройство COM3:" -#define STR_COM4 "Устройство COM4:" -#define STR_LPT1 "Устройство LPT1:" -#define STR_LPT2 "Устройство LPT2:" -#define STR_LPT3 "Устройство LPT3:" -#define STR_LPT4 "Устройство LPT4:" -#define STR_SERIAL1 "Последов. порт COM1" -#define STR_SERIAL2 "Последов. порт COM2" -#define STR_SERIAL3 "Последов. порт COM3" -#define STR_SERIAL4 "Последов. порт COM4" -#define STR_PARALLEL1 "Параллельный порт LPT1" -#define STR_PARALLEL2 "Параллельный порт LPT2" -#define STR_PARALLEL3 "Параллельный порт LPT3" -#define STR_PARALLEL4 "Параллельный порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Контроллер HD:" -#define STR_FDC "Контроллер FD:" -#define STR_IDE_TER "Третичный IDE контроллер" -#define STR_IDE_QUA "Четвертичный IDE контроллер" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Контроллер 1:" -#define STR_SCSI_2 "Контроллер 2:" -#define STR_SCSI_3 "Контроллер 3:" -#define STR_SCSI_4 "Контроллер 4:" -#define STR_CASSETTE "Кассета" - -#define STR_HDD "Жёсткие диски:" -#define STR_NEW "&Создать..." -#define STR_EXISTING "&Выбрать..." -#define STR_REMOVE "&Убрать" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Указать..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Цилиндры:" -#define STR_SIZE_MB "Размер (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образа:" -#define STR_BLOCK_SIZE "Размер блока:" - -#define STR_FLOPPY_DRIVES "Гибкие диски:" -#define STR_TURBO "Турбо тайминги" -#define STR_CHECKBPB "Проверять BPB" -#define STR_CDROM_DRIVES "Дисководы CD-ROM:" -#define STR_CD_SPEED "Скорость:" - -#define STR_MO_DRIVES "Магнитооптические дисководы:" -#define STR_ZIP_DRIVES "ZIP дисководы:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Карта расширения памяти (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" -#define STR_BUGGER "Устройство ISABugger" -#define STR_POSTCARD "Карта POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Ошибка" - IDS_2050 "Неустранимая ошибка" - IDS_2051 " - ПАУЗА" - IDS_2052 "Нажмите Ctrl+Alt+PgDn для возврата в оконный режим." - IDS_2053 "Скорость" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Образы ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box не смог найти ни одного подходящего для использования файла с ПЗУ.\n\nПожалуйста скачайте набор ПЗУ и извлеките его в каталог ""roms""." - IDS_2057 "(пусто)" - IDS_2058 "Образы ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Все файлы (*.*)\0*.*\0" - IDS_2059 "Турбо" - IDS_2060 "Вкл" - IDS_2061 "Выкл" - IDS_2062 "Все образы (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Простые посекторные образы (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface образы (*.86F)\0*.86F\0" - IDS_2063 "Системная плата ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/machines. Переключение на доступную системную плату." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Видеокарта ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Переключение на доступную видеокарту." - IDS_2065 "Компьютер" - IDS_2066 "Дисплей" - IDS_2067 "Устройства ввода" - IDS_2068 "Звук" - IDS_2069 "Сеть" - IDS_2070 "Порты (COM и LPT)" - IDS_2071 "Контроллеры дисков" - IDS_2072 "Жёсткие диски" - IDS_2073 "Гибкие диски и CD-ROM" - IDS_2074 "Другие съёмные устр-ва" - IDS_2075 "Другая периферия" - IDS_2076 "Образы Surface (*.86F)\0*.86F\0" - IDS_2077 "Щёлкните мышью для захвата курсора" - IDS_2078 "Нажмите F8+F12 чтобы освободить курсор" - IDS_2079 "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Шина" - IDS_2082 "Файл" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "МБ" - IDS_2087 "Speed" - IDS_2088 "Проверять BPB" - IDS_2089 "КБ" - IDS_2090 "Не удалось инициализировать рендерер видео." - IDS_2091 "По умолчанию" - IDS_2092 "%i WS" - IDS_2093 "Тип" - IDS_2094 "Не удалось настроить PCap" - IDS_2095 "Устройства PCap не найдены" - IDS_2096 "Неверное устройство PCap" - IDS_2097 "Стандартный 2-кнопочный джойстик" - IDS_2098 "Стандартный 4-кнопочный джойстик" - IDS_2099 "Стандартный 6-кнопочный джойстик" - IDS_2100 "Стандартный 8-кнопочный джойстик" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Система управления полетом Thrustmaster" - IDS_2104 "Нет" - IDS_2105 "Невозможно загрузить ускорители клавиатуры." - IDS_2106 "Невозможно зарегистрировать необработанный (RAW) ввод." - IDS_2107 "%u" - IDS_2108 "%u МБ (CHS: %i, %i, %i)" - IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" - IDS_2114 "Вы уверены, что хотите выйти из 86Box?" - IDS_2115 "Невозможно инициализировать Ghostscript" - IDS_2116 "Магнитооптический %i (%ls): %ls" - IDS_2117 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2118 "Добро пожаловать в 86Box!" - IDS_2119 "Встроенный контроллер" - IDS_2120 "Выход" - IDS_2121 "ПЗУ не найдены" - IDS_2122 "Хотите ли вы сохранить настройки?" - IDS_2123 "Это приведет к холодной перезагрузке эмулируемой машины." - IDS_2124 "Сохранить" - IDS_2125 "О 86Box" - IDS_2126 "86Box v." EMU_VERSION - - IDS_2127 "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." - IDS_2128 "OK" - IDS_2129 "Оборудование недоступно" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Убедитесь, что " LIB_NAME_PCAP " установлен и ваше сетевое соединение, совместимо с " LIB_NAME_PCAP "." - IDS_2131 "Недопустимая конфигурация" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." - IDS_2135 "Вход в полноэкранный режим" - IDS_2136 "Больше не показывать это сообщение" - IDS_2137 "Не выходить" - IDS_2138 "Перезагрузить" - IDS_2139 "Не перезагружать" - IDS_2140 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2141 "Образы CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Все файлы (*.*)\0*.*\0" - IDS_2142 "Конфигурация устройства %hs" - IDS_2143 "Монитор в спящем режиме" - IDS_2144 "Шейдеры OpenGL (*.GLSL)\0*.GLSL\0Все файлы (*.*)\0*.*\0" - IDS_2145 "Параметры OpenGL" - IDS_2146 "Вы загружаете неподдерживаемую конфигурацию" - IDS_2147 "Выбор типов ЦП для этой системной платы на данной эмулируемой машине отключен.\n\nЭто позволяет выбрать процессор, который в противном случае несовместим с выбранной материнской платой. Однако, вы можете столкнуться с несовместимостью с BIOS материнской платы или другим ПО.\n\nВключение этого параметра официально не поддерживается, и все поданные отчеты об ошибках могут быть закрыты как недействительные." - IDS_2148 "Продолжить" - IDS_2149 "Кассета: %s" - IDS_2150 "Образы кассет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Все файлы (*.*)\0*.*\0" - IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образы картриджей (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Все файлы (*.*)\0*.*\0" - IDS_2153 "Ошибка инициализации рендерера" - IDS_2154 "Невозможно инициализировать рендерер OpenGL (3.0). Пожалуйста, используйте другой рендерер." - IDS_2155 "Возобновить выполнение" - IDS_2156 "Приостановить выполнение" - IDS_2157 "Нажать Ctrl+Alt+Del" - IDS_2158 "Нажать Ctrl+Alt+Esc" - IDS_2159 "Холодная перезагрузка" - IDS_2160 "Сигнал завершения ACPI" - IDS_2161 "Настройки машины" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Жёсткий диск (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL или ESDI дисководов CD-ROM никогда не существовало" - IDS_4100 "Задать вручную..." - IDS_4101 "Задать вручную (large)..." - IDS_4102 "Создать новый жёсткий диск" - IDS_4103 "Выбрать существующий жёсткий диск" - IDS_4104 "Размер образов дисков HDI не может превышать 4 ГБ." - IDS_4105 "Размер образов дисков не может превышать 127 ГБ." - IDS_4106 "Образы жёстких дисков (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Все файлы (*.*)\0*.*\0" - IDS_4107 "Невозможно прочитать файл" - IDS_4108 "Невозможно записать файл" - IDS_4109 "Образы HDI или HDX с размером сектора, отличным от 512, не поддерживаются." - IDS_4110 "USB пока не поддерживается" - IDS_4111 "Файл образа диска уже существует" - IDS_4112 "Пожалуйста, укажите правильное имя файла." - IDS_4113 "Образ диска создан" - IDS_4114 "Убедитесь, что файл существует и доступен для чтения." - IDS_4115 "Убедитесь, что файл сохраняется в директории доступной для записи." - IDS_4116 "Слишком большой образ диска" - IDS_4117 "Не забудьте разметить и отформатировать вновь созданный диск." - IDS_4118 "Выбранный файл будет перезаписан. Вы уверены, что хотите использовать его?" - IDS_4119 "Неподдерживаемый образ диска" - IDS_4120 "Перезаписать" - IDS_4121 "Не перезаписывать" - IDS_4122 "RAW образ (.img)" - IDS_4123 "Образ HDI (.hdi)" - IDS_4124 "Образ HDX (.hdx)" - IDS_4125 "VHD фиксированного размера (.vhd)" - IDS_4126 "VHD динамического размера (.vhd)" - IDS_4127 "Дифференцированный образ VHD (.vhd)" - IDS_4128 "Большие блоки (2 МБ)" - IDS_4129 "Маленькие блоки (512 КБ)" - IDS_4130 "Файлы VHD (*.VHD)\0*.VHD\0Все файлы (*.*)\0*.*\0" - IDS_4131 "Выберите родительский VHD" - IDS_4132 "Это может означать, что родительский образ был изменён после того, как был создан дифференцированный образ.\n\nЭто также может произойти, если файлы образа были перемещены или скопированы, или из-за ошибки в программе, создавшей этот диск.\n\nВы хотите исправить временные метки?" - IDS_4133 "Временные метки родительского и дочернего дисков не совпадают" - IDS_4134 "Не удалось исправить временную метку VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Отключён" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Отключён" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 кБ" - IDS_5889 "180 кБ" - IDS_5890 "320 кБ" - IDS_5891 "360 кБ" - IDS_5892 "640 кБ" - IDS_5893 "720 кБ" - IDS_5894 "1.2 МБ" - IDS_5895 "1.25 МБ" - IDS_5896 "1.44 МБ" - IDS_5897 "DMF (кластер 1024)" - IDS_5898 "DMF (кластер 2048)" - IDS_5899 "2.88 МБ" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 МБ (ISO 10090)" - IDS_5903 "3.5"" 230 МБ (ISO 13963)" - IDS_5904 "3.5"" 540 МБ (ISO 15498)" - IDS_5905 "3.5"" 640 МБ (ISO 15498)" - IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" - IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" - IDS_5908 "5.25"" 600 МБ" - IDS_5909 "5.25"" 650 МБ" - IDS_5910 "5.25"" 1 ГБ" - IDS_5911 "5.25"" 1.3 ГБ" - - IDS_6144 "Точный RPM" - IDS_6145 "На 1% медленнее точного RPM" - IDS_6146 "На 1.5% медленнее точного RPM" - IDS_6147 "На 2% медленнее точного RPM" - - IDS_7168 "(Системный)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Russian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc deleted file mode 100644 index 3a8b12dbb..000000000 --- a/src/win/languages/sl-SI.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Slovenian resources - -#ifdef _WIN32 -LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Dejanja" - BEGIN - MENUITEM "&Tipkovnica potrebuje zajem", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je levi ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Ponovni zagon...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Premor", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Iz&hod...", IDM_ACTION_EXIT - END - POPUP "&Pogled" - BEGIN - MENUITEM "&Skrij statusno vrstico", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "S&premenljiva velikost okna", IDM_VID_RESIZE - MENUITEM "&Zapomni si velikost in položaj", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Upodabljanje" - BEGIN - MENUITEM "&SDL (programsko)", IDM_VID_SDL_SW - MENUITEM "SDL (s&trojno)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Jedro 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Določi velikost...", IDM_VID_SPECIFY_DIM - MENUITEM "&Vsili 4:3 razmerje zaslona", IDM_VID_FORCE43 - POPUP "&Faktor velikosti okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Metoda filtriranja" - BEGIN - MENUITEM "&Najbližja", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Raztezanje za visok DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Celozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Način celozaslonskega raztezanja" - BEGIN - MENUITEM "&Raztegni na celoten zaslon", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kvadratni piksli (ohrani razmerje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Celoštevilsko raztezanje", IDM_VID_FS_INT - END - POPUP "Nastavitve E&GA/(S)VGA" - BEGIN - MENUITEM "&Obrni barve zaslona VGA", IDM_VID_INVERT - POPUP "&Vrsta zaslona VGA" - BEGIN - MENUITEM "&Barvni RGB", IDM_VID_GRAY_RGB - MENUITEM "&Sivinski RGB", IDM_VID_GRAY_MONO - MENUITEM "&Rumeni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "B&eli zaslon", IDM_VID_GRAY_WHITE - END - POPUP "V&rsta pretvorbe sivin" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Povprečje", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Presežek slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Spremeni contrast za črno-beli zaslon", IDM_VID_CGACON - END - MENUITEM "&Mediji", IDM_MEDIA - POPUP "&Orodja" - BEGIN - MENUITEM "&Nastavitve...", IDM_CONFIG - MENUITEM "&Posodabljaj ikone statusne vrstice", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Zajemi posnetek zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Možnosti...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Omogoči integracijo s programom &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ojačanje zvoka...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Z&ačni sledenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Končaj sledenje\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoč" - BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Snemaj", IDM_CASSETTE_RECORD - MENUITEM "Predvajaj", IDM_CASSETTE_PLAY - MENUITEM "Previj na začetek", IDM_CASSETTE_REWIND - MENUITEM "Preskoči na konec", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "Slika...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izvozi v 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Utišaj", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Prazen", IDM_CDROM_EMPTY - MENUITEM "&Naloži zadnjo sliko", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_ZIP_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_MO_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Ciljno št. sličic na sekundo" - BEGIN - MENUITEM "&Sinhroniziraj z videom", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Izberi senčilnik...", IDM_VID_GL_SHADER - MENUITEM "&Odstrani senčilnik", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Možnosti" -#define STR_SND_GAIN "Ojačanje zvoka" -#define STR_NEW_FLOPPY "Nova slika" -#define STR_CONFIG "Nastavitve" -#define STR_SPECIFY_DIM "Določi velikost glavnega okna" - -#define STR_OK "V redu" -#define STR_CANCEL "Prekliči" -#define STR_GLOBAL "Shrani te nastavitve kot globalne privzete" -#define STR_DEFAULT "Privzeto" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Komplet ikon:" - -#define STR_GAIN "Ojačanje" - -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Velikost diska:" -#define STR_RPM_MODE "Način števila obratov:" -#define STR_PROGRESS "Napredek:" - -#define STR_WIDTH "Širina:" -#define STR_HEIGHT "Višina:" -#define STR_LOCK_TO_SIZE "Zakleni na to velikost" - -#define STR_MACHINE_TYPE "Vrsta sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Nastavi" -#define STR_CPU_TYPE "Vrsta procesorja:" -#define STR_CPU_SPEED "Hitrost:" -#define STR_FPU "Procesor plavajoče vejice:" -#define STR_WAIT_STATES "Čakalna stanja:" -#define STR_MB "MB" -#define STR_MEMORY "Spomin:" -#define STR_TIME_SYNC "Sinhronizacija časa" -#define STR_DISABLED "Onemogočeno" -#define STR_ENABLED_LOCAL "Omogočeno (lokalni čas)" -#define STR_ENABLED_UTC "Omogočeno (UTC)" -#define STR_DYNAREC "Dinamični prevajalnik" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/A grafika" -#define STR_XGA "XGA grafika" - -#define STR_MOUSE "Miška:" -#define STR_JOYSTICK "Igralna palica:" -#define STR_JOY1 "Igralna palica 1..." -#define STR_JOY2 "Igralna palica 2..." -#define STR_JOY3 "Igralna palica 3..." -#define STR_JOY4 "Igralna palica 4..." - -#define STR_SOUND1 "Zvočna kartica 1:" -#define STR_SOUND2 "Zvočna kartica 2:" -#define STR_SOUND3 "Zvočna kartica 3:" -#define STR_SOUND4 "Zvočna kartica 4:" -#define STR_MIDI_OUT "Izhodna naprava MIDI:" -#define STR_MIDI_IN "Vhodna naprava MIDI:" -#define STR_MPU401 "Samostojen MPU-401" -#define STR_FLOAT "Uporabi FLOAT32 za zvok" -#define STR_FM_DRIVER "Gonilnik sintetizacije FM" -#define STR_FM_DRV_NUKED "Nuked (točnejši)" -#define STR_FM_DRV_YMFM "YMFM (hitrejši)" - -#define STR_NET_TYPE "Vrsta omrežja:" -#define STR_PCAP "Naprava PCap:" -#define STR_NET "Omrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Naprava COM1:" -#define STR_COM2 "Naprava COM2:" -#define STR_COM3 "Naprava COM3:" -#define STR_COM4 "Naprava COM4:" -#define STR_LPT1 "Naprava LPT1:" -#define STR_LPT2 "Naprava LPT2:" -#define STR_LPT3 "Naprava LPT3:" -#define STR_LPT4 "Naprava LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Krmilnik trdega diska:" -#define STR_FDC "Krmilnik disketnika:" -#define STR_IDE_TER "Terciarni krmilnik IDE" -#define STR_IDE_QUA "Kvartarni krmilnik IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Krmilnik 1:" -#define STR_SCSI_2 "Krmilnik 2:" -#define STR_SCSI_3 "Krmilnik 3:" -#define STR_SCSI_4 "Krmilnik 4:" -#define STR_CASSETTE "Kasetnik" - -#define STR_HDD "Trdi diski:" -#define STR_NEW "Nov..." -#define STR_EXISTING "Obstoječ..." -#define STR_REMOVE "Odstrani" -#define STR_BUS "Vodilo:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "Določi..." -#define STR_SECTORS "Sektorji:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Velikost (MB):" -#define STR_TYPE "Vrsta:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Velikost bloka:" - -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo časovniki" -#define STR_CHECKBPB "Preverjaj BPB" -#define STR_CDROM_DRIVES "Pogoni CD-ROM:" -#define STR_CD_SPEED "Hitrost:" - -#define STR_MO_DRIVES "Magnetno-optični pogoni:" -#define STR_ZIP_DRIVES "Pogoni ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Ura v realnem času ISA:" -#define STR_ISAMEM "Razširitev spomina ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" -#define STR_BUGGER "Naprava ISABugger" -#define STR_POSTCARD "Kartica POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Napaka" - IDS_2050 "Kritična napaka" - IDS_2051 " - PAUSED" - IDS_2052 "Pritisnite Ctrl+Alt+PgDn za povratek iz celozaslonskega načina." - IDS_2053 "Hitrost" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite set ROM-ov in ga razširite v mapo ""roms""." - IDS_2057 "(prazno)" - IDS_2058 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Vključeno" - IDS_2061 "Izključeno" - IDS_2062 "Vse slike (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Osnovne sektorske slike (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Površinske slike (*.86F)\0*.86F\0" - IDS_2063 "Sistem ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/machines. Preklapljam na drug sistem, ki je na voljo." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Grafična kartica ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo.." - IDS_2065 "Sistem" - IDS_2066 "Zaslon" - IDS_2067 "Vhodne naprave" - IDS_2068 "Zvok" - IDS_2069 "Omrežje" - IDS_2070 "Vrata (COM & LPT)" - IDS_2071 "Krmilniki shrambe" - IDS_2072 "Trdi diski" - IDS_2073 "Disketni in CD-ROM pogoni" - IDS_2074 "Druge odstranljive naprave" - IDS_2075 "Druga periferija" - IDS_2076 "Površinske slike (*.86F)\0*.86F\0" - IDS_2077 "Kliknite za zajem miške" - IDS_2078 "Pritisnite F8+F12 za izpust miške" - IDS_2079 "Pritisnite F8+F12 ali srednji gumb za izpust miške" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Vodilo" - IDS_2082 "Datoteka" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Preveri BPB" - IDS_2089 "KB" - IDS_2090 "Ne morem inicializirati pogona upodabljanja." - IDS_2091 "Privzeto" - IDS_2092 "%i stanj čakanja" - IDS_2093 "Vrsta" - IDS_2094 "Nastavitev PCap ni uspela" - IDS_2095 "Nobena naprava PCap ni bila najdena" - IDS_2096 "Neveljavna naprava PCap" - IDS_2097 "Standardna krmilna palica z 2 gumboma" - IDS_2098 "Standardna krmilna palica s 4 gumbi" - IDS_2099 "Standardna krmilna palica s 6 gumbi" - IDS_2100 "Standardna krmilna palica z 8 gumbi" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Brez" - IDS_2105 "Ne morem naložiti pospeševalnikov tipkovnice." - IDS_2106 "Ne morem registrirati neobdelanega vnosa." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketa %i (%s): %ls" - IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" - IDS_2114 "Ste prepričani, da želite zapreti 86Box?" - IDS_2115 "Ne morem inicializirati Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2118 "Dobrodošli v 86Box!" - IDS_2119 "Notranji krmilnik" - IDS_2120 "Izhod" - IDS_2121 "Nobeni ROM-i niso bili najdeni" - IDS_2122 "Želite shraniti nastavitve?" - IDS_2123 "To bo ponovno zagnalo emuliran sistem." - IDS_2124 "Shrani" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." - IDS_2128 "V redu" - IDS_2129 "Strojna oprema ni na voljo" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Prepičajte se, da je nameščen " LIB_NAME_PCAP " in da ste na omrežni povezavi, združljivi z " LIB_NAME_PCAP - IDS_2131 "Neveljavna konfiguracija" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." - IDS_2135 "Preklapljam v celozaslonski način" - IDS_2136 "Ne pokaži več tega sporočila" - IDS_2137 "Prekliči izhod" - IDS_2138 "Resetiraj" - IDS_2139 "Ne resetiraj" - IDS_2140 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2141 "Slike CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Vse datoteke (*.*)\0*.*\0" - IDS_2142 "Konfiguracija naprave %hs" - IDS_2143 "Zaslon v načinu spanja" - IDS_2144 "Senčilniki OpenGL (*.GLSL)\0*.GLSL\0Vse datoteke (*.*)\0*.*\0" - IDS_2145 "Možnosti OpenGL" - IDS_2146 "Nalagate nepodprto konfiguracijo" - IDS_2147 "Filtriranje vrste procesorja glede na izbran sistem je onemogočeno za ta emuliran sistem.\n\nTako lahko izberete procesor, ki je sicer nezdružljiv z izbranim sistemom. Vendar lahko naletite na nezdružljivosti z BIOS-om sistema ali drugo programsko opremo\n\nOmogočanje te nastavitve ni uradno podprto, vsa poročila o hroščih iz tega naslova pa bodo zaprta kot neveljavna." - IDS_2148 "Nadaljuj" - IDS_2149 "Kaseta: %s" - IDS_2150 "Slike kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Vse datoteke (*.*)\0*.*\0" - IDS_2151 "Spominski vložek %i: %ls" - IDS_2152 "Slike spominskega vložka (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Vse datoteke (*.*)\0*.*\0" - IDS_2153 "Napaka pri zagonu sistema za upodabljanje" - IDS_2154 "Sistema za upodabljanje OpenGL (3.0 Core) ni bilo mogoče zagnati. Uporabite drug sistem za upodabljanje." - IDS_2155 "Nadaljuj izvajanje" - IDS_2156 "Prekini izvajanje" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Ponovni zagon" - IDS_2160 "Zaustavitev ACPI" - IDS_2161 "Nastavitve" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Trdi disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL ali ESDI pogoni CD-ROM niso nikoli obstajali" - IDS_4100 "Po meri..." - IDS_4101 "Po meri (velik)..." - IDS_4102 "Dodaj nov trdi disk" - IDS_4103 "Dodaj obstoječ trdi disk" - IDS_4104 "Slike diska HDI ne morejo biti večje od 4 GB." - IDS_4105 "Slike diska ne morejo biti večje od 127 GB." - IDS_4106 "Slike trdega diska (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Vse datoteke (*.*)\0*.*\0" - IDS_4107 "Ne morem prebrati datoteke" - IDS_4108 "Ne morem pisati v datoteko" - IDS_4109 "Slike HDI ali HDX, ki nimajo sektorjev velikosti 512 bajtov, niso podprte." - IDS_4110 "USB še ni podprt" - IDS_4111 "Datoteka s sliko diska že obstaja" - IDS_4112 "Prosim, navedite veljavno ime datoteke." - IDS_4113 "Slika diska ustvarjena" - IDS_4114 "Prepričajte se, da datoteka obstaja in je berljiva." - IDS_4115 "Prepričajte se, da datoteko shranjujete v zapisljivo mapo." - IDS_4116 "Slika diska je prevelika" - IDS_4117 "Ne pozabite na novem disku ustvariti particij in jih formatirati." - IDS_4118 "Izbrana datoteka bo prepisana. Ali jo res želite uporabiti?" - IDS_4119 "Nepodprta slika diska" - IDS_4120 "Prepiši" - IDS_4121 "Ne prepiši" - IDS_4122 "Surova slika (.img)" - IDS_4123 "Slika HDI (.hdi)" - IDS_4124 "Slika HDX (.hdx)" - IDS_4125 "VHD fiksne velikosti (.vhd)" - IDS_4126 "Dinamičen VHD (.vhd)" - IDS_4127 "Diferencialni VHD (.vhd)" - IDS_4128 "Veliki bloki (2 MB)" - IDS_4129 "Mali bloki (512 KB)" - IDS_4130 "Datoteke VHD (*.VHD)\0*.VHD\0Vse datoteke (*.*)\0*.*\0" - IDS_4131 "Izberite starševsko sliko VHD" - IDS_4132 "To lahko pomeni, da je bila starševska slika spremenjena potem, ko je že bila ustvarjena diferencialna slika.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" - IDS_4133 "Časovna žiga starševske slike diska in slike diska otroka se ne ujemata" - IDS_4134 "Ne morem popraviti časovnega žiga slike VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Onemogočeno" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Onemogočeno" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (grozd 1024)" - IDS_5898 "DMF (grozd 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Popolni obrati na minuto" - IDS_6145 "1% pod popolnimi obrati" - IDS_6146 "1.5% pod popolnimi obrati" - IDS_6147 "2% pod popolnimi obrati" - - IDS_7168 "(Sistemsko privzeto)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Slovenian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc deleted file mode 100644 index 80a436c5d..000000000 --- a/src/win/languages/tr-TR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Turkish (TR) resources - -#ifdef _WIN32 -LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Komutlar" - BEGIN - MENUITEM "&Klavye sadece fare yakalandığında çalışsın", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Makineyi yeniden başlat...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Duraklat", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Emülatörden &çık...", IDM_ACTION_EXIT - END - POPUP "&Görüntüleme" - BEGIN - MENUITEM "&Durum çubuğunu gizle", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Yeniden boyutlandırılabilir pencere", IDM_VID_RESIZE - MENUITEM "&Pencere boyut ve pozisyonunu hatırla", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&İşleyici" - BEGIN - MENUITEM "&SDL (Yazılım)", IDM_VID_SDL_SW - MENUITEM "SDL (&Donanım)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Pencere &boyutunu belirle...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 görüntüleme oranına zorla", IDM_VID_FORCE43 - POPUP "Pencere &ölçek çarpanı" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Filtre metodu" - BEGIN - MENUITEM "&Nearest (En yakın)", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear (Doğrusal)", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI ölçeklemesi", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Tam ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Tam ekran &germe modu" - BEGIN - MENUITEM "&Tam ekrana ger", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kare piksel (ölçeği koru)", IDM_VID_FS_KEEPRATIO - MENUITEM "Tam &sayı ölçeklemesi", IDM_VID_FS_INT - END - POPUP "EGA/&(S)VGA ayarları" - BEGIN - MENUITEM "Ters &renk VGA monitör", IDM_VID_INVERT - POPUP "VGA ekran &tipi" - BEGIN - MENUITEM "RGB (&renkli)", IDM_VID_GRAY_RGB - MENUITEM "RGB (&gri tonlama)", IDM_VID_GRAY_MONO - MENUITEM "&Kehribar rengi monitör", IDM_VID_GRAY_AMBER - MENUITEM "&Yeşil renk monitör", IDM_VID_GRAY_GREEN - MENUITEM "&Beyaz renk monitör", IDM_VID_GRAY_WHITE - END - POPUP "&Gri tonlama dönüştürme tipi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Ortalama", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması", IDM_VID_OVERSCAN - MENUITEM "Gri to&nlamalı görüntü için kontrastı değiştir", IDM_VID_CGACON - END - MENUITEM "&Medya", IDM_MEDIA - POPUP "&Araçlar" - BEGIN - MENUITEM "&Ayarlar...", IDM_CONFIG - MENUITEM "Durum &çubuğu ikonlarını güncelle", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Ekran görüntüsü al\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Tercihler...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord entegrasyonunu etkinleştir", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ses yükseltici...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Yardım" - BEGIN - MENUITEM "&Dökümanlar...", IDM_DOCS - MENUITEM "&86Box Hakkında...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Kaydet", IDM_CASSETTE_RECORD - MENUITEM "&Oynat", IDM_CASSETTE_PLAY - MENUITEM "&Başlangıca geri sar", IDM_CASSETTE_REWIND - MENUITEM "Sona doğru &ileri sar", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&İmaj...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&86F dosyası olarak aktar...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Sesi kapat", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "İmajı &çıkar", IDM_CDROM_EMPTY - MENUITEM "&Önceki imajı seç", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CDROM_IMAGE - MENUITEM "&Klasör...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_ZIP_EJECT - MENUITEM "&Önceki imajı seç", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_MO_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_MO_EJECT - MENUITEM "&Önceki imajı seç", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Hedef &kare oranı" - BEGIN - MENUITEM "Video ile &senkronize et", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Gölgelendirici &seç...", IDM_VID_GL_SHADER - MENUITEM "&Gölgelendiriciyi kaldır", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Tercihler" -#define STR_SND_GAIN "Ses Artırma" -#define STR_NEW_FLOPPY "Yeni İmaj" -#define STR_CONFIG "Ayarlar" -#define STR_SPECIFY_DIM "Ana Pencere Boyutunu Belirle" - -#define STR_OK "Tamam" -#define STR_CANCEL "İptal et" -#define STR_GLOBAL "Bu ayarları &varsayılan olarak kaydet" -#define STR_DEFAULT "&Varsayılan" -#define STR_LANGUAGE "Dil:" -#define STR_ICONSET "Simge seti:" - -#define STR_GAIN "Artırma" - -#define STR_FILE_NAME "Dosya adı:" -#define STR_DISK_SIZE "Disk boyutu:" -#define STR_RPM_MODE "RPM modu:" -#define STR_PROGRESS "İşlem:" - -#define STR_WIDTH "Genişlik:" -#define STR_HEIGHT "Yükseklik:" -#define STR_LOCK_TO_SIZE "Bu boyuta kilitle" - -#define STR_MACHINE_TYPE "Makine türü:" -#define STR_MACHINE "Makine:" -#define STR_CONFIGURE "Ayarla" -#define STR_CPU_TYPE "CPU türü:" -#define STR_CPU_SPEED "Hız:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Bekleme süreleri:" -#define STR_MB "MB" -#define STR_MEMORY "Bellek:" -#define STR_TIME_SYNC "Zaman senkronizasyonu" -#define STR_DISABLED "Devre dışı" -#define STR_ENABLED_LOCAL "Etkin (yerel zaman)" -#define STR_ENABLED_UTC "Etkin (UTC)" -#define STR_DYNAREC "Dinamik Derleyici" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Ekran kartı:" -#define STR_VIDEO_2 "Ekran kartı 2:" -#define STR_VOODOO "Voodoo Grafikleri" -#define STR_IBM8514 "IBM 8514/A Grafikleri" -#define STR_XGA "XGA Grafikleri" - -#define STR_MOUSE "Fare:" -#define STR_JOYSTICK "Oyun kolu:" -#define STR_JOY1 "Oyun kolu 1..." -#define STR_JOY2 "Oyun kolu 2..." -#define STR_JOY3 "Oyun kolu 3..." -#define STR_JOY4 "Oyun kolu 4..." - -#define STR_SOUND1 "Ses kartı 1:" -#define STR_SOUND2 "Ses kartı 2:" -#define STR_SOUND3 "Ses kartı 3:" -#define STR_SOUND4 "Ses kartı 4:" -#define STR_MIDI_OUT "MIDI Çıkış Cihazı:" -#define STR_MIDI_IN "MIDI Giriş Cihazı:" -#define STR_MPU401 "Bağımsız MPU-401" -#define STR_FLOAT "FLOAT32 ses kullan" -#define STR_FM_DRIVER "FM sentez sürücüsü" -#define STR_FM_DRV_NUKED "Nuked (daha doğru)" -#define STR_FM_DRV_YMFM "YMFM (daha hızlı)" - -#define STR_NET_TYPE "Ağ tipi:" -#define STR_PCAP "PCap cihazı:" -#define STR_NET "Ağ cihazı:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Cihazı:" -#define STR_COM2 "COM2 Cihazı:" -#define STR_COM3 "COM3 Cihazı:" -#define STR_COM4 "COM4 Cihazı:" -#define STR_LPT1 "LPT1 Cihazı:" -#define STR_LPT2 "LPT2 Cihazı:" -#define STR_LPT3 "LPT3 Cihazı:" -#define STR_LPT4 "LPT4 Cihazı:" -#define STR_SERIAL1 "Seri port 1" -#define STR_SERIAL2 "Seri port 2" -#define STR_SERIAL3 "Seri port 3" -#define STR_SERIAL4 "Seri port 4" -#define STR_PARALLEL1 "Paralel port 1" -#define STR_PARALLEL2 "Paralel port 2" -#define STR_PARALLEL3 "Paralel port 3" -#define STR_PARALLEL4 "Paralel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Kontrolcüsü:" -#define STR_FDC "FD Kontrolcüsü:" -#define STR_IDE_TER "Üçlü IDE Kontrolcüsü" -#define STR_IDE_QUA "Dörtlü IDE Kontrolcüsü" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontrolcü 1:" -#define STR_SCSI_2 "Kontrolcü 2:" -#define STR_SCSI_3 "Kontrolcü 3:" -#define STR_SCSI_4 "Kontrolcü 4:" -#define STR_CASSETTE "Kaset" - -#define STR_HDD "Hard diskler:" -#define STR_NEW "&Yeni..." -#define STR_EXISTING "&Var olan..." -#define STR_REMOVE "&Kaldır" -#define STR_BUS "Veri yolu:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Belirle..." -#define STR_SECTORS "Sektörler:" -#define STR_HEADS "Veri Kafaları:" -#define STR_CYLS "Silindirler:" -#define STR_SIZE_MB "Boyut (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "İmaj Düzeni:" -#define STR_BLOCK_SIZE "Blok Boyutu:" - -#define STR_FLOPPY_DRIVES "Disket sürücüleri:" -#define STR_TURBO "Turbo zamanlamaları" -#define STR_CHECKBPB "BPB'yi denetle" -#define STR_CDROM_DRIVES "CD-ROM sürücüleri:" -#define STR_CD_SPEED "Hız:" - -#define STR_MO_DRIVES "MO sürücüleri:" -#define STR_ZIP_DRIVES "ZIP sürücüleri:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Bellek Artırma" -#define STR_ISAMEM_1 "Kart 1:" -#define STR_ISAMEM_2 "Kart 2:" -#define STR_ISAMEM_3 "Kart 3:" -#define STR_ISAMEM_4 "Kart 4:" -#define STR_BUGGER "ISABugger cihazı" -#define STR_POSTCARD "POST kartı" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Hata" - IDS_2050 "Kritik hata" - IDS_2051 " - PAUSED" - IDS_2052 "Pencere moduna geri dönmek için Ctrl+Alt+PgDn tuşlarına basın." - IDS_2053 "Hız" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP imajları (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box hiç bir kullanılabilir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve onu ""Roms"" klasörüne çıkarın." - IDS_2057 "(empty)" - IDS_2058 "ZIP imajları (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Açık" - IDS_2061 "Kapalı" - IDS_2062 "Tüm imajlar (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basit sektör imajları (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Yüzey imajları (*.86F)\0*.86F\0" - IDS_2063 """%hs"" makinesi roms/machines klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir makineye geçiş yapılıyor." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 """%hs"" ekran kartı roms/video klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir ekran kartına geçiş yapılıyor." - IDS_2065 "Makine" - IDS_2066 "Görüntü" - IDS_2067 "Giriş aygıtları" - IDS_2068 "Ses" - IDS_2069 "Ağ" - IDS_2070 "Portlar (COM & LPT)" - IDS_2071 "Depolama kontrolcüleri" - IDS_2072 "Hard diskler" - IDS_2073 "Disket & CD-ROM sürücüleri" - IDS_2074 "Diğer kaldırılabilir cihazlar" - IDS_2075 "Diğer cihazlar" - IDS_2076 "Yüzey imajları (*.86F)\0*.86F\0" - IDS_2077 "Farenin yakalanması için tıklayın" - IDS_2078 "Farenin bırakılması için F8+F12 tuşlarına basın" - IDS_2079 "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Veri yolu" - IDS_2082 "Dosya" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB'yi kontrol et" - IDS_2089 "KB" - IDS_2090 "Video işleyici başlatılamadı." - IDS_2091 "Varsayılan" - IDS_2092 "%i Bekleme durumları" - IDS_2093 "Tür" - IDS_2094 "PCap ayarlanamadı" - IDS_2095 "Herhangi bir PCap cihazı bulunamadı" - IDS_2096 "Geçersiz PCap cihazı" - IDS_2097 "Standart 2-button oyun kolları" - IDS_2098 "Standart 4-button oyun kolu" - IDS_2099 "Standart 6-button oyun kolu" - IDS_2100 "Standart 8-button oyun kolu" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Kontrol Sistemi" - IDS_2104 "Hiçbiri" - IDS_2105 "Klavye ivdirgeçleri yüklenemedi." - IDS_2106 "Ham girdi kaydedilemedi." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disket %i (%s): %ls" - IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" - IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" - IDS_2115 "Ghostscript başlatılamadı" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "86Box'a hoşgeldiniz!" - IDS_2119 "Dahili kontrolcü" - IDS_2120 "Çıkış" - IDS_2121 "Hiçbir ROM imajı bulunamadı" - IDS_2122 "Ayarları kaydetmek istediğinizden emin misiniz?" - IDS_2123 "Bu makineyi yeniden başlatacak." - IDS_2124 "Kaydet" - IDS_2125 "86Box Hakkında" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, ve diğerleri.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." - IDS_2128 "Tamam" - IDS_2129 "Donanım mevcut değil" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "" LIB_NAME_PCAP " kurulu olduğundan ve " LIB_NAME_PCAP "-uyumlu bir internet ağında bulunduğunuzdan emin olun." - IDS_2131 "Geçersiz konfigürasyon" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." - IDS_2135 "Tam ekran moduna geçiliyor" - IDS_2136 "Bu mesajı bir daha gösterme" - IDS_2137 "Çıkış yapma" - IDS_2138 "Yeniden başlat" - IDS_2139 "Yeniden başlatma" - IDS_2140 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2141 "CD-ROM imajları (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2142 "%hs Cihaz Konfigürasyonu" - IDS_2143 "Monitör uyku modunda" - IDS_2144 "OpenGL Gölgelendiricileri (*.GLSL)\0*.GLSL\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2145 "OpenGL ayarları" - IDS_2146 "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" - IDS_2147 "Seçtiğiniz makineye uygun CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." - IDS_2148 "Devam et" - IDS_2149 "Kaset: %s" - IDS_2150 "Kaset imajları (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2151 "Kartuş %i: %ls" - IDS_2152 "Kartuş imajları (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2153 "Oluşturucu başlatılırken hata oluştu" - IDS_2154 "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." - IDS_2155 "Yürütmeye devam et" - IDS_2156 "Yürütmeyi duraklat" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "Makineyi yeniden başlat" - IDS_2160 "ACPI kapatma" - IDS_2161 "Ayarlar" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" - IDS_4100 "Diğer..." - IDS_4101 "Diğer (büyük)..." - IDS_4102 "Yeni Hard Disk Dosyası Oluştur" - IDS_4103 "Var Olan Hard Disk Dosyası Ekle" - IDS_4104 "HDI disk imajları 4 GB'tan daha büyük olamaz." - IDS_4105 "Disk imajları 127 GB'tan daha büyük olamaz." - IDS_4106 "Hard disk imajları (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tüm dosyalar (*.*)\0*.*\0" - IDS_4107 "Dosya okunamıyor" - IDS_4108 "Dosyanın üzerine yazılamıyor" - IDS_4109 "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." - IDS_4110 "USB şu anda desteklenmemektedir" - IDS_4111 "Disk imaj dosyası zaten var olmakta" - IDS_4112 "Lütfen geçerli bir dosya ismi belirleyin." - IDS_4113 "Disk imajı oluşturuldu" - IDS_4114 "Dosyanın var olduğuna ve okunabildiğine emin olun." - IDS_4115 "Dosyanın yazılabilir bir klasöre kaydedildiğinden emin olun." - IDS_4116 "Disk imajı çok büyük" - IDS_4117 "Yeni oluşturulan diski bölmeyi ve formatlamayı unutmayın." - IDS_4118 "Seçili dosyanın üzerine yazılacaktır. Bunu yapmak istediğinizden emin misiniz?" - IDS_4119 "Desteklenmeyen disk imajı" - IDS_4120 "Üzerine yaz" - IDS_4121 "Üzerine yazma" - IDS_4122 "Ham imaj (.img)" - IDS_4123 "HDI imajı (.hdi)" - IDS_4124 "HDX imajı (.hdx)" - IDS_4125 "Sabit-boyutlu VHD (.vhd)" - IDS_4126 "Dinamik-boyutlu VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Büyük bloklar (2 MB)" - IDS_4129 "Küçük bloklar (512 KB)" - IDS_4130 "VHD dosyaları (*.VHD)\0*.VHD\0Tüm dosyalar (*.*)\0*.*\0" - IDS_4131 "Ana VHD dosyasını seçin" - IDS_4132 "Bu, farkı alınan imaj oluşturulduktan sonra ana imaj dosyasının düzenlendiği anlamına geliyor olabilir.\n\nBu durum ayrıca imaj dosyaları kopyalandığında veya yerleri değiştirildiğinde veya imaj dosyalarını oluşturan programdaki bir hatadan dolayı olmuş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" - IDS_4133 "Ana ve ek disk zaman damgaları uyuşmuyor" - IDS_4134 "VHD zaman damgası düzeltilemedi." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Devre dışı" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Devre dışı" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Mükemmel RPM" - IDS_6145 "mükemmel RPM değerinin 1% altı" - IDS_6146 "mükemmel RPM değerinin 1.5% altı" - IDS_6147 "mükemmel RPM değerinin 2% altı" - - IDS_7168 "(Sistem Varsayılanı)" -END -#define IDS_LANG_TRTR IDS_7168 - -// Turkish (TR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc deleted file mode 100644 index 53f401e81..000000000 --- a/src/win/languages/uk-UA.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Ukrainian resources - -#ifdef _WIN32 -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Дія" - BEGIN - MENUITEM "&Клавіатура потребує захвату", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правий CTRL - це лівий ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Холодне перезавантаження...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Вихід...", IDM_ACTION_EXIT - END - POPUP "&Вигляд" - BEGIN - MENUITEM "&Приховати рядок стану", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Приховати панель інструментів", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Змінний розмір вікна", IDM_VID_RESIZE - MENUITEM "&Запам'ятати розмір і становище", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Рендеринг" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Вказати розміри...", IDM_VID_SPECIFY_DIM - MENUITEM "&Встановити відношення сторін 4:3", IDM_VID_FORCE43 - POPUP "&Масштаб вікна" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Метод фільтрації" - BEGIN - MENUITEM "&Найближчий", IDM_VID_FILTER_NEAREST - MENUITEM "&Лінійний", IDM_VID_FILTER_LINEAR - END - MENUITEM "Масштабування Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Повноекранний режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Розстягування у повноекранному режимі" - BEGIN - MENUITEM "&На весь екран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Квадратні пікселі (зберегти відношення)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Цілісночисленне масштабування", IDM_VID_FS_INT - END - POPUP "Налаштування E&GA/(S)VGA" - BEGIN - MENUITEM "&Інвертувати кольори VGA", IDM_VID_INVERT - POPUP "&Тип екрана VGA" - BEGIN - MENUITEM "RGB &кольоровий", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромний", IDM_VID_GRAY_MONO - MENUITEM "&Бурштиновий відтінок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелений відтінок", IDM_VID_GRAY_GREEN - MENUITEM "&Білий відтінок", IDM_VID_GRAY_WHITE - END - POPUP "Тип монохромного &конвертування" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усереднений", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Вильоти розгортки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Змінити контрастність &монохромного дисплея", IDM_VID_CGACON - END - MENUITEM "&Носії", IDM_MEDIA - POPUP "&Інструменти" - BEGIN - MENUITEM "&Налаштування машини...", IDM_CONFIG - MENUITEM "&Обновлення значків рядка стану", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Зробити &знімок\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Параметри...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Увімкнути інтеграцію &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Посилення звуку...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Почати трасування\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершити трасування\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Допомога" - BEGIN - MENUITEM "&Документація...", IDM_DOCS - MENUITEM "&Про програму 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Запис", IDM_CASSETTE_RECORD - MENUITEM "&Відтворення", IDM_CASSETTE_PLAY - MENUITEM "&Перемотування на початок", IDM_CASSETTE_REWIND - MENUITEM "&Перемотування у кінець", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Експорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Відключити звук", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Пустий", IDM_CDROM_EMPTY - MENUITEM "&Знову завантажити попередній образ", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Тека...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_ZIP_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_MO_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Цільова &частота кадрів" - BEGIN - MENUITEM "&Синхронізація з відео", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 кадрів в секунду", IDM_VID_GL_FPS_25 - MENUITEM "&30 кадрів в секунду", IDM_VID_GL_FPS_30 - MENUITEM "&50 кадрів в секунду", IDM_VID_GL_FPS_50 - MENUITEM "&60 кадрів в секунду", IDM_VID_GL_FPS_60 - MENUITEM "&75 кадрів в секунду", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Вибрати шейдер...", IDM_VID_GL_SHADER - MENUITEM "&Видалити шейдер", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Параметри" -#define STR_SND_GAIN "Посилення звуку" -#define STR_NEW_FLOPPY "Новий образ" -#define STR_CONFIG "Налаштування" -#define STR_SPECIFY_DIM "Вказати розміри головного вікна" - -#define STR_OK "OK" -#define STR_CANCEL "Відміна" -#define STR_GLOBAL "Зберегти ці параметри як &глобальні за замовчуванням" -#define STR_DEFAULT "&За замовчуванням" -#define STR_LANGUAGE "Мова:" -#define STR_ICONSET "Набір іконок:" - -#define STR_GAIN "Посилення" - -#define STR_FILE_NAME "Ім'я файлу:" -#define STR_DISK_SIZE "Розмір диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогрес:" - -#define STR_WIDTH "Ширина:" -#define STR_HEIGHT "Висота:" -#define STR_LOCK_TO_SIZE "Зафіксувати розмір" - -#define STR_MACHINE_TYPE "Тип машини:" -#define STR_MACHINE "Системна плата:" -#define STR_CONFIGURE "Налаштування" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Швидкість:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Цикли очікування:" -#define STR_MB "МБ" -#define STR_MEMORY "Пам'ять:" -#define STR_TIME_SYNC "Синхронізація часу" -#define STR_DISABLED "Відключити" -#define STR_ENABLED_LOCAL "Увімкнути (місцеве)" -#define STR_ENABLED_UTC "Увімкнути (UTC)" -#define STR_DYNAREC "Динамічний рекомпілятор" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Відеокарта:" -#define STR_VIDEO_2 "Відеокарта 2:" -#define STR_VOODOO "Прискорювач Voodoo" -#define STR_IBM8514 "Прискорювач IBM 8514/A" -#define STR_XGA "Прискорювач XGA" - -#define STR_MOUSE "Миша:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." - -#define STR_SOUND1 "Звукова карта 1:" -#define STR_SOUND2 "Звукова карта 2:" -#define STR_SOUND3 "Звукова карта 3:" -#define STR_SOUND4 "Звукова карта 4:" -#define STR_MIDI_OUT "MIDI Out при-ій:" -#define STR_MIDI_IN "MIDI In при-ій:" -#define STR_MPU401 "Окремий MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (більш точний)" -#define STR_FM_DRV_YMFM "YMFM (швидший)" - -#define STR_NET_TYPE "Тип мережі:" -#define STR_PCAP "Пристрій PCap:" -#define STR_NET "Мережевий адаптер:" -#define STR_NET1 "Мережева карта 1:" -#define STR_NET2 "Мережева карта 2:" -#define STR_NET3 "Мережева карта 3:" -#define STR_NET4 "Мережева карта 4:" - -#define STR_COM1 "Пристрій COM1:" -#define STR_COM2 "Пристрій COM2:" -#define STR_COM3 "Пристрій COM3:" -#define STR_COM4 "Пристрій COM4:" -#define STR_LPT1 "Пристрій LPT1:" -#define STR_LPT2 "Пристрій LPT2:" -#define STR_LPT3 "Пристрій LPT3:" -#define STR_LPT4 "Пристрій LPT4:" -#define STR_SERIAL1 "Послідов. порт COM1" -#define STR_SERIAL2 "Послідов. порт COM2" -#define STR_SERIAL3 "Послідов. порт COM3" -#define STR_SERIAL4 "Послідов. порт COM4" -#define STR_PARALLEL1 "Паралельний порт LPT1" -#define STR_PARALLEL2 "Паралельний порт LPT2" -#define STR_PARALLEL3 "Паралельний порт LPT3" -#define STR_PARALLEL4 "Паралельний порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Контролер HD:" -#define STR_FDC "Контролер FD:" -#define STR_IDE_TER "Третинний IDE контролер" -#define STR_IDE_QUA "Четвертинний IDE контролер" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Контролер 1:" -#define STR_SCSI_2 "Контролер 2:" -#define STR_SCSI_3 "Контролер 3:" -#define STR_SCSI_4 "Контролер 4:" -#define STR_CASSETTE "Касета" - -#define STR_HDD "Жорсткі диски:" -#define STR_NEW "&Створити..." -#define STR_EXISTING "&Вибрати..." -#define STR_REMOVE "&Прибрати" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Вказати..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Циліндри:" -#define STR_SIZE_MB "Розмір (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образу:" -#define STR_BLOCK_SIZE "Розмір блоку:" - -#define STR_FLOPPY_DRIVES "Гнучкі диски:" -#define STR_TURBO "Турбо таймінги" -#define STR_CHECKBPB "Перевіряти BPB" -#define STR_CDROM_DRIVES "Дисководи CD-ROM:" -#define STR_CD_SPEED "Швидкість:" - -#define STR_MO_DRIVES "Магнітооптичні дисководи:" -#define STR_ZIP_DRIVES "ZIP дисководи:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Карта розширення пам'яті (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" -#define STR_BUGGER "Пристрій ISABugger" -#define STR_POSTCARD "Карта POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Помилка" - IDS_2050 "Непереробна помилка" - IDS_2051 " - PAUSED" - IDS_2052 "Натисніть Ctrl+Alt+PgDn для повернення у віконний режим." - IDS_2053 "Швидкість" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box не зміг знайти жодного відповідного для використання файлу з ПЗУ.\n\nБудь ласка завантажте набір ПЗУ і витягніть його в каталог ""roms""." - IDS_2057 "(порожньо)" - IDS_2058 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Усі файли (*.*)\0*.*\0" - IDS_2059 "Турбо" - IDS_2060 "Увімк" - IDS_2061 "Вимк" - IDS_2062 "Усі образи (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Прості посекторні образи (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Образ поверхні (*.86F)\0*.86F\0" - IDS_2063 "Системна плата ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/machines. Переключення на доступну системну плату." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Відеокарта ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Переключення на доступну відеокарту." - IDS_2065 "Комп'ютер" - IDS_2066 "Дисплей" - IDS_2067 "Пристрій введення" - IDS_2068 "Звук" - IDS_2069 "Мережа" - IDS_2070 "Порти (COM и LPT)" - IDS_2071 "Контролери дисків" - IDS_2072 "Жорсткі диски" - IDS_2073 "Гнучкі диски і CD-ROM" - IDS_2074 "Інші знімні при-ої" - IDS_2075 "Інша периферія" - IDS_2076 "Образи Surface (*.86F)\0*.86F\0" - IDS_2077 "Клацніть мишею для захвату курсора" - IDS_2078 "Натисніть F8+F12, щоб звільнити курсор" - IDS_2079 "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Шина" - IDS_2082 "Файл" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "МБ" - IDS_2087 "Speed" - IDS_2088 "Перевіряти BPB" - IDS_2089 "КБ" - IDS_2090 "Не вдалося ініціалізувати рендер відео." - IDS_2091 "За замовчуванням" - IDS_2092 "%i WS" - IDS_2093 "Тип" - IDS_2094 "Не вдалося налаштувати PCap" - IDS_2095 "Пристрої PCap не знайдені" - IDS_2096 "Невірний пристрій PCap" - IDS_2097 "Стандартний 2-кнопковий джойстик" - IDS_2098 "Стандартний 4-кнопковий джойстик" - IDS_2099 "Стандартний 6-кнопковий джойстик" - IDS_2100 "Стандартний 8-кнопковий джойстик" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Система управління польотом Thrustmaster" - IDS_2104 "Ні" - IDS_2105 "Неможливо завантажити прискорювачі клавіатури." - IDS_2106 "Неможливо зарреєструвати необроблене (RAW) введення." - IDS_2107 "%u" - IDS_2108 "%u МБ (CHS: %i, %i, %i)" - IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" - IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" - IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" - IDS_2115 "Неможливо ініціалізувати Ghostscript" - IDS_2116 "Магнітооптичний %i (%ls): %ls" - IDS_2117 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файлі (*.*)\0*.*\0" - IDS_2118 "Ласкаво просимо в 86Box!" - IDS_2119 "Вбудований контролер" - IDS_2120 "Вихід" - IDS_2121 "ПЗУ не знайдені" - IDS_2122 "Чи бажаєте ви зберегти налаштування?" - IDS_2123 "Це призведе до холодної перезагрузки емульованої машини." - IDS_2124 "Зберегти" - IDS_2125 "Про 86Box" - IDS_2126 "86Box v." EMU_VERSION - - IDS_2127 "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." - IDS_2128 "OK" - IDS_2129 "Обладнання недоступне" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Переконайтесь, що " LIB_NAME_PCAP " встановлений і ваше мережеве з'єднання, сумісне з " LIB_NAME_PCAP "." - IDS_2131 "Неприпустима конфігурація" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." - IDS_2135 "Вхід у повноекранний режим" - IDS_2136 "Більше не показувати це повідомлення" - IDS_2137 "Не виходити" - IDS_2138 "Перезавантажити" - IDS_2139 "Не перезавантажувати" - IDS_2140 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файли (*.*)\0*.*\0" - IDS_2141 "Образи CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Усі файли (*.*)\0*.*\0" - IDS_2142 "Конфігурація пристрою %hs" - IDS_2143 "Монітор у сплячому режимі" - IDS_2144 "Шейдери OpenGL (*.GLSL)\0*.GLSL\0Усі файли (*.*)\0*.*\0" - IDS_2145 "Параметри OpenGL" - IDS_2146 "Ви завантажуєте непідтримувану конфігурацію" - IDS_2147 "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." - IDS_2148 "Продовжити" - IDS_2149 "Касета: %s" - IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" - IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Усі файли (*.*)\0*.*\0" - IDS_2153 "Помилка ініціалізації рендерера" - IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." - IDS_2155 "Відновити виконання" - IDS_2156 "Призупинити виконання" - IDS_2157 "Натиснути Ctrl+Alt+Del" - IDS_2158 "Натиснути Ctrl+Alt+Esc" - IDS_2159 "Холодне перезавантаження" - IDS_2160 "Сигнал завершення ACPI" - IDS_2161 "Налаштування машини" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Відеокарта #2 ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Відключення другої відеокарти." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Жорсткий диск (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" - IDS_4100 "Задати вручну..." - IDS_4101 "Задати вручну (large)..." - IDS_4102 "Створити новий жорсткий диск" - IDS_4103 "Вибрати існуючий жорсткий диск" - IDS_4104 "Розмір образів дисків HDI не може перевищувати 4 ГБ." - IDS_4105 "Розмір образів дисків не може перевищувати 127 ГБ." - IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Усі файли (*.*)\0*.*\0 " - IDS_4107 "Неможливо прочитати файл" - IDS_4108 "Неможливо записати файл" - IDS_4109 "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." - IDS_4110 "USB поки не підтримується" - IDS_4111 "Файл образу диска вже існує" - IDS_4112 "Вкажіть правильне ім'я файлу." - IDS_4113 "Образ диску створено" - IDS_4114 "Переконайтеся, що файл є доступним для читання." - IDS_4115 "Переконайтеся, що файл зберігається в каталог, який є доступним для запису." - IDS_4116 "Занадто великий образ диска" - IDS_4117 "Не забудьте розмітити та відформатувати новостворений диск." - IDS_4118 "Вибраний файл буде перезаписано. Ви впевнені, що хочете використовувати його?" - IDS_4119 "Образ диска, що не підтримується" - IDS_4120 "Перезаписати" - IDS_4121 "Не перезаписувати" - IDS_4122 "RAW образ (.img)" - IDS_4123 "Образ HDI (.hdi)" - IDS_4124 "Образ HDX (.hdx)" - IDS_4125 "VHD фіксованого розміру (.vhd)" - IDS_4126 "VHD динамічного розміру (.vhd)" - IDS_4127 "Диференційований образ VHD (.vhd)" - IDS_4128 "Великі блоки (2 МБ)" - IDS_4129 "Маленькі блоки (512 КБ)" - IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Усі файли (*.*)\0*.*\0" - IDS_4131 "Виберіть батьківський VHD" - IDS_4132 "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" - IDS_4133 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" - IDS_4134 "Не вдалося виправити тимчасову позначку VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Відключено" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Відключено" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 кБ" - IDS_5889 "180 кБ" - IDS_5890 "320 кБ" - IDS_5891 "360 кБ" - IDS_5892 "640 кБ" - IDS_5893 "720 кБ" - IDS_5894 "1.2 МБ" - IDS_5895 "1.25 МБ" - IDS_5896 "1.44 МБ" - IDS_5897 "DMF (кластер 1024)" - IDS_5898 "DMF (кластер 2048)" - IDS_5899 "2.88 МБ" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 МБ (ISO 10090)" - IDS_5903 "3.5"" 230 МБ (ISO 13963)" - IDS_5904 "3.5"" 540 МБ (ISO 15498)" - IDS_5905 "3.5"" 640 МБ (ISO 15498)" - IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" - IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" - IDS_5908 "5.25"" 600 МБ" - IDS_5909 "5.25"" 650 МБ" - IDS_5910 "5.25"" 1 ГБ" - IDS_5911 "5.25"" 1.3 ГБ" - - IDS_6144 "Точний RPM" - IDS_6145 "На 1% повільніше точного RPM" - IDS_6146 "На 1.5% повільніше точного RPM" - IDS_6147 "На 2% повільніше точного RPM" - - IDS_7168 "(Системний)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Ukrainian resources -//////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc deleted file mode 100644 index 676574720..000000000 --- a/src/win/languages/zh-CN.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Simplified Chinese resources - -#ifdef _WIN32 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "操作(&A)" - BEGIN - MENUITEM "键盘需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "将右 CTRL 键映射为左 ALT 键(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "硬重置(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "暂停(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT - END - POPUP "查看(&V)" - BEGIN - MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "显示次要显示器(&S)", IDM_VID_MONITORS - MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE - MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "渲染器(&N)" - BEGIN - MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "指定窗口大小...", IDM_VID_SPECIFY_DIM - MENUITEM "强制 4:3 显示比例(&O)", IDM_VID_FORCE43 - POPUP "窗口缩放系数(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "过滤方式" - BEGIN - MENUITEM "邻近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "线性(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 缩放(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全屏(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全屏拉伸模式(&S)" - BEGIN - MENUITEM "全屏拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数比例(&I)", IDM_VID_FS_INT - END - POPUP "EGA/(S)VGA 设置(&G)" - BEGIN - MENUITEM "VGA 显示器反色显示(&I)", IDM_VID_INVERT - POPUP "VGA 屏幕类型(&T)" - BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色单色显示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "绿色单色显示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色单色显示器(&W)", IDM_VID_GRAY_WHITE - END - POPUP "灰度转换类型(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)", IDM_VID_OVERSCAN - MENUITEM "更改单色显示对比度(&M)", IDM_VID_CGACON - END - MENUITEM "介质(&M)", IDM_MEDIA - POPUP "工具(&T)" - BEGIN - MENUITEM "设置(&S)...", IDM_CONFIG - MENUITEM "更新状态栏图标(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "截图(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "首选项(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "启用 Discord 集成(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "开始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "结束追踪\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "帮助(&H)" - BEGIN - MENUITEM "文档(&D)...", IDM_DOCS - MENUITEM "关于 86Box(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "录制(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒带至起点(&R)", IDM_CASSETTE_REWIND - MENUITEM "快进至终点(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "静音(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY - MENUITEM "载入上一个映像(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "映像(&I)...", IDM_CDROM_IMAGE - MENUITEM "文件夹(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_ZIP_EJECT - MENUITEM "载入上一个映像(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_MO_EJECT - MENUITEM "载入上一个映像(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目标帧率(&F)" - BEGIN - MENUITEM "与视频同步(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC - MENUITEM "选择着色器(&S)...", IDM_VID_GL_SHADER - MENUITEM "移除着色器(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "首选项" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新建映像" -#define STR_CONFIG "设置" -#define STR_SPECIFY_DIM "指定主窗口大小" - -#define STR_OK "确定" -#define STR_CANCEL "取消" -#define STR_GLOBAL "将以上设置存储为全局默认值(&G)" -#define STR_DEFAULT "默认(&D)" -#define STR_LANGUAGE "语言:" -#define STR_ICONSET "图标集:" - -#define STR_GAIN "增益" - -#define STR_FILE_NAME "文件名:" -#define STR_DISK_SIZE "磁盘大小:" -#define STR_RPM_MODE "转速 (RPM) 模式:" -#define STR_PROGRESS "进度:" - -#define STR_WIDTH "宽度:" -#define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "锁定此大小" - -#define STR_MACHINE_TYPE "机器类型:" -#define STR_MACHINE "机型:" -#define STR_CONFIGURE "配置" -#define STR_CPU_TYPE "CPU 类型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮点处理器 (FPU):" -#define STR_WAIT_STATES "等待状态 (WS):" -#define STR_MB "MB" -#define STR_MEMORY "内存:" -#define STR_TIME_SYNC "时间同步" -#define STR_DISABLED "禁用" -#define STR_ENABLED_LOCAL "启用 (本地时间)" -#define STR_ENABLED_UTC "启用 (协调世界时)" -#define STR_DYNAREC "动态重编译器" -#define STR_SOFTFLOAT "软浮点 FPU" - -#define STR_VIDEO "显卡:" -#define STR_VIDEO_2 "显卡 2:" -#define STR_VOODOO "Voodoo 显卡" -#define STR_IBM8514 "IBM 8514/A 显卡" -#define STR_XGA "XGA 显卡" - -#define STR_MOUSE "鼠标:" -#define STR_JOYSTICK "操纵杆:" -#define STR_JOY1 "操纵杆 1..." -#define STR_JOY2 "操纵杆 2..." -#define STR_JOY3 "操纵杆 3..." -#define STR_JOY4 "操纵杆 4..." - -#define STR_SOUND1 "声卡 1:" -#define STR_SOUND2 "声卡 2:" -#define STR_SOUND3 "声卡 3:" -#define STR_SOUND4 "声卡 4:" -#define STR_MIDI_OUT "MIDI 输出设备:" -#define STR_MIDI_IN "MIDI 输入设备:" -#define STR_MPU401 "独立 MPU-401" -#define STR_FLOAT "使用单精度浮点 (FLOAT32)" -#define STR_FM_DRIVER "调频合成器驱动器" -#define STR_FM_DRV_NUKED "Nuked (更准确)" -#define STR_FM_DRV_YMFM "YMFM (更快)" - -#define STR_NET_TYPE "网络类型:" -#define STR_PCAP "PCap 设备:" -#define STR_NET "网络适配器:" -#define STR_NET1 "网卡 1:" -#define STR_NET2 "网卡 2:" -#define STR_NET3 "网卡 3:" -#define STR_NET4 "网卡 4:" - -#define STR_COM1 "COM1 设备:" -#define STR_COM2 "COM2 设备:" -#define STR_COM3 "COM3 设备:" -#define STR_COM4 "COM4 设备:" -#define STR_LPT1 "LPT1 设备:" -#define STR_LPT2 "LPT2 设备:" -#define STR_LPT3 "LPT3 设备:" -#define STR_LPT4 "LPT4 设备:" -#define STR_SERIAL1 "串口 1" -#define STR_SERIAL2 "串口 2" -#define STR_SERIAL3 "串口 3" -#define STR_SERIAL4 "串口 4" -#define STR_PARALLEL1 "并口 1" -#define STR_PARALLEL2 "并口 2" -#define STR_PARALLEL3 "并口 3" -#define STR_PARALLEL4 "并口 4" -#define STR_SERIAL_PASS1 "串口直通 1" -#define STR_SERIAL_PASS2 "串口直通 2" -#define STR_SERIAL_PASS3 "串口直通 3" -#define STR_SERIAL_PASS4 "串口直通 4" - -#define STR_HDC "硬盘控制器:" -#define STR_FDC "软盘控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "控制器 1:" -#define STR_SCSI_2 "控制器 2:" -#define STR_SCSI_3 "控制器 3:" -#define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁带" - -#define STR_HDD "硬盘:" -#define STR_NEW "新建(&N)..." -#define STR_EXISTING "已有映像(&E)..." -#define STR_REMOVE "移除(&R)" -#define STR_BUS "总线:" -#define STR_CHANNEL "通道:" -#define STR_ID "ID:" -#define STR_SPEED "速度:" - -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "扇区(S):" -#define STR_HEADS "磁头(H):" -#define STR_CYLS "柱面(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "类型:" -#define STR_IMG_FORMAT "映像格式:" -#define STR_BLOCK_SIZE "块大小:" - -#define STR_FLOPPY_DRIVES "软盘驱动器:" -#define STR_TURBO "加速时序" -#define STR_CHECKBPB "检查 BPB" -#define STR_CDROM_DRIVES "光盘驱动器:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "磁光盘驱动器:" -#define STR_ZIP_DRIVES "ZIP 驱动器:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA 实时时钟:" -#define STR_ISAMEM "ISA 内存扩充" -#define STR_ISAMEM_1 "扩展卡 1:" -#define STR_ISAMEM_2 "扩展卡 2:" -#define STR_ISAMEM_3 "扩展卡 3:" -#define STR_ISAMEM_4 "扩展卡 4:" -#define STR_BUGGER "ISABugger 设备" -#define STR_POSTCARD "自检 (POST) 卡" - -#define FONT_SIZE 9 -#define FONT_NAME "Microsoft YaHei" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "错误" - IDS_2050 "致命错误" - IDS_2051 " - 已暂停" - IDS_2052 "按下 Ctrl+Alt+PgDn 返回到窗口模式。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到任何可用的 ROM 映像。\n\n请下载ROM 包并将其解压到 ""roms"" 文件夹中。" - IDS_2057 "(空)" - IDS_2058 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有文件 (*.*)\0*.*\0" - IDS_2059 "加速" - IDS_2060 "开" - IDS_2061 "关" - IDS_2062 "所有映像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区映像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面映像 (*.86F)\0*.86F\0" - IDS_2063 "由于 roms/machines 文件夹中缺少合适的 ROM,机型 ""%hs"" 不可用。将切换到其他可用机型。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 ""%hs"" 不可用。将切换到其他可用显卡。" - IDS_2065 "机型" - IDS_2066 "显示" - IDS_2067 "输入设备" - IDS_2068 "声音" - IDS_2069 "网络" - IDS_2070 "端口 (COM 和 LPT)" - IDS_2071 "存储控制器" - IDS_2072 "硬盘" - IDS_2073 "软盘/光盘驱动器" - IDS_2074 "其他可移动设备" - IDS_2075 "其他外围设备" - IDS_2076 "表面映像 (*.86F)\0*.86F\0" - IDS_2077 "单击窗口捕捉鼠标" - IDS_2078 "按下 F8+F12 释放鼠标" - IDS_2079 "按下 F8+F12 或鼠标中键释放鼠标" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "总线" - IDS_2082 "文件" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "速度" - IDS_2088 "检查 BPB" - IDS_2089 "KB" - IDS_2090 "无法初始化视频渲染器。" - IDS_2091 "默认" - IDS_2092 "%i 等待状态 (WS)" - IDS_2093 "类型" - IDS_2094 "设置 PCap 失败" - IDS_2095 "未找到 PCap 设备" - IDS_2096 "无效 PCap 设备" - IDS_2097 "标准 2 键操纵杆" - IDS_2098 "标准 4 键操纵杆" - IDS_2099 "标准 6 键操纵杆" - IDS_2100 "标准 8 键操纵杆" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "无" - IDS_2105 "无法加载键盘加速器。" - IDS_2106 "无法注册原始输入。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "软盘 %i (%s): %ls" - IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2113 "确定要硬重置模拟器吗?" - IDS_2114 "确定要退出 86Box 吗?" - IDS_2115 "无法初始化 Ghostscript" - IDS_2116 "磁光盘 %i (%ls): %ls" - IDS_2117 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2118 "欢迎使用 86Box!" - IDS_2119 "内部控制器" - IDS_2120 "退出" - IDS_2121 "找不到 ROM" - IDS_2122 "要保存设置吗?" - IDS_2123 "此操作将硬重置模拟器。" - IDS_2124 "保存" - IDS_2125 "关于 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" - IDS_2128 "确定" - IDS_2129 "硬件不可用" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" - IDS_2131 "无效配置" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" - IDS_2135 "正在进入全屏模式" - IDS_2136 "不再显示此消息" - IDS_2137 "不退出" - IDS_2138 "重置" - IDS_2139 "不重置" - IDS_2140 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2141 "光盘映像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" - IDS_2142 "%hs 设备配置" - IDS_2143 "显示器处在睡眠状态" - IDS_2144 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" - IDS_2145 "OpenGL 选项" - IDS_2146 "正在载入一个不受支持的配置" - IDS_2147 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" - IDS_2148 "继续" - IDS_2149 "磁带: %s" - IDS_2150 "磁带映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" - IDS_2151 "卡带 %i: %ls" - IDS_2152 "卡带映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" - IDS_2153 "初始化渲染器时出错" - IDS_2154 "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" - IDS_2155 "恢复执行" - IDS_2156 "暂停执行" - IDS_2157 "按下 Ctrl+Alt+Del" - IDS_2158 "按下 Ctrl+Alt+Esc" - IDS_2159 "硬重置" - IDS_2160 "ACPI 关机" - IDS_2161 "设置" - IDS_2162 "类型" - IDS_2163 "无动态重编译" - IDS_2164 "旧式动态重编译" - IDS_2165 "新式动态重编译" - IDS_2166 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 #2 ""%hs"" 不可用。将禁用第二张显卡。" - IDS_2167 "初始化网络驱动程序失败" - IDS_2168 "网络配置将切换为空驱动程序" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "硬盘 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" - IDS_4100 "自定义..." - IDS_4101 "自定义 (大容量)..." - IDS_4102 "添加新硬盘" - IDS_4103 "添加已存在的硬盘" - IDS_4104 "HDI 磁盘映像不能超过 4 GB。" - IDS_4105 "磁盘映像不能超过 127 GB。" - IDS_4106 "硬盘映像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有文件 (*.*)\0*.*\0" - IDS_4107 "无法读取文件" - IDS_4108 "无法写入文件" - IDS_4109 "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" - IDS_4110 "尚未支持 USB" - IDS_4111 "磁盘映像文件已存在" - IDS_4112 "请指定有效的文件名。" - IDS_4113 "已创建磁盘映像" - IDS_4114 "请确定此文件已存在并可读取。" - IDS_4115 "请确定此文件保存在可写目录中。" - IDS_4116 "磁盘映像太大" - IDS_4117 "请记得为新创建的映像分区并格式化。" - IDS_4118 "选定的文件将被覆盖。确定继续使用此文件吗?" - IDS_4119 "不支持的磁盘映像" - IDS_4120 "覆盖" - IDS_4121 "不覆盖" - IDS_4122 "原始映像 (.img)" - IDS_4123 "HDI 映像 (.hdi)" - IDS_4124 "HDX 映像 (.hdx)" - IDS_4125 "固定大小 VHD (.vhd)" - IDS_4126 "动态大小 VHD (.vhd)" - IDS_4127 "差分 VHD (.vhd)" - IDS_4128 "大块 (2 MB)" - IDS_4129 "小块 (512 KB)" - IDS_4130 "VHD 文件 (*.VHD)\0*.VHD\0所有文件 (*.*)\0*.*\0" - IDS_4131 "选择父 VHD 文件" - IDS_4132 "父映像可能在创建差异映像后被修改。\n\n如果映像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" - IDS_4133 "父盘与子盘的时间戳不匹配" - IDS_4134 "无法修复 VHD 时间戳。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "光盘 %i (%s): %s" - - IDS_5376 "禁用" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "禁用" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 簇)" - IDS_5898 "DMF (2048 簇)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5 英寸 128 MB (ISO 10090)" - IDS_5903 "3.5 英寸 230 MB (ISO 13963)" - IDS_5904 "3.5 英寸 540 MB (ISO 15498)" - IDS_5905 "3.5 英寸 640 MB (ISO 15498)" - IDS_5906 "3.5 英寸 1.3 GB (GigaMO)" - IDS_5907 "3.5 英寸 2.3 GB (GigaMO 2)" - IDS_5908 "5.25 英寸 600 MB" - IDS_5909 "5.25 英寸 650 MB" - IDS_5910 "5.25 英寸 1 GB" - IDS_5911 "5.25 英寸 1.3 GB" - - IDS_6144 "标准转速 (RPM)" - IDS_6145 "低于标准转速的 1%" - IDS_6146 "低于标准转速的 1.5%" - IDS_6147 "低于标准转速的 2%" - - IDS_7168 "(系统默认)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Simplified Chinese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc deleted file mode 100644 index 171d8e3f6..000000000 --- a/src/win/languages/zh-TW.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Traditional Chinese resources - -#ifdef _WIN32 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "動作(&A)" - BEGIN - MENUITEM "鍵盤需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "將右 CTRL 鍵映射為左 ALT 鍵(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "硬重設(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "暫停(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT - END - POPUP "檢視(&V)" - BEGIN - MENUITEM "隱藏狀態列(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隱藏工具列(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS - MENUITEM "視窗大小可調(&R)", IDM_VID_RESIZE - MENUITEM "記住視窗大小和位置(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "渲染器(&N)" - BEGIN - MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "指定視窗大小...", IDM_VID_SPECIFY_DIM - MENUITEM "強制 4:3 顯示比例(&O)", IDM_VID_FORCE43 - POPUP "視窗縮放係數(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "過濾方式" - BEGIN - MENUITEM "鄰近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線性(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 縮放(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全螢幕(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全螢幕拉伸模式(&S)" - BEGIN - MENUITEM "全螢幕拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整數比例(&I)", IDM_VID_FS_INT - END - POPUP "EGA/(S)VGA 設定(&G)" - BEGIN - MENUITEM "VGA 顯示器反色顯示(&I)", IDM_VID_INVERT - POPUP "VGA 螢幕類型(&T)" - BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色單色顯示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "綠色單色顯示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色單色顯示器(&W)", IDM_VID_GRAY_WHITE - END - POPUP "灰度轉換類型(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)", IDM_VID_OVERSCAN - MENUITEM "變更單色顯示對比度(&M)", IDM_VID_CGACON - END - MENUITEM "介質(&M)", IDM_MEDIA - POPUP "工具(&T)" - BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "更新狀態列圖示(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "偏好設定(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "啟用 Discord 整合(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "開始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "結束追踪\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "說明(&H)" - BEGIN - MENUITEM "文件(&D)...", IDM_DOCS - MENUITEM "關於 86Box(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "錄製(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒帶至起點(&R)", IDM_CASSETTE_REWIND - MENUITEM "快進至終點(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "匯出為 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "靜音(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空置光碟機(&M)", IDM_CDROM_EMPTY - MENUITEM "載入上一個映像(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "映像(&I)...", IDM_CDROM_IMAGE - MENUITEM "資料夾(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_ZIP_EJECT - MENUITEM "載入上一個映像(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_MO_EJECT - MENUITEM "載入上一個映像(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目標幀率(&F)" - BEGIN - MENUITEM "與視訊同步(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC - MENUITEM "選取著色器(&S)...", IDM_VID_GL_SHADER - MENUITEM "移除著色器(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "偏好設定" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新增映像" -#define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "指定主視窗大小" - -#define STR_OK "確定" -#define STR_CANCEL "取消" -#define STR_GLOBAL "將以上設定存儲為全局預設值(&G)" -#define STR_DEFAULT "預設(&D)" -#define STR_LANGUAGE "語言:" -#define STR_ICONSET "圖示集:" - -#define STR_GAIN "增益" - -#define STR_FILE_NAME "檔案名:" -#define STR_DISK_SIZE "磁碟大小:" -#define STR_RPM_MODE "轉速 (RPM) 模式:" -#define STR_PROGRESS "進度:" - -#define STR_WIDTH "寬度:" -#define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "鎖定此大小" - -#define STR_MACHINE_TYPE "機器類型:" -#define STR_MACHINE "機型:" -#define STR_CONFIGURE "設定" -#define STR_CPU_TYPE "CPU 類型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮點處理器 (FPU):" -#define STR_WAIT_STATES "等待狀態 (WS):" -#define STR_MB "MB" -#define STR_MEMORY "記憶體:" -#define STR_TIME_SYNC "時間同步" -#define STR_DISABLED "停用" -#define STR_ENABLED_LOCAL "啟用 (本地時間)" -#define STR_ENABLED_UTC "啟用 (UTC)" -#define STR_DYNAREC "動態重編譯器" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "顯示卡:" -#define STR_VIDEO_2 "顯示卡 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "滑鼠:" -#define STR_JOYSTICK "搖桿:" -#define STR_JOY1 "搖桿 1..." -#define STR_JOY2 "搖桿 2..." -#define STR_JOY3 "搖桿 3..." -#define STR_JOY4 "搖桿 4..." - -#define STR_SOUND1 "音效卡 1:" -#define STR_SOUND2 "音效卡 2:" -#define STR_SOUND3 "音效卡 3:" -#define STR_SOUND4 "音效卡 4:" -#define STR_MIDI_OUT "MIDI 輸出裝置:" -#define STR_MIDI_IN "MIDI 輸入裝置:" -#define STR_MPU401 "獨立 MPU-401" -#define STR_FLOAT "使用單精度浮點 (FLOAT32)" -#define STR_FM_DRIVER "調頻合成器驅動器" -#define STR_FM_DRV_NUKED "Nuked (更準確)" -#define STR_FM_DRV_YMFM "YMFM (更快)" - -#define STR_NET_TYPE "網路類型:" -#define STR_PCAP "PCap 裝置:" -#define STR_NET "網路配接器:" -#define STR_NET1 "網路卡 1:" -#define STR_NET2 "網路卡 2:" -#define STR_NET3 "網路卡 3:" -#define STR_NET4 "網路卡 4:" - -#define STR_COM1 "COM1 裝置:" -#define STR_COM2 "COM2 裝置:" -#define STR_COM3 "COM3 裝置:" -#define STR_COM4 "COM4 裝置:" -#define STR_LPT1 "LPT1 裝置:" -#define STR_LPT2 "LPT2 裝置:" -#define STR_LPT3 "LPT3 裝置:" -#define STR_LPT4 "LPT4 裝置:" -#define STR_SERIAL1 "序列埠 1" -#define STR_SERIAL2 "序列埠 2" -#define STR_SERIAL3 "序列埠 3" -#define STR_SERIAL4 "序列埠 4" -#define STR_PARALLEL1 "並列埠 1" -#define STR_PARALLEL2 "並列埠 2" -#define STR_PARALLEL3 "並列埠 3" -#define STR_PARALLEL4 "並列埠 4" -#define STR_SERIAL_PASS1 "序列埠直通 1" -#define STR_SERIAL_PASS2 "序列埠直通 2" -#define STR_SERIAL_PASS3 "序列埠直通 3" -#define STR_SERIAL_PASS4 "序列埠直通 4" - -#define STR_HDC "硬碟控制器:" -#define STR_FDC "軟碟控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "控制器 1:" -#define STR_SCSI_2 "控制器 2:" -#define STR_SCSI_3 "控制器 3:" -#define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁帶" - -#define STR_HDD "硬碟:" -#define STR_NEW "新增(&N)..." -#define STR_EXISTING "已有映像(&E)..." -#define STR_REMOVE "移除(&R)" -#define STR_BUS "匯流排:" -#define STR_CHANNEL "通道:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "磁區(S):" -#define STR_HEADS "磁頭(H):" -#define STR_CYLS "磁柱(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "類型:" -#define STR_IMG_FORMAT "映像格式:" -#define STR_BLOCK_SIZE "區塊大小:" - -#define STR_FLOPPY_DRIVES "軟碟機:" -#define STR_TURBO "加速時序" -#define STR_CHECKBPB "檢查 BPB" -#define STR_CDROM_DRIVES "光碟機:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "磁光碟機:" -#define STR_ZIP_DRIVES "ZIP 磁碟機:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA 實時時鐘:" -#define STR_ISAMEM "ISA 記憶體擴充" -#define STR_ISAMEM_1 "擴充卡 1:" -#define STR_ISAMEM_2 "擴充卡 2:" -#define STR_ISAMEM_3 "擴充卡 3:" -#define STR_ISAMEM_4 "擴充卡 4:" -#define STR_BUGGER "ISABugger 裝置" -#define STR_POSTCARD "自檢 (POST) 卡" - -#define FONT_SIZE 9 -#define FONT_NAME "Microsoft JhengHei" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "錯誤" - IDS_2050 "致命錯誤" - IDS_2051 " - 已暫停" - IDS_2052 "按下 Ctrl+Alt+PgDn 返回到視窗模式。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到任何可用的 ROM 映像。\n\n請下載 ROM 套件並將其解壓到 ""roms"" 資料夾。" - IDS_2057 "(空)" - IDS_2058 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有檔案 (*.*)\0*.*\0" - IDS_2059 "加速" - IDS_2060 "開" - IDS_2061 "關" - IDS_2062 "所有映像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本磁區映像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面映像 (*.86F)\0*.86F\0" - IDS_2063 "由於 roms/machines 資料夾中缺少合適的 ROM,機型 ""%hs"" 不可用。將切換到其他可用機型。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 ""%hs"" 不可用。將切換到其他可用顯示卡。" - IDS_2065 "機型" - IDS_2066 "顯示" - IDS_2067 "輸入裝置" - IDS_2068 "聲音" - IDS_2069 "網路" - IDS_2070 "連接埠 (COM 和 LPT)" - IDS_2071 "存儲控制器" - IDS_2072 "硬碟" - IDS_2073 "軟碟/光碟機" - IDS_2074 "其他可移除裝置" - IDS_2075 "其他周邊裝置" - IDS_2076 "表面映像 (*.86F)\0*.86F\0" - IDS_2077 "點擊視窗捕捉滑鼠" - IDS_2078 "按下 F8+F12 釋放滑鼠" - IDS_2079 "按下 F8+F12 或滑鼠中鍵釋放滑鼠" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "匯流排" - IDS_2082 "檔案" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "檢查 BPB" - IDS_2089 "KB" - IDS_2090 "無法初始化視訊渲染器。" - IDS_2091 "預設" - IDS_2092 "%i 等待狀態 (WS)" - IDS_2093 "類型" - IDS_2094 "設定 PCap 失敗" - IDS_2095 "未找到 PCap 裝置" - IDS_2096 "無效 PCap 裝置" - IDS_2097 "標準 2 鍵搖桿" - IDS_2098 "標準 4 鍵搖桿" - IDS_2099 "標準 6 鍵搖桿" - IDS_2100 "標準 8 鍵搖桿" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "無" - IDS_2105 "無法載入鍵盤加速器。" - IDS_2106 "無法註冊原始輸入。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "軟碟 %i (%s): %ls" - IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" - IDS_2113 "確定要硬重設模擬器嗎?" - IDS_2114 "確定要退出 86Box 嗎?" - IDS_2115 "無法初始化 Ghostscript" - IDS_2116 "磁光碟 %i (%ls): %ls" - IDS_2117 "磁光碟映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" - IDS_2118 "歡迎使用 86Box!" - IDS_2119 "內部控制器" - IDS_2120 "退出" - IDS_2121 "找不到 ROM" - IDS_2122 "要儲存設定嗎?" - IDS_2123 "此操作將硬重設模擬器。" - IDS_2124 "儲存" - IDS_2125 "關於 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" - IDS_2128 "確定" - IDS_2129 "硬體不可用" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "請確認 " LIB_NAME_PCAP " 已安裝且使用相容 " LIB_NAME_PCAP " 的網路連線。" - IDS_2131 "無效設定" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" - IDS_2135 "正在進入全螢幕模式" - IDS_2136 "不要再顯示此消息" - IDS_2137 "不退出" - IDS_2138 "重設" - IDS_2139 "不重設" - IDS_2140 "磁光碟映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" - IDS_2141 "光碟映像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有檔案 (*.*)\0*.*\0" - IDS_2142 "%hs 裝置設定" - IDS_2143 "顯示器處在睡眠狀態" - IDS_2144 "OpenGL 著色器 (*.GLSL)\0*.GLSL\0所有檔案 (*.*)\0*.*\0" - IDS_2145 "OpenGL 選項" - IDS_2146 "正在載入一個不受支援的設定" - IDS_2147 "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" - IDS_2148 "繼續" - IDS_2149 "磁帶: %s" - IDS_2150 "磁帶映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有檔案 (*.*)\0*.*\0" - IDS_2151 "卡帶 %i: %ls" - IDS_2152 "卡帶映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有檔案 (*.*)\0*.*\0" - IDS_2153 "初始化渲染器時出錯" - IDS_2154 "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" - IDS_2155 "恢復執行" - IDS_2156 "暫停執行" - IDS_2157 "按下 Ctrl+Alt+Del" - IDS_2158 "按下 Ctrl+Alt+Esc" - IDS_2159 "硬重設" - IDS_2160 "ACPI 關機" - IDS_2161 "設定" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "硬碟 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" - IDS_4100 "自訂..." - IDS_4101 "自訂 (大容量)..." - IDS_4102 "增加新硬碟" - IDS_4103 "增加已存在的硬碟" - IDS_4104 "HDI 磁碟映像不能超過 4 GB。" - IDS_4105 "磁碟映像不能超過 127 GB。" - IDS_4106 "硬碟映像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有檔案 (*.*)\0*.*\0" - IDS_4107 "無法讀取檔案" - IDS_4108 "無法寫入檔案" - IDS_4109 "不支援非 512 位元組磁區大小的 HDI 或 HDX 映像。" - IDS_4110 "尚未支援 USB" - IDS_4111 "磁碟映像檔案已存在" - IDS_4112 "請指定有效的檔案名。" - IDS_4113 "已創建磁碟映像" - IDS_4114 "請確定此檔案已存在並可讀取。" - IDS_4115 "請確定此檔案儲存在可寫目錄中。" - IDS_4116 "磁碟映像太大" - IDS_4117 "請記得為新創建的映像分區並格式化。" - IDS_4118 "選定的檔案將被覆蓋。確定繼續使用此檔案嗎?" - IDS_4119 "不支援的磁碟映像" - IDS_4120 "覆蓋" - IDS_4121 "不覆蓋" - IDS_4122 "原始映像 (.img)" - IDS_4123 "HDI 映像 (.hdi)" - IDS_4124 "HDX 映像 (.hdx)" - IDS_4125 "固定大小 VHD (.vhd)" - IDS_4126 "動態大小 VHD (.vhd)" - IDS_4127 "差分 VHD (.vhd)" - IDS_4128 "大區塊 (2 MB)" - IDS_4129 "小區塊 (512 KB)" - IDS_4130 "VHD 檔案 (*.VHD)\0*.VHD\0所有檔案 (*.*)\0*.*\0" - IDS_4131 "選取父 VHD 檔案" - IDS_4132 "父映像可能在創建差異映像後被修改。\n\n如果映像檔案被移動或複製,或創建此磁碟的程式中存在錯誤,也可能發生這種情況。\n\n是否需要修復時間戳?" - IDS_4133 "父碟與子碟的時間戳不匹配" - IDS_4134 "無法修復 VHD 時間戳。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "光碟 %i (%s): %s" - - IDS_5376 "停用" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "停用" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 簇)" - IDS_5898 "DMF (2048 簇)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5 英吋 128 MB (ISO 10090)" - IDS_5903 "3.5 英吋 230 MB (ISO 13963)" - IDS_5904 "3.5 英吋 540 MB (ISO 15498)" - IDS_5905 "3.5 英吋 640 MB (ISO 15498)" - IDS_5906 "3.5 英吋 1.3 GB (GigaMO)" - IDS_5907 "3.5 英吋 2.3 GB (GigaMO 2)" - IDS_5908 "5.25 英吋 600 MB" - IDS_5909 "5.25 英吋 650 MB" - IDS_5910 "5.25 英吋 1 GB" - IDS_5911 "5.25 英吋 1.3 GB" - - IDS_6144 "標準轉速 (RPM)" - IDS_6145 "低於標準轉速的 1%" - IDS_6146 "低於標準轉速的 1.5%" - IDS_6147 "低於標準轉速的 2%" - - IDS_7168 "(系統預設)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Traditional Chinese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/pcap_if.rc b/src/win/pcap_if.rc deleted file mode 100644 index acc6d25c4..000000000 --- a/src/win/pcap_if.rc +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef _WIN32 -#include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - - -/* - * Icons by Devcore - * - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png - */ -#ifdef RELEASE_BUILD -100 ICON DISCARDABLE "win/icons/86Box-RB.ico" -#else -100 ICON DISCARDABLE "win/icons/86Box.ico" -#endif - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,2,0 - PRODUCTVERSION 1,0,2,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "IRC #SoftHistory\0" - VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" - VALUE "FileVersion", "1.0.2\0" - VALUE "InternalName", "pcap_if\0" - VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "pcap_if.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "WinPcap Test Tool\0" - VALUE "ProductVersion", "1.0.2\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/win/win.c b/src/win/win.c deleted file mode 100644 index d77ab32fd..000000000 --- a/src/win/win.c +++ /dev/null @@ -1,1346 +0,0 @@ -/* - * 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. - * - * Platform main support module for Windows. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define NTDDI_VERSION 0x06010000 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mouse.h> -#include <86box/timer.h> -#include <86box/nvr.h> -#include <86box/video.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/path.h> -#define GLOBAL -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/thread.h> -#include <86box/ui.h> -#ifdef USE_VNC -# include <86box/vnc.h> -#endif -#include <86box/win_sdl.h> -#include <86box/win_opengl.h> -#include <86box/win.h> -#include <86box/version.h> -#include <86box/gdbstub.h> -#ifdef MTR_ENABLED -# include -#endif - -typedef struct rc_str_t { - WCHAR str[1024]; -} rc_str_t; - -/* Platform Public data, specific. */ -HINSTANCE hinstance; /* application instance */ -HANDLE ghMutex; -uint32_t lang_id; /* current and system language ID */ -uint32_t lang_sys; /* current and system language ID */ -DWORD dwSubLangID; -int acp_utf8; /* Windows supports UTF-8 codepage */ -volatile int cpu_thread_run = 1; - -/* Local data. */ -static HANDLE thMain; -static rc_str_t *lpRCstr2048 = NULL; -static rc_str_t *lpRCstr4096 = NULL; -static rc_str_t *lpRCstr4352 = NULL; -static rc_str_t *lpRCstr4608 = NULL; -static rc_str_t *lpRCstr5120 = NULL; -static rc_str_t *lpRCstr5376 = NULL; -static rc_str_t *lpRCstr5632 = NULL; -static rc_str_t *lpRCstr5888 = NULL; -static rc_str_t *lpRCstr6144 = NULL; -static rc_str_t *lpRCstr7168 = NULL; -static int vid_api_inited = 0; -static char *argbuf; -static int first_use = 1; -static LARGE_INTEGER StartingTime; -static LARGE_INTEGER Frequency; - -static const struct { - const char *name; - int local; - int (*init)(void *); - void (*close)(void); - void (*resize)(int x, int y); - int (*pause)(void); - void (*enable)(int enable); - void (*set_fs)(int fs); - void (*reload)(void); -} vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int (*)(void *)) sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_Hardware", 1, (int (*)(void *)) sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_OpenGL", 1, (int (*)(void *)) sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "OpenGL_Core", 1, (int (*)(void *)) opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload } -#ifdef USE_VNC - , - { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } -#endif -}; - -extern int title_update; - -#ifdef ENABLE_WIN_LOG -int win_do_log = ENABLE_WIN_LOG; - -static void -win_log(const char *fmt, ...) -{ - va_list ap; - - if (win_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define win_log(fmt, ...) -#endif - -void -free_string(rc_str_t **str) -{ - if (*str != NULL) { - free(*str); - *str = NULL; - } -} - -static void -LoadCommonStrings(void) -{ - int i; - - free_string(&lpRCstr7168); - free_string(&lpRCstr6144); - free_string(&lpRCstr5888); - free_string(&lpRCstr5632); - free_string(&lpRCstr5376); - free_string(&lpRCstr5120); - free_string(&lpRCstr4608); - free_string(&lpRCstr4352); - free_string(&lpRCstr4096); - free_string(&lpRCstr2048); - - lpRCstr2048 = calloc(STR_NUM_2048, sizeof(rc_str_t)); - lpRCstr4096 = calloc(STR_NUM_4096, sizeof(rc_str_t)); - lpRCstr4352 = calloc(STR_NUM_4352, sizeof(rc_str_t)); - lpRCstr4608 = calloc(STR_NUM_4608, sizeof(rc_str_t)); - lpRCstr5120 = calloc(STR_NUM_5120, sizeof(rc_str_t)); - lpRCstr5376 = calloc(STR_NUM_5376, sizeof(rc_str_t)); - lpRCstr5632 = calloc(STR_NUM_5632, sizeof(rc_str_t)); - lpRCstr5888 = calloc(STR_NUM_5888, sizeof(rc_str_t)); - lpRCstr6144 = calloc(STR_NUM_6144, sizeof(rc_str_t)); - lpRCstr7168 = calloc(STR_NUM_7168, sizeof(rc_str_t)); - - for (i = 0; i < STR_NUM_2048; i++) - LoadString(hinstance, 2048 + i, lpRCstr2048[i].str, 1024); - - for (i = 0; i < STR_NUM_4096; i++) - LoadString(hinstance, 4096 + i, lpRCstr4096[i].str, 1024); - - for (i = 0; i < STR_NUM_4352; i++) - LoadString(hinstance, 4352 + i, lpRCstr4352[i].str, 1024); - - for (i = 0; i < STR_NUM_4608; i++) - LoadString(hinstance, 4608 + i, lpRCstr4608[i].str, 1024); - - for (i = 0; i < STR_NUM_5120; i++) - LoadString(hinstance, 5120 + i, lpRCstr5120[i].str, 1024); - - for (i = 0; i < STR_NUM_5376; i++) { - if ((i == 0) || (i > 3)) - LoadString(hinstance, 5376 + i, lpRCstr5376[i].str, 1024); - } - - for (i = 0; i < STR_NUM_5632; i++) { - if ((i == 0) || (i > 3)) - LoadString(hinstance, 5632 + i, lpRCstr5632[i].str, 1024); - } - - for (i = 0; i < STR_NUM_5888; i++) - LoadString(hinstance, 5888 + i, lpRCstr5888[i].str, 1024); - - for (i = 0; i < STR_NUM_6144; i++) - LoadString(hinstance, 6144 + i, lpRCstr6144[i].str, 1024); - - for (i = 0; i < STR_NUM_7168; i++) - LoadString(hinstance, 7168 + i, lpRCstr7168[i].str, 1024); -} - -size_t -mbstoc16s(uint16_t dst[], const char src[], int len) -{ - if (src == NULL) - return 0; - if (len < 0) - return 0; - - size_t ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, dst == NULL ? 0 : len); - - if (!ret) { - return -1; - } - - return ret; -} - -size_t -c16stombs(char dst[], const uint16_t src[], int len) -{ - if (src == NULL) - return 0; - if (len < 0) - return 0; - - size_t ret = WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, dst == NULL ? 0 : len, NULL, NULL); - - if (!ret) { - return -1; - } - - return ret; -} - -int -has_language_changed(uint32_t id) -{ - return (lang_id != id); -} - -/* Set (or re-set) the language for the application. */ -void -set_language(uint32_t id) -{ - if (id == 0xFFFF) { - set_language(lang_sys); - lang_id = id; - return; - } - - if (lang_id != id) { - /* Set our new language ID. */ - lang_id = id; - SetThreadUILanguage(lang_id); - - /* Load the strings table for this ID. */ - LoadCommonStrings(); - - /* Reload main menu */ - menuMain = LoadMenu(hinstance, L"MainMenu"); - if (hwndMain != NULL) - SetMenu(hwndMain, menuMain); - - /* Re-init all the menus */ - ResetAllMenus(); - media_menu_init(); - } -} - -wchar_t * -plat_get_string(int i) -{ - LPTSTR str; - - if ((i >= 2048) && (i <= 3071)) - str = lpRCstr2048[i - 2048].str; - else if ((i >= 4096) && (i <= 4351)) - str = lpRCstr4096[i - 4096].str; - else if ((i >= 4352) && (i <= 4607)) - str = lpRCstr4352[i - 4352].str; - else if ((i >= 4608) && (i <= 5119)) - str = lpRCstr4608[i - 4608].str; - else if ((i >= 5120) && (i <= 5375)) - str = lpRCstr5120[i - 5120].str; - else if ((i >= 5376) && (i <= 5631)) - str = lpRCstr5376[i - 5376].str; - else if ((i >= 5632) && (i <= 5887)) - str = lpRCstr5632[i - 5632].str; - else if ((i >= 5888) && (i <= 6143)) - str = lpRCstr5888[i - 5888].str; - else if ((i >= 6144) && (i <= 7167)) - str = lpRCstr6144[i - 6144].str; - else - str = lpRCstr7168[i - 7168].str; - - return str; -} - -#ifdef MTR_ENABLED -void -init_trace(void) -{ - mtr_init("trace.json"); - mtr_start(); -} - -void -shutdown_trace(void) -{ - mtr_stop(); - mtr_shutdown(); -} -#endif - -/* Create a console if we don't already have one. */ -static void -CreateConsole(int init) -{ - HANDLE h; - FILE *fp; - fpos_t p; - int i; - - if (!init) { - if (force_debug) - FreeConsole(); - return; - } - - /* Are we logging to a file? */ - p = 0; - (void) fgetpos(stdout, &p); - if (p != -1) - return; - - /* Not logging to file, attach to console. */ - if (!AttachConsole(ATTACH_PARENT_PROCESS)) { - /* Parent has no console, create one. */ - if (!AllocConsole()) { - /* Cannot create console, just give up. */ - return; - } - } - fp = NULL; - if ((h = GetStdHandle(STD_OUTPUT_HANDLE)) != NULL) { - /* We got the handle, now open a file descriptor. */ - if ((i = _open_osfhandle((intptr_t) h, _O_TEXT)) != -1) { - /* We got a file descriptor, now allocate a new stream. */ - if ((fp = _fdopen(i, "w")) != NULL) { - /* Got the stream, re-initialize stdout without it. */ - (void) freopen("CONOUT$", "w", stdout); - setvbuf(stdout, NULL, _IONBF, 0); - fflush(stdout); - } - } - } - - if (fp != NULL) { - fclose(fp); - fp = NULL; - } -} - -static void -CloseConsole(void) -{ - CreateConsole(0); -} - -/* Process the commandline, and create standard argc/argv array. */ -static int -ProcessCommandLine(char ***argv) -{ - char **args; - int argc_max; - int i; - int q; - int argc; - - if (acp_utf8) { - i = strlen(GetCommandLineA()) + 1; - argbuf = (char *) malloc(i); - strcpy(argbuf, GetCommandLineA()); - } else { - i = c16stombs(NULL, GetCommandLineW(), 0) + 1; - argbuf = (char *) malloc(i); - c16stombs(argbuf, GetCommandLineW(), i); - } - - argc = 0; - argc_max = 64; - args = (char **) malloc(sizeof(char *) * argc_max); - if (args == NULL) { - free(argbuf); - return 0; - } - - /* parse commandline into argc/argv format */ - i = 0; - while (argbuf[i]) { - while (argbuf[i] == ' ') - i++; - - if (argbuf[i]) { - if ((argbuf[i] == '\'') || (argbuf[i] == '"')) { - q = argbuf[i++]; - if (!argbuf[i]) - break; - } else - q = 0; - - args[argc++] = &argbuf[i]; - - if (argc >= argc_max) { - argc_max += 64; - args = realloc(args, sizeof(char *) * argc_max); - if (args == NULL) { - free(argbuf); - return 0; - } - } - - while ((argbuf[i]) && (q ? (argbuf[i] != q) : (argbuf[i] != ' '))) - i++; - - if (argbuf[i]) { - argbuf[i] = 0; - i++; - } - } - } - - args[argc] = NULL; - *argv = args; - - return argc; -} - -/* For the Windows platform, this is the start of the application. */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) -{ - char **argv = NULL; - int argc; - int i; - - /* Initialize the COM library for the main thread. */ - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - /* Check if Windows supports UTF-8 */ - if (GetACP() == CP_UTF8) - acp_utf8 = 1; - else - acp_utf8 = 0; - - /* Set this to the default value (windowed mode). */ - video_fullscreen = 0; - - /* We need this later. */ - hinstance = hInst; - - /* Set the application version ID string. */ - sprintf(emu_version, "%s v%s", EMU_NAME, EMU_VERSION_FULL); - - /* First, set our (default) language. */ - lang_sys = GetThreadUILanguage(); - set_language(DEFAULT_LANGUAGE); - - /* Process the command line for options. */ - argc = ProcessCommandLine(&argv); - - /* Pre-initialize the system, this loads the config file. */ - if (!pc_init(argc, argv)) { - /* Detach from console. */ - if (force_debug) - CreateConsole(0); - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); - - free(argbuf); - free(argv); - return 1; - } - - extern int gfxcard[2]; - gfxcard[1] = 0; - - /* Create console window. */ - if (force_debug) { - CreateConsole(1); - atexit(CloseConsole); - } - - /* Handle our GUI. */ - i = ui_init(nCmdShow); - - /* Uninitialize COM before exit. */ - CoUninitialize(); - - free(argbuf); - free(argv); - return i; -} - -void -main_thread(void *param) -{ - uint32_t old_time; - uint32_t new_time; - int drawits; - int frames; - - framecountx = 0; - title_update = 1; - old_time = GetTickCount(); - drawits = frames = 0; - while (!is_quit && cpu_thread_run) { - /* See if it is time to run a frame of code. */ - new_time = GetTickCount(); -#ifdef USE_GDBSTUB - if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; - else -#endif - drawits += (new_time - old_time); - old_time = new_time; - if (drawits > 0 && !dopause) { - /* Yes, so do one frame now. */ - drawits -= 10; - if (drawits > 50) - drawits = 0; - - /* Run a block of code. */ - pc_run(); - - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { - nvr_save(); - nvr_dosave = 0; - frames = 0; - } - } else /* Just so we dont overload the host OS. */ - Sleep(1); - - /* If needed, handle a screen resize. */ - if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { - if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); - else - plat_resize(scrnsz_x, scrnsz_y); - atomic_store(&doresize_monitors[0], 0); - } - } - - is_quit = 1; -} - -/* - * We do this here since there is platform-specific stuff - * going on here, and we do it in a function separate from - * main() so we can call it from the UI module as well. - */ -void -do_start(void) -{ - LARGE_INTEGER qpc; - - /* We have not stopped yet. */ - is_quit = 0; - - /* Initialize the high-precision timer. */ - timeBeginPeriod(1); - QueryPerformanceFrequency(&qpc); - timer_freq = qpc.QuadPart; - win_log("Main timer precision: %llu\n", timer_freq); - - /* Start the emulator, really. */ - thMain = thread_create(main_thread, NULL); - SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST); -} - -/* Cleanly stop the emulator. */ -void -do_stop(void) -{ - /* Claim the video blitter. */ - startblit(); - - vid_apis[vid_api].close(); - - pc_close(thMain); - - thMain = NULL; - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); -} - -void -plat_get_exe_name(char *s, int size) -{ - wchar_t *temp; - - if (acp_utf8) - GetModuleFileNameA(hinstance, s, size); - else { - temp = malloc(size * sizeof(wchar_t)); - GetModuleFileNameW(hinstance, temp, size); - c16stombs(s, temp, size); - free(temp); - } -} - -void -plat_tempfile(char *bufp, char *prefix, char *suffix) -{ - SYSTEMTIME SystemTime; - - if (prefix != NULL) - sprintf(bufp, "%s-", prefix); - else - strcpy(bufp, ""); - - GetLocalTime(&SystemTime); - sprintf(&bufp[strlen(bufp)], "%d%02d%02d-%02d%02d%02d-%03d%s", - SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, - SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, - SystemTime.wMilliseconds, - suffix); -} - -int -plat_getcwd(char *bufp, int max) -{ - wchar_t *temp; - - if (acp_utf8) - (void) _getcwd(bufp, max); - else { - temp = malloc(max * sizeof(wchar_t)); - (void) _wgetcwd(temp, max); - c16stombs(bufp, temp, max); - free(temp); - } - - return 0; -} - -int -plat_chdir(char *path) -{ - wchar_t *temp; - int len; - int ret; - - if (acp_utf8) - return (_chdir(path)); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - ret = _wchdir(temp); - - free(temp); - return ret; - } -} - -FILE * -plat_fopen(const char *path, const char *mode) -{ - wchar_t *pathw; - wchar_t *modew; - int len; - FILE *fp; - - if (acp_utf8) - return fopen(path, mode); - else { - len = mbstoc16s(NULL, path, 0) + 1; - pathw = malloc(sizeof(wchar_t) * len); - mbstoc16s(pathw, path, len); - - len = mbstoc16s(NULL, mode, 0) + 1; - modew = malloc(sizeof(wchar_t) * len); - mbstoc16s(modew, mode, len); - - fp = _wfopen(pathw, modew); - - free(pathw); - free(modew); - - return fp; - } -} - -/* Open a file, using Unicode pathname, with 64bit pointers. */ -FILE * -plat_fopen64(const char *path, const char *mode) -{ - return plat_fopen(path, mode); -} - -void -plat_remove(char *path) -{ - wchar_t *temp; - int len; - - if (acp_utf8) - remove(path); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - _wremove(temp); - - free(temp); - } -} - -void -path_normalize(UNUSED(char *path)) -{ - /* No-op */ -} - -/* Make sure a path ends with a trailing (back)slash. */ -void -path_slash(char *path) -{ - if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) - strcat(path, "\\"); -} - -/* Return a trailing (back)slash if necessary. */ -const 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. */ -int -path_abs(char *path) -{ - if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/')) - return 1; - - return 0; -} - -/* Return the last element of a pathname. */ -char * -plat_get_basename(const char *path) -{ - int c = (int) strlen(path); - - while (c > 0) { - if (path[c] == '/' || path[c] == '\\') - return ((char *) &path[c + 1]); - c--; - } - - return ((char *) path); -} - -/* Return the 'directory' element of a pathname. */ -void -path_get_dirname(char *dest, const char *path) -{ - int c = (int) strlen(path); - const char *ptr; - - ptr = (char *) path; - - while (c > 0) { - if (path[c] == '/' || path[c] == '\\') { - ptr = (char *) &path[c]; - break; - } - c--; - } - - /* Copy to destination. */ - while (path < ptr) - *dest++ = *path++; - *dest = '\0'; -} - -char * -path_get_filename(char *s) -{ - int c = strlen(s) - 1; - - while (c > 0) { - if (s[c] == '/' || s[c] == '\\') - return (&s[c + 1]); - c--; - } - - return s; -} - -char * -path_get_extension(char *s) -{ - int c = strlen(s) - 1; - - if (c <= 0) - return s; - - while (c && s[c] != '.') - c--; - - if (!c) - return (&s[strlen(s)]); - - return (&s[c + 1]); -} - -void -path_append_filename(char *dest, const char *s1, const char *s2) -{ - strcpy(dest, s1); - path_slash(dest); - strcat(dest, s2); -} - -void -plat_put_backslash(char *s) -{ - int c = strlen(s) - 1; - - if (s[c] != '/' && s[c] != '\\') - s[c] = '/'; -} - -int -plat_dir_check(char *path) -{ - DWORD dwAttrib; - int len; - wchar_t *temp; - - if (acp_utf8) - dwAttrib = GetFileAttributesA(path); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - dwAttrib = GetFileAttributesW(temp); - - free(temp); - } - - return ((dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) ? 1 : 0); -} - -int -plat_dir_create(char *path) -{ - int ret; - int len; - wchar_t *temp; - - if (acp_utf8) - return SHCreateDirectoryExA(NULL, path, NULL); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - ret = SHCreateDirectoryExW(NULL, temp, NULL); - - free(temp); - - return ret; - } -} - -void * -plat_mmap(size_t size, uint8_t executable) -{ - return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); -} - -void -plat_get_global_config_dir(char *strptr) -{ - wchar_t appdata_dir[1024] = { L'\0' }; - - if (_wgetenv(L"LOCALAPPDATA") && _wgetenv(L"LOCALAPPDATA")[0] != L'\0') { - size_t len = 0; - wcsncpy(appdata_dir, _wgetenv(L"LOCALAPPDATA"), 1024); - len = wcslen(appdata_dir); - if (appdata_dir[len - 1] != L'\\') { - appdata_dir[len] = L'\\'; - appdata_dir[len + 1] = L'\0'; - } - wcscat(appdata_dir, L"86box"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\"); - c16stombs(strptr, appdata_dir, 1024); - } -} - -void -plat_init_rom_paths(void) -{ - wchar_t appdata_dir[1024] = { L'\0' }; - - if (_wgetenv(L"LOCALAPPDATA") && _wgetenv(L"LOCALAPPDATA")[0] != L'\0') { - char appdata_dir_a[1024] = { '\0' }; - size_t len = 0; - wcsncpy(appdata_dir, _wgetenv(L"LOCALAPPDATA"), 1024); - len = wcslen(appdata_dir); - if (appdata_dir[len - 1] != L'\\') { - appdata_dir[len] = L'\\'; - appdata_dir[len + 1] = L'\0'; - } - wcscat(appdata_dir, L"86box"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\roms"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\"); - c16stombs(appdata_dir_a, appdata_dir, 1024); - rom_add_path(appdata_dir_a); - } -} - -void -plat_munmap(void *ptr, UNUSED(size_t size)) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - -uint64_t -plat_timer_read(void) -{ - LARGE_INTEGER li; - - QueryPerformanceCounter(&li); - - return (li.QuadPart); -} - -static LARGE_INTEGER -plat_get_ticks_common(void) -{ - LARGE_INTEGER EndingTime; - LARGE_INTEGER ElapsedMicroseconds; - - if (first_use) { - QueryPerformanceFrequency(&Frequency); - QueryPerformanceCounter(&StartingTime); - first_use = 0; - } - - QueryPerformanceCounter(&EndingTime); - ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; - - /* We now have the elapsed number of ticks, along with the - number of ticks-per-second. We use these values - to convert to the number of elapsed microseconds. - To guard against loss-of-precision, we convert - to microseconds *before* dividing by ticks-per-second. */ - ElapsedMicroseconds.QuadPart *= 1000000; - ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; - - return ElapsedMicroseconds; -} - -uint32_t -plat_get_ticks(void) -{ - return (uint32_t) (plat_get_ticks_common().QuadPart / 1000); -} - -uint32_t -plat_get_micro_ticks(void) -{ - return (uint32_t) plat_get_ticks_common().QuadPart; -} - -void -plat_delay_ms(uint32_t count) -{ - Sleep(count); -} - -/* Return the VIDAPI number for the given name. */ -int -plat_vidapi(char *name) -{ - /* Default/System is SDL Hardware. */ - if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) - return 1; - - /* If DirectDraw or plain SDL was specified, return SDL Software. */ - if (!strcasecmp(name, "ddraw") || !strcasecmp(name, "sdl")) - return 1; - - for (uint8_t i = 0; i < RENDERERS_NUM; i++) { - if (vid_apis[i].name && !strcasecmp(vid_apis[i].name, name)) - return i; - } - - /* Default value. */ - return 1; -} - -/* Return the VIDAPI name for the given number. */ -char * -plat_vidapi_name(int api) -{ - char *name = "default"; - - switch (api) { - case 0: - name = "sdl_software"; - break; - case 1: - break; - case 2: - name = "sdl_opengl"; - break; - case 3: - name = "opengl_core"; - break; -#ifdef USE_VNC - case 4: - name = "vnc"; - break; -#endif - default: - fatal("Unknown renderer: %i\n", api); - break; - } - - return name; -} - -int -plat_setvid(int api) -{ - int i; - - win_log("Initializing VIDAPI: api=%d\n", api); - startblit(); - - /* Close the (old) API. */ - vid_apis[vid_api].close(); - vid_api = api; - - if (vid_apis[vid_api].local) - ShowWindow(hwndRender, SW_SHOW); - else - ShowWindow(hwndRender, SW_HIDE); - - /* Initialize the (new) API. */ - i = vid_apis[vid_api].init((void *) hwndRender); - endblit(); - if (!i) - return 0; - - device_force_redraw(); - - vid_api_inited = 1; - - return 1; -} - -/* Tell the renderers about a new screen resolution. */ -void -plat_vidsize(int x, int y) -{ - if (!vid_api_inited || !vid_apis[vid_api].resize) - return; - - startblit(); - vid_apis[vid_api].resize(x, y); - endblit(); -} - -void -plat_vidapi_enable(int enable) -{ - int i = 1; - - if (!vid_api_inited || !vid_apis[vid_api].enable) - return; - - vid_apis[vid_api].enable(enable != 0); - - if (!i) - return; - - if (enable) - device_force_redraw(); -} - -int -get_vidpause(void) -{ - return (vid_apis[vid_api].pause()); -} - -void -plat_setfullscreen(int on) -{ - RECT rect; - int temp_x; - int temp_y; - int dpi = win_get_dpi(hwndMain); - - /* Are we changing from the same state to the same state? */ - if ((!!(on & 1)) == (!!video_fullscreen)) - return; - - if (on && video_fullscreen_first) { - video_fullscreen |= 2; - if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2135, (wchar_t *) IDS_2052) == 10) { - video_fullscreen_first = 0; - config_save(); - } - video_fullscreen &= 1; - } - - /* OK, claim the video. */ - if (!(on & 2)) - win_mouse_close(); - - /* Close the current mode, and open the new one. */ - video_fullscreen = (on & 1) | 2; - if (vid_apis[vid_api].set_fs) - vid_apis[vid_api].set_fs(on & 1); - if (!(on & 1)) { - plat_resize(scrnsz_x, scrnsz_y); - if (vid_resize) { - /* scale the screen base on DPI */ - if (!(vid_resize & 2) && window_remember) { - MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); - GetClientRect(hwndMain, &rect); - - temp_x = rect.right - rect.left + 1; - temp_y = rect.bottom - rect.top + 1 - (hide_status_bar ? 0 : sbar_height) - (hide_tool_bar ? 0 : tbar_height); - } else { - if (dpi_scale) { - temp_x = MulDiv((vid_resize & 2) ? fixed_size_x : unscaled_size_x, dpi, 96); - temp_y = MulDiv((vid_resize & 2) ? fixed_size_y : unscaled_size_y, dpi, 96); - } else { - temp_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; - temp_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; - } - - /* Main Window. */ - if (vid_resize >= 2) - MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); - - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } - - /* Toolbar. */ - MoveWindow(hwndRebar, 0, 0, temp_x, tbar_height, TRUE); - - /* Render window. */ - MoveWindow(hwndRender, 0, hide_tool_bar ? 0 : tbar_height, temp_x, temp_y, TRUE); - - /* Status bar. */ - GetClientRect(hwndMain, &rect); - MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, temp_x, sbar_height, TRUE); - - if (mouse_capture) - ClipCursor(&rect); - - scrnsz_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; - scrnsz_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; - } - } - video_fullscreen &= 1; - video_force_resize_set(1); - if (!(on & 1)) - atomic_store(&doresize_monitors[0], 1); - - win_mouse_init(); - - if (!(on & 2)) { - /* Release video and make it redraw the screen. */ - device_force_redraw(); - - /* Send a CTRL break code so CTRL does not get stuck. */ - keyboard_input(0, 0x01D); - } - - /* Finally, handle the host's mouse cursor. */ - /* win_log("%s full screen, %s cursor\n", on ? "enter" : "leave", on ? "hide" : "show"); */ - show_cursor(video_fullscreen ? 0 : -1); - - if (!(on & 2)) { - /* This is needed for OpenGL. */ - plat_vidapi_enable(0); - plat_vidapi_enable(1); - } -} - -void -plat_vid_reload_options(void) -{ - if (!vid_api_inited || !vid_apis[vid_api].reload) - return; - - vid_apis[vid_api].reload(); -} - -void -plat_vidapi_reload(void) -{ - vid_apis[vid_api].reload(); -} - -/* Sets up the program language before initialization. */ -uint32_t -plat_language_code(char *langcode) -{ - if (!strcmp(langcode, "system")) - return 0xFFFF; - - int len = mbstoc16s(NULL, langcode, 0) + 1; - wchar_t *temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, langcode, len); - - LCID lcid = LocaleNameToLCID(temp, 0); - - free(temp); - return lcid; -} - -/* Converts back the language code to LCID */ -void -plat_language_code_r(uint32_t lcid, char *outbuf, int len) -{ - if (lcid == 0xFFFF) { - strcpy(outbuf, "system"); - return; - } - - wchar_t buffer[LOCALE_NAME_MAX_LENGTH + 1]; - LCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); - - c16stombs(outbuf, buffer, len); -} - -void -plat_get_cpu_string(char *outbuf, uint8_t len) { - char cpu_string[] = "Unknown"; - strncpy(outbuf, cpu_string, len); -} - -void -plat_set_thread_name(void *thread, const char *name) -{ - /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ - static void *kernel32_handle = NULL; - static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; - static dllimp_t kernel32_imports[] = { - // clang-format off - { "SetThreadDescription", &pSetThreadDescription }, - { NULL, NULL } - // clang-format on - }; - - if (!kernel32_handle) { - kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); - if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ - pSetThreadDescription = NULL; - } - } - - if (pSetThreadDescription) { - size_t len = strlen(name) + 1; - wchar_t wname[len + 1]; - mbstowcs(wname, name, len); - pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); - } -} - -void -take_screenshot(void) -{ - startblit(); - monitors[0].mon_screenshots++; - endblit(); - device_force_redraw(); -} - -/* LPARAM interface to plat_get_string(). */ -LPARAM -win_get_string(int id) -{ - wchar_t *ret; - - ret = plat_get_string(id); - return ((LPARAM) ret); -} - -void /* plat_ */ -startblit(void) -{ - WaitForSingleObject(ghMutex, INFINITE); -} - -void /* plat_ */ -endblit(void) -{ - ReleaseMutex(ghMutex); -} - -double -plat_get_dpi(void) -{ - UINT dpi = win_get_dpi(hwndRender); - - return ((double) dpi) / 96.0; -} diff --git a/src/win/win_about.c b/src/win/win_about.c deleted file mode 100644 index 7ba55f73e..000000000 --- a/src/win/win_about.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * - * Handle the About dialog. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/win.h> -#include <86box/version.h> - -void -AboutDialogCreate(HWND hwnd) -{ - int i; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[] = { - {IDOK, EMU_SITE_W }, - { IDCANCEL, MAKEINTRESOURCE(IDS_2128)} - }; - - wchar_t emu_version[256]; - i = swprintf(emu_version, sizeof_w(emu_version), L"%ls v%ls", EMU_NAME_W, EMU_VERSION_FULL_W); -#ifdef EMU_GIT_HASH - i += swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls]", EMU_GIT_HASH_W); -#endif - -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) -# define ARCH_STR L"arm" -#elif defined(__aarch64__) || defined(_M_ARM64) -# define ARCH_STR L"arm64" -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define ARCH_STR L"i386" -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) -# define ARCH_STR L"x86_64" -#else -# define ARCH_STR L"unknown" -#endif - swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls, %ls]", ARCH_STR, plat_get_string(IDS_DYNAREC)); - - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.hwndParent = hwnd; - tdconfig.hInstance = hinstance; - tdconfig.dwCommonButtons = 0; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2125); - tdconfig.pszMainIcon = (PCWSTR) 10; - tdconfig.pszMainInstruction = emu_version; - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2127); - tdconfig.cButtons = ARRAYSIZE(tdbuttons); - tdconfig.pButtons = tdbuttons; - tdconfig.nDefaultButton = IDCANCEL; - TaskDialogIndirect(&tdconfig, &i, NULL, NULL); - - if (i == IDOK) - ShellExecute(hwnd, L"open", L"https://" EMU_SITE_W, NULL, NULL, SW_SHOW); -} diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c deleted file mode 100644 index 58bd85c65..000000000 --- a/src/win/win_cdrom.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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. - * - * Handle the platform-side of CDROM/ZIP/MO drives. - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/hdd.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/scsi_disk.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -void -cassette_mount(char *fn, uint8_t wp) -{ - pc_cas_set_fname(cassette, NULL); - memset(cassette_fname, 0, sizeof(cassette_fname)); - cassette_ui_writeprot = wp; - pc_cas_set_fname(cassette, fn); - if (fn != NULL) - memcpy(cassette_fname, fn, MIN(511, strlen(fn))); - ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0); - media_menu_update_cassette(); - ui_sb_update_tip(SB_CASSETTE); - config_save(); -} - -void -cassette_eject(void) -{ - pc_cas_set_fname(cassette, NULL); - memset(cassette_fname, 0x00, sizeof(cassette_fname)); - ui_sb_update_icon_state(SB_CASSETTE, 1); - media_menu_update_cassette(); - ui_sb_update_tip(SB_CASSETTE); - config_save(); -} - -void -cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) -{ - cart_close(id); - cart_load(id, fn); - ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1); - media_menu_update_cartridge(id); - ui_sb_update_tip(SB_CARTRIDGE | id); - config_save(); -} - -void -cartridge_eject(uint8_t id) -{ - cart_close(id); - ui_sb_update_icon_state(SB_CARTRIDGE | id, 1); - media_menu_update_cartridge(id); - ui_sb_update_tip(SB_CARTRIDGE | id); - config_save(); -} - -void -floppy_mount(uint8_t id, char *fn, uint8_t wp) -{ - fdd_close(id); - ui_writeprot[id] = wp; - fdd_load(id, fn); - ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1); - media_menu_update_floppy(id); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); -} - -void -floppy_eject(uint8_t id) -{ - fdd_close(id); - ui_sb_update_icon_state(SB_FLOPPY | id, 1); - media_menu_update_floppy(id); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); -} - -void -plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) -{ - const cdrom_t *drv = &cdrom[id]; - - if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } - - media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); -} - -void -cdrom_mount(uint8_t id, char *fn) -{ - cdrom[id].prev_host_drive = cdrom[id].host_drive; - strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); - if (cdrom[id].ops && cdrom[id].ops->exit) - cdrom[id].ops->exit(&(cdrom[id])); - cdrom[id].ops = NULL; - memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '/')) - fn[strlen(fn) - 1] = '\\'; - cdrom_image_open(&(cdrom[id]), fn); - /* Signal media change to the emulated machine. */ - if (cdrom[id].insert) - cdrom[id].insert(cdrom[id].priv); - cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200; - if (cdrom[id].host_drive == 200) { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } - media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); - config_save(); -} - -void -mo_eject(uint8_t id) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_close(dev); - if (mo_drives[id].bus_type) { - /* Signal disk change to the emulated machine. */ - mo_insert(dev); - } - - ui_sb_update_icon_state(SB_MO | id, 1); - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - config_save(); -} - -void -mo_mount(uint8_t id, char *fn, uint8_t wp) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_close(dev); - mo_drives[id].read_only = wp; - mo_load(dev, fn); - mo_insert(dev); - - ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1); - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - - config_save(); -} - -void -mo_reload(uint8_t id) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_reload(dev); - if (strlen(mo_drives[id].image_path) == 0) { - ui_sb_update_icon_state(SB_MO | id, 1); - } else { - ui_sb_update_icon_state(SB_MO | id, 0); - } - - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - - config_save(); -} - -void -zip_eject(uint8_t id) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_close(dev); - if (zip_drives[id].bus_type) { - /* Signal disk change to the emulated machine. */ - zip_insert(dev); - } - - ui_sb_update_icon_state(SB_ZIP | id, 1); - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - config_save(); -} - -void -zip_mount(uint8_t id, char *fn, uint8_t wp) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_close(dev); - zip_drives[id].read_only = wp; - zip_load(dev, fn); - zip_insert(dev); - - ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1); - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - - config_save(); -} - -void -zip_reload(uint8_t id) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_reload(dev); - if (strlen(zip_drives[id].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP | id, 1); - } else { - ui_sb_update_icon_state(SB_ZIP | id, 0); - } - - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - - config_save(); -} diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c deleted file mode 100644 index 92ab6b614..000000000 --- a/src/win/win_devconf.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows device configuration dialog implementation. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/ini.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/midi_rtmidi.h> -#include <86box/ui.h> -#include <86box/win.h> -#include - -static device_context_t config_device; - -static uint8_t deviceconfig_changed = 0; -static int combo_to_struct[256]; - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - - int val_int; - int id; - int c; - int d; - int p; - int q; -#ifdef USE_RTMIDI - int num; -#endif - int changed; - int cid; - const device_config_t *config; - const device_config_selection_t *selection; - const device_config_bios_t *bios; - char s[512]; - char file_filter[512]; - const char *str; - const char *val_str; - wchar_t ws[512]; - wchar_t *wstr; - LPTSTR lptsTemp; - - config = config_device.dev->config; - - switch (message) { - case WM_INITDIALOG: - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - - lptsTemp = (LPTSTR) malloc(512); - memset(combo_to_struct, 0, 256 * sizeof(int)); - - while (config->type != -1) { - selection = config->selection; - bios = config->bios; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - SendMessage(h, BM_SETCHECK, val_int, 0); - - id++; - break; - case CONFIG_SELECTION: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - case CONFIG_BIOS: - val_str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) config->default_string); - - c = 0; - q = 0; - while (bios && (bios->files_no > 0)) { - mbstowcs(lptsTemp, bios->name, strlen(bios->name) + 1); - p = 0; - for (d = 0; d < bios->files_no; d++) - p += !!rom_present(bios->files[d]); - if (p == bios->files_no) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (!strcmp(val_str, bios->internal_name)) - SendMessage(h, CB_SETCURSEL, c, 0); - combo_to_struct[c] = q; - c++; - } - q++; - bios++; - } - - id += 2; - break; -#ifdef USE_RTMIDI - case CONFIG_MIDI_OUT: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - num = rtmidi_out_get_num_devs(); - for (c = 0; c < num; c++) { - rtmidi_out_get_dev_name(c, s); - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == c) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - id += 2; - break; - case CONFIG_MIDI_IN: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - num = rtmidi_in_get_num_devs(); - for (c = 0; c < num; c++) { - rtmidi_in_get_dev_name(c, s); - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == c) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - id += 2; - break; -#endif - case CONFIG_SPINNER: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - _swprintf(ws, L"%i", val_int); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) ws); - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - wstr = config_get_wstring((char *) config_device.name, - (char *) config->name, 0); - if (wstr) - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wstr); - id += 3; - break; - case CONFIG_HEX16: - val_int = config_get_hex16((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - case CONFIG_HEX20: - val_int = config_get_hex20((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - } - config++; - } - free(lptsTemp); - return TRUE; - case WM_COMMAND: - cid = LOWORD(wParam); - if (cid == IDOK) { - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - changed = 0; - char s[512]; - - while (config->type != -1) { - const device_config_selection_t *selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) - changed = 1; - - id++; - break; - case CONFIG_SELECTION: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - case CONFIG_BIOS: - bios = config->bios; - - val_str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) config->default_string); - - c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - for (; c > 0; c--) - bios++; - - if (strcmp(val_str, bios->internal_name)) - changed = 1; - - id += 2; - break; - case CONFIG_MIDI_OUT: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_MIDI_IN: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) ""); - SendMessage(h, WM_GETTEXT, 511, (LPARAM) s); - if (strcmp(str, s)) - changed = 1; - - id += 3; - break; - case CONFIG_SPINNER: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - if (val_int > config->spinner.max) - val_int = config->spinner.max; - else if (val_int < config->spinner.min) - val_int = config->spinner.min; - - SendMessage(h, WM_GETTEXT, 79, (LPARAM) ws); - wcstombs(s, ws, 512); - sscanf(s, "%i", &c); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_HEX16: - val_int = config_get_hex16((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - case CONFIG_HEX20: - val_int = config_get_hex20((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - } - config++; - } - - if (!changed) { - deviceconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } - - deviceconfig_changed = 1; - - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - - while (config->type != -1) { - selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - config_set_int((char *) config_device.name, - (char *) config->name, SendMessage(h, BM_GETCHECK, 0, 0)); - - id++; - break; - case CONFIG_SELECTION: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_int((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - case CONFIG_BIOS: - bios = config->bios; - c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; - for (; c > 0; c--) - bios++; - config_set_string((char *) config_device.name, (char *) config->name, (char *) bios->internal_name); - - id += 2; - break; - case CONFIG_MIDI_OUT: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_MIDI_IN: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - SendMessage(h, WM_GETTEXT, 511, (LPARAM) ws); - config_set_wstring((char *) config_device.name, (char *) config->name, ws); - - id += 3; - break; - case CONFIG_SPINNER: - SendMessage(h, WM_GETTEXT, 79, (LPARAM) ws); - wcstombs(s, ws, 512); - sscanf(s, "%i", &c); - if (c > config->spinner.max) - c = config->spinner.max; - else if (c < config->spinner.min) - c = config->spinner.min; - - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_HEX16: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_hex16((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - case CONFIG_HEX20: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_hex20((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - } - config++; - } - - EndDialog(hdlg, 0); - return TRUE; - } else if (cid == IDCANCEL) { - deviceconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } else { - id = IDC_CONFIG_BASE; - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY: - id++; - break; - case CONFIG_SELECTION: - case CONFIG_HEX16: - case CONFIG_HEX20: - case CONFIG_BIOS: - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_SPINNER: - case CONFIG_STRING: - id += 2; - break; - case CONFIG_FNAME: - if (cid == id + 1) { - s[0] = 0; - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 511, (LPARAM) s); - file_filter[0] = 0; - - strcat(file_filter, config->file_filter); - strcat(file_filter, "|All files (*.*)|*.*|"); - mbstowcs(ws, file_filter, strlen(file_filter) + 1); - d = strlen(file_filter); - - /* replace | with \0 */ - for (c = 0; c < d; ++c) { - if (ws[c] == L'|') - ws[c] = 0; - } - - if (!file_dlg(hdlg, ws, s, NULL, 0)) - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - } - break; - } - config++; - } - } - break; - } - return FALSE; -} - -uint8_t -deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst) -{ - const device_config_t *config = device->config; - uint16_t *data_block; - uint16_t *data; - DLGTEMPLATE *dlg; - DLGITEMTEMPLATE *item; - - data_block = malloc(16384); - dlg = (DLGTEMPLATE *) data_block; - int y = 10; - int id = IDC_CONFIG_BASE; - - deviceconfig_changed = 0; - - memset(data_block, 0, 16384); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *) (dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - - data += wsprintf(data, plat_get_string(IDS_2142), device->name) + 1; - - *data++ = 9; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 120); - - if (((uintptr_t) data) & 2) - data++; - - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY: - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 100; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - y += 20; - break; - - case CONFIG_SELECTION: - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_HEX16: - case CONFIG_HEX20: - case CONFIG_BIOS: - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_SPINNER: - /*Spinner*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /* TODO: add up down class */ - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_STRING: - /*Editable Text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_READONLY; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_FNAME: - /*File*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 100; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_READONLY; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /* Button */ - item = (DLGITEMTEMPLATE *) data; - item->x = 175; - item->y = y; - item->id = id++; - - item->cx = 35; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Browse", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - } - - if (((uintptr_t) data) & 2) - data++; - - config++; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *) data; - item->x = 100; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - item = (DLGITEMTEMPLATE *) data; - item->x = 160; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 25; - - device_set_context(&config_device, device, inst); - - DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc); - - free(data_block); - - return deviceconfig_changed; -} - -uint8_t -deviceconfig_open(HWND hwnd, const device_t *device) -{ - return deviceconfig_inst_open(hwnd, device, 0); -} diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c deleted file mode 100644 index 15b00bf3f..000000000 --- a/src/win/win_dialog.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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. - * - * Several dialogs for the application. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -#define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t) s) < ((uintptr_t) 65636)) ? (MAKEINTRESOURCE((uintptr_t) s)) : (s))) - -WCHAR wopenfilestring[512]; -char openfilestring[512]; -uint8_t filterindex = 0; - -int -ui_msgbox(int flags, void *message) -{ - return ui_msgbox_ex(flags, NULL, message, NULL, NULL, NULL); -} - -int -ui_msgbox_header(int flags, void *header, void *message) -{ - return ui_msgbox_ex(flags, header, message, NULL, NULL, NULL); -} - -int -ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - WCHAR temp[512]; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[3]; - TASKDIALOG_BUTTON tdb_yes = { IDYES, STRING_OR_RESOURCE(btn1) }; - TASKDIALOG_BUTTON tdb_no = { IDNO, STRING_OR_RESOURCE(btn2) }; - TASKDIALOG_BUTTON tdb_cancel = { IDCANCEL, STRING_OR_RESOURCE(btn3) }; - TASKDIALOG_BUTTON tdb_exit = { IDCLOSE, MAKEINTRESOURCE(IDS_2120) }; - int ret = 0; - int checked = 0; - - /* Configure the default OK button. */ - tdconfig.cButtons = 0; - if (btn1) - tdbuttons[tdconfig.cButtons++] = tdb_yes; - else - tdconfig.dwCommonButtons = TDCBF_OK_BUTTON; - - /* Configure the message type. */ - switch (flags & 0x1f) { - case MBX_INFO: /* just an informational message */ - tdconfig.pszMainIcon = TD_INFORMATION_ICON; - break; - - case MBX_ERROR: /* error message */ - if (flags & MBX_FATAL) { - tdconfig.pszMainIcon = TD_ERROR_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */ - - /* replace default "OK" button with "Exit" button */ - if (btn1) - tdconfig.cButtons = 0; - else - tdconfig.dwCommonButtons = 0; - tdbuttons[tdconfig.cButtons++] = tdb_exit; - } else { - tdconfig.pszMainIcon = TD_WARNING_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */ - } - break; - - case MBX_QUESTION: /* question */ - case MBX_QUESTION_YN: - case MBX_QUESTION_OK: - if (!btn1) /* replace default "OK" button with "Yes" button */ - tdconfig.dwCommonButtons = (flags & MBX_QUESTION_OK) ? TDCBF_OK_BUTTON : TDCBF_YES_BUTTON; - - if (btn2) /* "No" button */ - tdbuttons[tdconfig.cButtons++] = tdb_no; - else - tdconfig.dwCommonButtons |= (flags & MBX_QUESTION_OK) ? TDCBF_CANCEL_BUTTON : TDCBF_NO_BUTTON; - - if (flags & MBX_QUESTION) { - if (btn3) /* "Cancel" button */ - tdbuttons[tdconfig.cButtons++] = tdb_cancel; - else - tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON; - } - - if (flags & MBX_WARNING) - tdconfig.pszMainIcon = TD_WARNING_ICON; - break; - } - - /* If the message is an ANSI string, convert it. */ - tdconfig.pszContent = (WCHAR *) STRING_OR_RESOURCE(message); - if (flags & MBX_ANSI) { - mbstoc16s(temp, (char *) message, strlen((char *) message) + 1); - tdconfig.pszContent = temp; - } - - /* Configure the rest of the TaskDialog. */ - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.hwndParent = hwndMain; - if (flags & MBX_LINKS) - tdconfig.dwFlags = TDF_USE_COMMAND_LINKS; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); - if (header) - tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header); - tdconfig.pButtons = tdbuttons; - if (flags & MBX_DONTASK) - tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2136); - - /* Run the TaskDialog. */ - TaskDialogIndirect(&tdconfig, &ret, NULL, &checked); - - /* Convert return values to generic ones. */ - if (ret == IDNO) - ret = 1; - else if (ret == IDCANCEL) - ret = -1; - else - ret = 0; - - /* 10 is added to the return value if "don't show again" is checked. */ - if (checked) - ret += 10; - - return ret; -} - -int -file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save) -{ - OPENFILENAME ofn; - BOOL r; -#if 0 - DWORD err; -#endif - int old_dopause; - - /* Initialize OPENFILENAME */ - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFile = wopenfilestring; - - /* - * Set lpstrFile[0] to '\0' so that GetOpenFileName does - * not use the contents of szFile to initialize itself. - */ - memset(ofn.lpstrFile, 0x00, 512 * sizeof(WCHAR)); - if (fn) - memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); - ofn.nMaxFile = sizeof_w(wopenfilestring); - ofn.lpstrFilter = f; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST; - if (!save) - ofn.Flags |= OFN_FILEMUSTEXIST; - if (title) - ofn.lpstrTitle = title; - - /* Display the Open dialog box. */ - old_dopause = dopause; - plat_pause(1); - if (save) - r = GetSaveFileName(&ofn); - else - r = GetOpenFileName(&ofn); - plat_pause(old_dopause); - - plat_chdir(usr_path); - - if (r) { - c16stombs(openfilestring, wopenfilestring, sizeof(openfilestring)); - filterindex = ofn.nFilterIndex; - - return 0; - } - - return 1; -} - -int -file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save) -{ - WCHAR ufn[512]; - WCHAR title_buf[512]; - - if (fn) - mbstoc16s(ufn, fn, strlen(fn) + 1); - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - - return (file_dlg_w(hwnd, f, fn ? ufn : NULL, title ? title_buf : NULL, save)); -} - -int -file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save) -{ - WCHAR uf[512]; - WCHAR ufn[512]; - WCHAR title_buf[512]; - - mbstoc16s(uf, f, strlen(f) + 1); - mbstoc16s(ufn, fn, strlen(fn) + 1); - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - - return (file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save)); -} - -int -file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, char *title, int save) -{ - WCHAR title_buf[512]; - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - return (file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save)); -} - -int -file_dlg_st(HWND hwnd, int id, char *fn, char *title, int save) -{ - return (file_dlg(hwnd, plat_get_string(id), fn, title, save)); -} diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c deleted file mode 100644 index 24690f2ba..000000000 --- a/src/win/win_dynld.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - * - * Try to load a support DLL. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/plat_dynld.h> - -#ifdef ENABLE_DYNLD_LOG -int dynld_do_log = ENABLE_DYNLD_LOG; - -static void -dynld_log(const char *fmt, ...) -{ - va_list ap; - - if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define dynld_log(fmt, ...) -#endif - -void * -dynld_module(const char *name, dllimp_t *table) -{ - HMODULE h; - void *func; - - /* See if we can load the desired module. */ - if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return (NULL); - } - - /* Now load the desired function pointers. */ - for (dllimp_t *imp = table; imp->name != NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return (NULL); - } - - /* To overcome typing issues.. */ - *(char **) imp->func = (char *) func; - } - - /* All good. */ - dynld_log("loaded %s\n", name); - return ((void *) h); -} - -void -dynld_close(void *handle) -{ - if (handle != NULL) - FreeLibrary((HMODULE) handle); -} diff --git a/src/win/win_icon.c b/src/win/win_icon.c deleted file mode 100644 index f3426b8b5..000000000 --- a/src/win/win_icon.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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. - * - * Implement the application's icon changing system. - * - * - * - * Authors: Laci bá' - * - * Copyright 2021 Laci bá'. - * Copyright 2021-2023 Jasmine Iwanek. - */ - -#include -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/path.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -HICON hIcon[256]; /* icon data loaded from resources */ -char icon_set[256] = ""; /* name of the iconset to be used */ - -void -win_clear_icon_set(void) -{ - for (uint16_t i = 0; i < 256; i++) - if (hIcon[i] != 0) { - DestroyIcon(hIcon[i]); - hIcon[i] = 0; - } -} - -void -win_system_icon_set(void) -{ - int x = win_get_system_metrics(SM_CXSMICON, dpi); - int y = win_get_system_metrics(SM_CYSMICON, dpi); - - for (uint16_t i = 0; i < 256; i++) - hIcon[i] = LoadImage(hinstance, MAKEINTRESOURCE(i), IMAGE_ICON, x, y, LR_DEFAULTCOLOR); -} - -typedef struct -{ - int id; - char *filename; -} _ICON_DATA; - -const _ICON_DATA icon_files[] = { - {16, "floppy_525.ico" }, - { 17, "floppy_525_active.ico" }, - { 24, "floppy_35.ico" }, - { 25, "floppy_35_active.ico" }, - { 32, "cdrom.ico" }, - { 33, "cdrom_active.ico" }, - { 48, "zip.ico" }, - { 49, "zip_active.ico" }, - { 56, "mo.ico" }, - { 57, "mo_active.ico" }, - { 64, "cassette.ico" }, - { 65, "cassette_active.ico" }, - { 80, "hard_disk.ico" }, - { 81, "hard_disk_active.ico" }, - { 96, "network.ico" }, - { 97, "network_active.ico" }, - { 104, "cartridge.ico" }, - { 144, "floppy_525_empty.ico" }, - { 145, "floppy_525_empty_active.ico"}, - { 152, "floppy_35_empty.ico" }, - { 153, "floppy_35_empty_active.ico" }, - { 160, "cdrom_empty.ico" }, - { 161, "cdrom_empty_active.ico" }, - { 176, "zip_empty.ico" }, - { 177, "zip_empty_active.ico" }, - { 184, "mo_empty.ico" }, - { 185, "mo_empty_active.ico" }, - { 192, "cassette_empty.ico" }, - { 193, "cassette_empty_active.ico" }, - { 200, "run.ico" }, - { 201, "pause.ico" }, - { 202, "send_cad.ico" }, - { 203, "send_cae.ico" }, - { 204, "hard_reset.ico" }, - { 205, "acpi_shutdown.ico" }, - { 206, "settings.ico" }, - { 232, "cartridge_empty.ico" }, - { 240, "machine.ico" }, - { 241, "display.ico" }, - { 242, "input_devices.ico" }, - { 243, "sound.ico" }, - { 244, "ports.ico" }, - { 245, "other_peripherals.ico" }, - { 246, "floppy_and_cdrom_drives.ico"}, - { 247, "other_removable_devices.ico"}, - { 248, "floppy_disabled.ico" }, - { 249, "cdrom_disabled.ico" }, - { 250, "zip_disabled.ico" }, - { 251, "mo_disabled.ico" }, - { 252, "storage_controllers.ico" } -}; - -void -win_get_icons_path(char *path_root) -{ - char roms_root[1024] = { 0 }; - if (rom_path[0]) - strcpy(roms_root, rom_path); - else - path_append_filename(roms_root, exe_path, "roms"); - - path_append_filename(path_root, roms_root, "icons"); - path_slash(path_root); -} - -void -win_load_icon_set(void) -{ - win_clear_icon_set(); - win_system_icon_set(); - - if (strlen(icon_set) == 0) { - ToolBarLoadIcons(); - return; - } - - char path_root[2048] = { 0 }; - char temp[2048] = { 0 }; - wchar_t wtemp[2048] = { 0 }; - - win_get_icons_path(path_root); - strcat(path_root, icon_set); - path_slash(path_root); - - int count = sizeof(icon_files) / sizeof(_ICON_DATA); - int x = win_get_system_metrics(SM_CXSMICON, dpi); - int y = win_get_system_metrics(SM_CYSMICON, dpi); - for (int i = 0; i < count; i++) { - path_append_filename(temp, path_root, icon_files[i].filename); - mbstoc16s(wtemp, temp, strlen(temp) + 1); - - HICON ictemp; - ictemp = LoadImageW(NULL, (LPWSTR) wtemp, IMAGE_ICON, x, y, LR_LOADFROMFILE | LR_DEFAULTCOLOR); - if (ictemp) { - if (hIcon[icon_files[i].id]) - DestroyIcon(hIcon[icon_files[i].id]); - hIcon[icon_files[i].id] = ictemp; - } - } - - uint32_t curr_lang = lang_id; - lang_id = 0; - set_language(curr_lang); - - ToolBarLoadIcons(); -} diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp deleted file mode 100644 index 9b264a700..000000000 --- a/src/win/win_joystick.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Joystick interface to host device. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define DIRECTINPUT_VERSION 0x0800 -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -#define DIDEVTYPE_JOYSTICK 4 - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; -int has_slider = 0; - -static LPDIRECTINPUT8 lpdi; -static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL }; -static GUID joystick_guids[MAX_JOYSTICKS]; - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -static BOOL CALLBACK -joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, UNUSED(LPVOID data)) -{ - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - joystick_log("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName); - - joystick_guids[joysticks_present++] = lpddi->guidInstance; - - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; -} - -BOOL CALLBACK -DIEnumDeviceObjectsCallback( - LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - plat_joystick_t *state = (plat_joystick_t *) pvRef; - - if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis) { - if (state->nr_axes < MAX_JOY_AXES) { - memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); - if (lpddoi->guidType == GUID_XAxis) - state->axis[state->nr_axes].id = 0; - else if (lpddoi->guidType == GUID_YAxis) - state->axis[state->nr_axes].id = 1; - else if (lpddoi->guidType == GUID_ZAxis) - state->axis[state->nr_axes].id = 2; - else if (lpddoi->guidType == GUID_RxAxis) - state->axis[state->nr_axes].id = 3; - else if (lpddoi->guidType == GUID_RyAxis) - state->axis[state->nr_axes].id = 4; - else if (lpddoi->guidType == GUID_RzAxis) - state->axis[state->nr_axes].id = 5; - else if (lpddoi->guidType == GUID_Slider) { - state->axis[state->nr_axes].id = 6 + has_slider; - has_slider++; - } - state->nr_axes++; - } - } else if (lpddoi->guidType == GUID_Button) { - if (state->nr_buttons < MAX_JOY_BUTTONS) { - memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_buttons++; - } - } else if (lpddoi->guidType == GUID_POV) { - if (state->nr_povs < MAX_JOY_POVS) { - memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_povs++; - } - } - - return DIENUM_CONTINUE; -} - -void -joystick_init() -{ - int c; - - atexit(joystick_close); - - joysticks_present = 0; - - if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) - fatal("joystick_init : DirectInputCreate failed\n"); - - if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY))) - fatal("joystick_init : EnumDevices failed\n"); - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - for (c = 0; c < joysticks_present; c++) { - LPDIRECTINPUTDEVICE8 lpdi_joystick_temp = NULL; - DIPROPRANGE joy_axis_range; - DIDEVICEINSTANCE device_instance; - DIDEVCAPS devcaps; - - if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) - fatal("joystick_init : CreateDevice failed\n"); - if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice8, (void **) &lpdi_joystick[c]))) - fatal("joystick_init : CreateDevice failed\n"); - lpdi_joystick_temp->Release(); - - memset(&device_instance, 0, sizeof(device_instance)); - device_instance.dwSize = sizeof(device_instance); - if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance))) - fatal("joystick_init : GetDeviceInfo failed\n"); - joystick_log("Joystick %i :\n", c); - joystick_log(" tszInstanceName = %s\n", device_instance.tszInstanceName); - joystick_log(" tszProductName = %s\n", device_instance.tszProductName); - memcpy(plat_joystick_state[c].name, device_instance.tszInstanceName, strlen(device_instance.tszInstanceName) + 1); - - memset(&devcaps, 0, sizeof(devcaps)); - devcaps.dwSize = sizeof(devcaps); - if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps))) - fatal("joystick_init : GetCapabilities failed\n"); - joystick_log(" Axes = %i\n", devcaps.dwAxes); - joystick_log(" Buttons = %i\n", devcaps.dwButtons); - joystick_log(" POVs = %i\n", devcaps.dwPOVs); - - has_slider = 0; - lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); - - if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - fatal("joystick_init : SetCooperativeLevel failed\n"); - if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick))) - fatal("joystick_init : SetDataFormat failed\n"); - - joy_axis_range.lMin = -32768; - joy_axis_range.lMax = 32767; - joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); - joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); - joy_axis_range.diph.dwHow = DIPH_BYOFFSET; - joy_axis_range.diph.dwObj = DIJOFS_X; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Y; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Z; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RX; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RY; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RZ; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_SLIDER(0); - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_SLIDER(1); - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - - if (FAILED(lpdi_joystick[c]->Acquire())) - fatal("joystick_init : Acquire failed\n"); - } -} - -void -joystick_close() -{ - if (lpdi_joystick[1]) { - lpdi_joystick[1]->Release(); - lpdi_joystick[1] = NULL; - } - if (lpdi_joystick[0]) { - lpdi_joystick[0]->Release(); - lpdi_joystick[0] = NULL; - } -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int c; - int d; - - if (!joystick_type) - return; - - for (c = 0; c < joysticks_present; c++) { - DIJOYSTATE joystate; - int b; - - if (FAILED(lpdi_joystick[c]->Poll())) { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - } - if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID) &joystate))) { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID) &joystate); - } - - plat_joystick_state[c].a[0] = joystate.lX; - plat_joystick_state[c].a[1] = joystate.lY; - plat_joystick_state[c].a[2] = joystate.lZ; - plat_joystick_state[c].a[3] = joystate.lRx; - plat_joystick_state[c].a[4] = joystate.lRy; - plat_joystick_state[c].a[5] = joystate.lRz; - plat_joystick_state[c].a[6] = joystate.rglSlider[0]; - plat_joystick_state[c].a[7] = joystate.rglSlider[1]; - - for (b = 0; b < MAX_JOY_BUTTONS; b++) - plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - - for (b = 0; b < MAX_JOY_POVS; b++) - plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; - // joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); - } - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} - -void -win_joystick_handle(UNUSED(PRAWINPUT raw)) -{ - // Nothing to be done here, atleast currently -} diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c deleted file mode 100644 index bb05c3f5c..000000000 --- a/src/win/win_joystick_rawinput.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * 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. - * - * RawInput joystick interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2020 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ -#ifndef HID_USAGE_SIMULATION_AILERON -# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) -#endif -#ifndef HID_USAGE_SIMULATION_ELEVATOR -# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) -#endif -#ifndef HID_USAGE_SIMULATION_ACCELLERATOR -# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) -#endif -#ifndef HID_USAGE_SIMULATION_BRAKE -# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) -#endif -#ifndef HID_USAGE_SIMULATION_CLUTCH -# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) -#endif -#ifndef HID_USAGE_SIMULATION_SHIFTER -# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) -#endif -#ifndef HID_USAGE_SIMULATION_STEERING -# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) -#endif - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -typedef struct { - HANDLE hdevice; - PHIDP_PREPARSED_DATA data; - - USAGE usage_button[256]; - - struct raw_axis_t { - USAGE usage; - USHORT link; - USHORT bitsize; - LONG max; - LONG min; - } axis[MAX_JOY_AXES]; - - struct raw_pov_t { - USAGE usage; - USHORT link; - LONG max; - LONG min; - } pov[MAX_JOY_POVS]; -} raw_joystick_t; - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; - -raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; - -/* We only use the first 32 buttons reported, from Usage ID 1-128 */ -void -joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) -{ - if (joy->nr_buttons >= MAX_JOY_BUTTONS) - return; - if (usage < 1 || usage > 128) - return; - - rawjoy->usage_button[usage] = joy->nr_buttons; - sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); - joy->nr_buttons++; -} - -void -joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) -{ - if (joy->nr_axes >= MAX_JOY_AXES) - return; - - switch (prop->Range.UsageMin) { - case HID_USAGE_GENERIC_X: - sprintf(joy->axis[joy->nr_axes].name, "X"); - break; - case HID_USAGE_GENERIC_Y: - sprintf(joy->axis[joy->nr_axes].name, "Y"); - break; - case HID_USAGE_GENERIC_Z: - sprintf(joy->axis[joy->nr_axes].name, "Z"); - break; - case HID_USAGE_GENERIC_RX: - sprintf(joy->axis[joy->nr_axes].name, "RX"); - break; - case HID_USAGE_GENERIC_RY: - sprintf(joy->axis[joy->nr_axes].name, "RY"); - break; - case HID_USAGE_GENERIC_RZ: - sprintf(joy->axis[joy->nr_axes].name, "RZ"); - break; - case HID_USAGE_GENERIC_SLIDER: - sprintf(joy->axis[joy->nr_axes].name, "Slider"); - break; - case HID_USAGE_GENERIC_DIAL: - sprintf(joy->axis[joy->nr_axes].name, "Dial"); - break; - case HID_USAGE_GENERIC_WHEEL: - sprintf(joy->axis[joy->nr_axes].name, "Wheel"); - break; - case HID_USAGE_SIMULATION_AILERON: - sprintf(joy->axis[joy->nr_axes].name, "Aileron"); - break; - case HID_USAGE_SIMULATION_ELEVATOR: - sprintf(joy->axis[joy->nr_axes].name, "Elevator"); - break; - case HID_USAGE_SIMULATION_RUDDER: - sprintf(joy->axis[joy->nr_axes].name, "Rudder"); - break; - case HID_USAGE_SIMULATION_THROTTLE: - sprintf(joy->axis[joy->nr_axes].name, "Throttle"); - break; - case HID_USAGE_SIMULATION_ACCELLERATOR: - sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); - break; - case HID_USAGE_SIMULATION_BRAKE: - sprintf(joy->axis[joy->nr_axes].name, "Brake"); - break; - case HID_USAGE_SIMULATION_CLUTCH: - sprintf(joy->axis[joy->nr_axes].name, "Clutch"); - break; - case HID_USAGE_SIMULATION_SHIFTER: - sprintf(joy->axis[joy->nr_axes].name, "Shifter"); - break; - case HID_USAGE_SIMULATION_STEERING: - sprintf(joy->axis[joy->nr_axes].name, "Steering"); - break; - default: - return; - } - - joy->axis[joy->nr_axes].id = joy->nr_axes; - rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; - rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; - rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; - - /* Assume unsigned when min >= 0 */ - if (prop->LogicalMin < 0) { - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; - } else { - /* - * Some joysticks will send -1 in LogicalMax, like Xbox Controllers - * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) - */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1ULL << prop->BitSize) - 1); - } - rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - - joy->nr_axes++; -} - -void -joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) -{ - if (joy->nr_povs >= MAX_JOY_POVS) - return; - - sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); - rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; - rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; - rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; - rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - - joy->nr_povs++; -} - -void -joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) -{ - UINT size = 0; - PHIDP_BUTTON_CAPS btn_caps = NULL; - PHIDP_VALUE_CAPS val_caps = NULL; - - /* Get preparsed data (HID data format) */ - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); - rawjoy->data = malloc(size); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); - - HIDP_CAPS caps; - HidP_GetCaps(rawjoy->data, &caps); - - /* Buttons */ - if (caps.NumberInputButtonCaps > 0) { - btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); - if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c = 0; c < caps.NumberInputButtonCaps; c++) { - if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON) - continue; - - int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1; - for (int b = 0; b < button_count; b++) { - joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin); - } - } - } - - /* Values (axes and povs) */ - if (caps.NumberInputValueCaps > 0) { - val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); - if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c = 0; c < caps.NumberInputValueCaps; c++) { - if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC) - continue; - - if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH) - joystick_add_pov(rawjoy, joy, &val_caps[c]); - else - joystick_add_axis(rawjoy, joy, &val_caps[c]); - } - } - -end: - free(btn_caps); - free(val_caps); -} - -void -joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info) -{ - UINT size = 0; - WCHAR *device_name = NULL; - WCHAR device_desc_wide[200] = { 0 }; - - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size); - device_name = calloc(size, sizeof(WCHAR)); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get device name.\n"); - - HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hDevObj) { - HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); - CloseHandle(hDevObj); - } - free(device_name); - - int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); - if (result == 0 || strlen(joy->name) == 0) - sprintf(joy->name, - "RawInput %s, VID:%04lX PID:%04lX", - info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", - info->hid.dwVendorId, - info->hid.dwProductId); -} - -void -joystick_init(void) -{ - UINT size = 0; - atexit(joystick_close); - - joysticks_present = 0; - memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); - - /* Get a list of raw input devices from Windows */ - UINT raw_devices = 0; - GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); - GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - - for (int i = 0; i < raw_devices; i++) { - PRID_DEVICE_INFO info = NULL; - - if (joysticks_present >= MAX_PLAT_JOYSTICKS) - break; - if (deviceList[i].dwType != RIM_TYPEHID) - continue; - - /* Get device info: hardware IDs and usage IDs */ - GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); - info = malloc(size); - info->cbSize = sizeof(RID_DEVICE_INFO); - if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) - goto end_loop; - - /* If this is not a joystick/gamepad, skip */ - if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) - goto end_loop; - if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) - goto end_loop; - - plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; - raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; - rawjoy->hdevice = deviceList[i].hDevice; - - joystick_get_capabilities(rawjoy, joy); - joystick_get_device_name(rawjoy, joy, info); - - joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", - joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); - - joysticks_present++; - -end_loop: - free(info); - } - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - /* Initialize the RawInput (joystick and gamepad) module. */ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = 0; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = 0; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) - fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); -} - -void -joystick_close(void) -{ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = RIDEV_REMOVE; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = RIDEV_REMOVE; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); -} - -void -win_joystick_handle(PRAWINPUT raw) -{ - HRESULT r; - int j = -1; /* current joystick index, -1 when not found */ - - /* If the input is not from a known device, we ignore it */ - for (int i = 0; i < joysticks_present; i++) { - if (raw_joystick_state[i].hdevice == raw->header.hDevice) { - j = i; - break; - } - } - if (j == -1) - return; - - /* Read buttons */ - USAGE usage_list[128] = { 0 }; - ULONG usage_length = plat_joystick_state[j].nr_buttons; - memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); - - r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - for (int i = 0; i < usage_length; i++) { - int button = raw_joystick_state[j].usage_button[usage_list[i]]; - plat_joystick_state[j].b[button] = 128; - } - } - - /* Read axes */ - for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - if (axis->min < 0) { - /* extend signed uvalue to LONG */ - if (uvalue & (1 << (axis->bitsize - 1))) { - ULONG mask = (1 << axis->bitsize) - 1; - value = -1U ^ mask; - value |= uvalue; - } else { - value = uvalue; - } - } else { - /* Assume unsigned when min >= 0, convert to a signed value */ - value = (LONG) uvalue - center; - } - if (abs(value) == 1) - value = 0; - value = value * 32768 / center; - } - - plat_joystick_state[j].a[a] = value; -#if 0 - joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); -#endif - } - - /* read povs */ - for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { - value = (uvalue - pov->min) * 36000; - value /= (pov->max - pov->min + 1); - value %= 36000; - } - - plat_joystick_state[j].p[p] = value; - -#if 0 - joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); -#endif - } -#if 0 - joystick_log("\n"); -#endif -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int d; - - if (joystick_type == JS_TYPE_NONE) - return; - - for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} diff --git a/src/win/win_joystick_xinput.c b/src/win/win_joystick_xinput.c deleted file mode 100644 index f313522a9..000000000 --- a/src/win/win_joystick_xinput.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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. - * - * Xinput joystick interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2019 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -#define XINPUT_MAX_JOYSTICKS 4 -#define XINPUT_NAME "Xinput compatiable controller" -#define XINPUT_NAME_LX "Left Stick X" -#define XINPUT_NAME_LY "Left Stick Y" -#define XINPUT_NAME_RX "Right Stick X" -#define XINPUT_NAME_RY "Right Stick Y" -#define XINPUT_NAME_DPAD_X "D-pad X" -#define XINPUT_NAME_DPAD_Y "D-pad Y" -#define XINPUT_NAME_LB "LB" -#define XINPUT_NAME_RB "RB" -#define XINPUT_NAME_LT "LT" -#define XINPUT_NAME_RT "RT" -#define XINPUT_NAME_A "A" -#define XINPUT_NAME_B "B" -#define XINPUT_NAME_X "X" -#define XINPUT_NAME_Y "Y" -#define XINPUT_NAME_BACK "Back/View" -#define XINPUT_NAME_START "Start/Menu" -#define XINPUT_NAME_LS "Left Stick" -#define XINPUT_NAME_RS "Right Stick" - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; - -XINPUT_STATE controllers[XINPUT_MAX_JOYSTICKS]; - -void -joystick_init() -{ - atexit(joystick_close); - - joysticks_present = 0; - - memset(controllers, 0, sizeof(XINPUT_STATE) * XINPUT_MAX_JOYSTICKS); - - for (uint8_t c = 0; c < XINPUT_MAX_JOYSTICKS; c++) { - int value = XInputGetState(c, &controllers[c]); - if (value != ERROR_SUCCESS) - continue; - memcpy(plat_joystick_state[c].name, XINPUT_NAME, sizeof(XINPUT_NAME)); - - plat_joystick_state[c].nr_axes = 8; - - /* analog stick */ - memcpy(plat_joystick_state[c].axis[0].name, XINPUT_NAME_LX, sizeof(XINPUT_NAME_LX)); - plat_joystick_state[c].axis[0].id = 0; /* X axis */ - memcpy(plat_joystick_state[c].axis[1].name, XINPUT_NAME_LY, sizeof(XINPUT_NAME_LY)); - plat_joystick_state[c].axis[1].id = 1; /* Y axis */ - memcpy(plat_joystick_state[c].axis[2].name, XINPUT_NAME_RX, sizeof(XINPUT_NAME_RX)); - plat_joystick_state[c].axis[2].id = 3; /* RX axis */ - memcpy(plat_joystick_state[c].axis[3].name, XINPUT_NAME_RY, sizeof(XINPUT_NAME_RY)); - plat_joystick_state[c].axis[3].id = 4; /* RY axis */ - - /* d-pad, assigned to Z and RZ */ - memcpy(plat_joystick_state[c].axis[4].name, XINPUT_NAME_DPAD_X, sizeof(XINPUT_NAME_DPAD_X)); - plat_joystick_state[c].axis[4].id = 2; - memcpy(plat_joystick_state[c].axis[5].name, XINPUT_NAME_DPAD_Y, sizeof(XINPUT_NAME_DPAD_Y)); - plat_joystick_state[c].axis[5].id = 5; - - /* Analog trigger */ - memcpy(plat_joystick_state[c].axis[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT)); - plat_joystick_state[c].axis[6].id = 6; - memcpy(plat_joystick_state[c].axis[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT)); - plat_joystick_state[c].axis[7].id = 7; - - plat_joystick_state[c].nr_buttons = 12; - memcpy(plat_joystick_state[c].button[0].name, XINPUT_NAME_A, sizeof(XINPUT_NAME_A)); - memcpy(plat_joystick_state[c].button[1].name, XINPUT_NAME_B, sizeof(XINPUT_NAME_B)); - memcpy(plat_joystick_state[c].button[2].name, XINPUT_NAME_X, sizeof(XINPUT_NAME_X)); - memcpy(plat_joystick_state[c].button[3].name, XINPUT_NAME_Y, sizeof(XINPUT_NAME_Y)); - memcpy(plat_joystick_state[c].button[4].name, XINPUT_NAME_LB, sizeof(XINPUT_NAME_LB)); - memcpy(plat_joystick_state[c].button[5].name, XINPUT_NAME_RB, sizeof(XINPUT_NAME_RB)); - memcpy(plat_joystick_state[c].button[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT)); - memcpy(plat_joystick_state[c].button[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT)); - memcpy(plat_joystick_state[c].button[8].name, XINPUT_NAME_BACK, sizeof(XINPUT_NAME_BACK)); - memcpy(plat_joystick_state[c].button[9].name, XINPUT_NAME_START, sizeof(XINPUT_NAME_START)); - memcpy(plat_joystick_state[c].button[10].name, XINPUT_NAME_LS, sizeof(XINPUT_NAME_LS)); - memcpy(plat_joystick_state[c].button[11].name, XINPUT_NAME_RS, sizeof(XINPUT_NAME_RS)); - - plat_joystick_state[c].nr_povs = 0; - - joysticks_present++; - } - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); -} - -void -joystick_close() -{ - // -} - -void -joystick_poll(void) -{ - for (int c = 0; c < joysticks_present; c++) { - int value = XInputGetState(c, &controllers[c]); - if (value != ERROR_SUCCESS) - continue; - - plat_joystick_state[c].a[0] = controllers[c].Gamepad.sThumbLX; - plat_joystick_state[c].a[1] = -controllers[c].Gamepad.sThumbLY; - plat_joystick_state[c].a[3] = controllers[c].Gamepad.sThumbRX; - plat_joystick_state[c].a[4] = -controllers[c].Gamepad.sThumbRY; - plat_joystick_state[c].a[6] = (double) controllers[c].Gamepad.bLeftTrigger / 255 * 32767; - plat_joystick_state[c].a[7] = (double) controllers[c].Gamepad.bRightTrigger / 255 * 32767; - - plat_joystick_state[c].b[0] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 128 : 0; - plat_joystick_state[c].b[1] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 128 : 0; - plat_joystick_state[c].b[2] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 128 : 0; - plat_joystick_state[c].b[3] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 128 : 0; - plat_joystick_state[c].b[4] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 128 : 0; - plat_joystick_state[c].b[5] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 128 : 0; - plat_joystick_state[c].b[6] = (controllers[c].Gamepad.bLeftTrigger > 127) ? 128 : 0; - plat_joystick_state[c].b[7] = (controllers[c].Gamepad.bRightTrigger > 127) ? 128 : 0; - plat_joystick_state[c].b[8] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 128 : 0; - plat_joystick_state[c].b[9] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 128 : 0; - plat_joystick_state[c].b[10] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 128 : 0; - plat_joystick_state[c].b[11] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 128 : 0; - - int dpad_x = 0; - int dpad_y = 0; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) - dpad_y -= 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) - dpad_y += 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) - dpad_x -= 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) - dpad_x += 32767; - - plat_joystick_state[c].a[2] = dpad_x; - plat_joystick_state[c].a[5] = dpad_y; - - for (int a = 0; a < 8; a++) { - if (plat_joystick_state[c].a[a] == -32768) - plat_joystick_state[c].a[a] = -32767; - if (plat_joystick_state[c].a[a] == 32768) - plat_joystick_state[c].a[a] = 32767; - } - } -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int d; - - if (!joystick_type) - return; - - joystick_poll(); - - for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} - -void -win_joystick_handle(UNUSED(PRAWINPUT raw)) -{ - // Nothing to be done here, atleast currently -} diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c deleted file mode 100644 index 416e7858d..000000000 --- a/src/win/win_jsconf.c +++ /dev/null @@ -1,527 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/gameport.h> -#include <86box/plat.h> -#include <86box/win.h> - -static int joystick_nr; -static int joystick_config_type; -#define AXIS_STRINGS_MAX 3 -static char *axis_strings[AXIS_STRINGS_MAX] = { "X Axis", "Y Axis", "Z Axis" }; - -static uint8_t joystickconfig_changed = 0; - -static void -rebuild_axis_button_selections(HWND hdlg) -{ - int id = IDC_CONFIG_BASE + 2; - HWND h; - int joystick; - int c; - int d; - char s[269]; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name); - if (c < AXIS_STRINGS_MAX) { - if (!stricmp(axis_strings[c], plat_joystick_state[joystick - 1].axis[d].name)) - sel = d; - } - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_buttons; d++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].button[d].name); - SendMessage(h, CB_SETCURSEL, c, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_pov_count(joystick_config_type) * 2; c++) { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } -} - -static int -get_axis(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - - if (axis_sel < nr_axes) - return axis_sel; - - axis_sel -= nr_axes; - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); -} - -static int -get_pov(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; - - if (axis_sel < nr_povs) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - - return axis_sel - nr_povs; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - int c; - int id; - int joystick; - int nr_axes; - int nr_povs; - int mapping; - - switch (message) { - case WM_INITDIALOG: - { - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - id = IDC_CONFIG_BASE + 2; - joystick = joystick_state[joystick_nr].plat_joystick_nr; - - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) "None"); - - for (c = 0; c < joysticks_present; c++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[c].name); - - SendMessage(h, CB_SETCURSEL, joystick, 0); - - rebuild_axis_button_selections(hdlg); - - if (joystick_state[joystick_nr].plat_joystick_nr) { - nr_axes = plat_joystick_state[joystick - 1].nr_axes; - nr_povs = plat_joystick_state[joystick - 1].nr_povs; - - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int mapping = joystick_state[joystick_nr].axis_mapping[c]; - - h = GetDlgItem(hdlg, id); - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping, 0); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][0]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - } - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIG_BASE: - if (HIWORD(wParam) == CBN_SELCHANGE) - rebuild_axis_button_selections(hdlg); - break; - - case IDOK: - { - id = IDC_CONFIG_BASE + 2; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (joystick_state[joystick_nr].plat_joystick_nr) { - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); - id += 2; - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); - id += 2; - } - } - } - joystickconfig_changed = 1; - EndDialog(hdlg, 0); - return TRUE; - case IDCANCEL: - joystickconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; -} - -uint8_t -joystickconfig_open(HWND hwnd, int joy_nr, int type) -{ - uint16_t *data_block = malloc(16384); - uint16_t *data; - DLGTEMPLATE *dlg = (DLGTEMPLATE *) data_block; - DLGITEMTEMPLATE *item; - int y = 10; - int id = IDC_CONFIG_BASE; - int c; - char s[269]; - - joystickconfig_changed = 0; - - joystick_nr = joy_nr; - joystick_config_type = type; - - memset(data_block, 0, 4096); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *) (dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - data += MultiByteToWideChar(CP_ACP, 0, "Joystick Configuration", -1, data, 50); - - *data++ = 9; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50); - - if (((uintptr_t) data) & 2) - data++; - - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - - for (c = 0; c < joystick_get_axis_count(type); c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_button_count(type); c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_pov_count(type) * 2; c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - if (c & 1) - sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c / 2)); - else - sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c / 2)); - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *) data; - item->x = 100; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - item = (DLGITEMTEMPLATE *) data; - item->x = 160; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* Cancel button identifier */ - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 25; - - DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc); - - free(data_block); - - return joystickconfig_changed; -} diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c deleted file mode 100644 index 54be91e6c..000000000 --- a/src/win/win_keyboard.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows raw keyboard input handler. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/plat.h> -#include <86box/win.h> - -static uint16_t scancode_map[768]; - -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -static UINT16 -convert_scan_code(UINT16 scan_code) -{ - if ((scan_code & 0xff00) == 0xe000) - scan_code = (scan_code & 0xff) | 0x0100; - - if (scan_code == 0xE11D) - scan_code = 0x0100; - /* E0 00 is sent by some USB keyboards for their special keys, as it is an - invalid scan code (it has no untranslated set 2 equivalent), we mark it - appropriately so it does not get passed through. */ - else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) - scan_code = 0xFFFF; - - return scan_code; -} - -void -keyboard_getkeymap(void) -{ - const WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const WCHAR *valueName = L"Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - const UINT32 *bufEx2; - int scMapCount; - const UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; - - /* First, prepare the default scan code map list which is 1:1. - * Remappings will be inserted directly into it. - * 512 bytes so this takes less memory, bit 9 set means E0 - * prefix. - */ - for (j = 0; j < 512; j++) - scancode_map[j] = j; - - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - bufSize = 32768; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { - bufEx2 = (UINT32 *) buf; - scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) { - bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; - - scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Ignore source scan codes with prefixes other than E1 - that are not E1 1D. */ - if (scancode_unmapped != 0xFFFF) - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -void -keyboard_handle(PRAWINPUT raw) -{ - USHORT scancode; - static int recv_lalt = 0; - static int recv_ralt = 0; - static int recv_tab = 0; - - RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; - - if (kbd_req_capture && !mouse_capture && !video_fullscreen) - return; - - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { - if (rawKB.Flags & RI_KEY_E0) - scancode |= 0x100; - - /* Translate the scan code to 9-bit */ - scancode = convert_scan_code(scancode); - - /* Remap it according to the list from the Registry */ - if (scancode != scancode_map[scancode]) - pclog("Scan code remap: %03X -> %03X\n", scancode, scancode); - scancode = scancode_map[scancode]; - - /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00f); - recv_tab = 0; - } else { - switch (scancode) { - case 0x00f: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; - } - - /* Translate right CTRL to left ALT if the user has so - chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } - } else { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } -} diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c deleted file mode 100644 index 549a495b9..000000000 --- a/src/win/win_media_menu.c +++ /dev/null @@ -1,766 +0,0 @@ -#define UNICODE -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/cdrom.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/fdd_86f.h> -#include <86box/hdc.h> -#include <86box/language.h> -#include <86box/machine.h> -#include <86box/scsi_device.h> -#include <86box/mo.h> -#include <86box/plat.h> -#include <86box/scsi.h> -#include <86box/sound.h> -#include <86box/ui.h> -#include <86box/zip.h> -#include <86box/win.h> - -#define MACHINE_HAS_IDE (machine_has_flags(machine, MACHINE_IDE_QUAD)) -#define MACHINE_HAS_SCSI (machine_has_flags(machine, MACHINE_SCSI)) - -#define CASSETTE_FIRST 0 -#define CARTRIDGE_FIRST CASSETTE_FIRST + 1 -#define FDD_FIRST CARTRIDGE_FIRST + 2 -#define CDROM_FIRST FDD_FIRST + FDD_NUM -#define ZIP_FIRST CDROM_FIRST + CDROM_NUM -#define MO_FIRST ZIP_FIRST + ZIP_NUM - -static HMENU media_menu; -static HMENU stbar_menu; -static HMENU menus[1 + 2 + FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM]; - -static char index_map[255]; - -static void -media_menu_set_ids(HMENU hMenu, int id) -{ - int c = GetMenuItemCount(hMenu); - - MENUITEMINFO mii = { 0 }; - mii.fMask = MIIM_ID; - mii.cbSize = sizeof(mii); - - for (int i = 0; i < c; i++) { - GetMenuItemInfo(hMenu, i, TRUE, &mii); - mii.wID |= id; - SetMenuItemInfo(hMenu, i, TRUE, &mii); - } -} - -/* Loads the submenu from resource by name */ -static HMENU -media_menu_load_resource(wchar_t *lpName) -{ - HMENU loaded = LoadMenu(NULL, lpName); - - /* The actual submenu is in a dummy popup menu item */ - HMENU actual = GetSubMenu(loaded, 0); - - /* Now that we have our submenu, we can destroy the parent menu */ - RemoveMenu(loaded, (UINT_PTR) actual, MF_BYCOMMAND); - DestroyMenu(loaded); - - return actual; -} - -static void -media_menu_set_name_cassette(void) -{ - wchar_t name[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - if (strlen(cassette_fname) == 0) - _swprintf(name, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); - else { - mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2149), fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CASSETTE_FIRST], FALSE, &mii); -} - -static void -media_menu_set_name_cartridge(int drive) -{ - wchar_t name[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - if (strlen(cart_fns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2151), - drive + 1, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2151), - drive + 1, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CARTRIDGE_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_floppy(int drive) -{ - wchar_t name[512]; - wchar_t temp[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - mbstoc16s(temp, fdd_getname(fdd_get_type(drive)), - strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (strlen(floppyfns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2109), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2109), - drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[FDD_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_cdrom(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = cdrom[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - if (cdrom[drive].host_drive == 200) { - if (strlen(cdrom[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_5120), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cdrom[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_5120), - drive + 1, temp, fn); - } - } else - _swprintf(name, plat_get_string(IDS_5120), drive + 1, temp, plat_get_string(IDS_2057)); - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CDROM_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_zip(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = zip_drives[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - int type = zip_drives[drive].is_250 ? 250 : 100; - - if (strlen(zip_drives[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_2054), - type, drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, zip_drives[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2054), - type, drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[ZIP_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_mo(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = mo_drives[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_2116), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2116), - drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[MO_FIRST + drive], FALSE, &mii); -} - -void -media_menu_update_cassette(void) -{ - int i = CASSETTE_FIRST; - - if (strlen(cassette_fname) == 0) { - EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_GRAYED); - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_GRAYED); - } else { - EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_ENABLED); - if (strcmp(cassette_mode, "save") == 0) { - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - } else { - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED); - } - EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_ENABLED); - } - - media_menu_set_name_cassette(); -} - -void -media_menu_update_cartridge(int id) -{ - int i = CARTRIDGE_FIRST + id; - - if (strlen(cart_fns[id]) == 0) - EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_cartridge(id); -} - -void -media_menu_update_floppy(int id) -{ - int i = FDD_FIRST + id; - - if (strlen(floppyfns[id]) == 0) { - EnableMenuItem(menus[i], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED); - } else { - EnableMenuItem(menus[i], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_ENABLED); - } - - media_menu_set_name_floppy(id); -} - -void -media_menu_update_cdrom(int id) -{ - int i = CDROM_FIRST + id; - - if (!cdrom[id].sound_on) - CheckMenuItem(menus[i], IDM_CDROM_MUTE | id, MF_BYCOMMAND | MF_CHECKED); - else - CheckMenuItem(menus[i], IDM_CDROM_MUTE | id, MF_BYCOMMAND | MF_UNCHECKED); - - if (cdrom[id].host_drive == 200) { - CheckMenuItem(menus[i], IDM_CDROM_IMAGE | id, MF_BYCOMMAND | (cdrom[id].is_dir ? MF_UNCHECKED : MF_CHECKED)); - CheckMenuItem(menus[i], IDM_CDROM_DIR | id, MF_BYCOMMAND | (cdrom[id].is_dir ? MF_CHECKED : MF_UNCHECKED)); - CheckMenuItem(menus[i], IDM_CDROM_EMPTY | id, MF_BYCOMMAND | MF_UNCHECKED); - } else { - cdrom[id].host_drive = 0; - CheckMenuItem(menus[i], IDM_CDROM_IMAGE | id, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CDROM_DIR | id, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CDROM_EMPTY | id, MF_BYCOMMAND | MF_CHECKED); - } - - if (cdrom[id].prev_host_drive == 0) - EnableMenuItem(menus[i], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_cdrom(id); -} - -void -media_menu_update_zip(int id) -{ - int i = ZIP_FIRST + id; - - if (strlen(zip_drives[id].image_path) == 0) - EnableMenuItem(menus[i], IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - if (strlen(zip_drives[id].prev_image_path) == 0) - EnableMenuItem(menus[i], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_zip(id); -} - -void -media_menu_update_mo(int id) -{ - int i = MO_FIRST + id; - - if (strlen(mo_drives[id].image_path) == 0) - EnableMenuItem(menus[i], IDM_MO_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_MO_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - if (strlen(mo_drives[id].prev_image_path) == 0) - EnableMenuItem(menus[i], IDM_MO_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_MO_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_mo(id); -} - -static void -media_menu_load_submenus(void) -{ - memset(index_map, -1, sizeof(index_map)); - - int curr = 0; - - menus[curr] = media_menu_load_resource(CASSETTE_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], 0); - - for (int i = 0; i < 2; i++) { - menus[curr] = media_menu_load_resource(CARTRIDGE_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < FDD_NUM; i++) { - menus[curr] = media_menu_load_resource(FLOPPY_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < CDROM_NUM; i++) { - menus[curr] = media_menu_load_resource(CDROM_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < ZIP_NUM; i++) { - menus[curr] = media_menu_load_resource(ZIP_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < MO_NUM; i++) { - menus[curr] = media_menu_load_resource(MO_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } -} - -static inline int -is_valid_cartridge(void) -{ - return (machine_has_cartridge(machine)); -} - -static inline int -is_valid_fdd(int i) -{ - return fdd_get_type(i) != 0; -} - -static inline int -is_valid_cdrom(int i) -{ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return cdrom[i].bus_type != 0; -} - -static inline int -is_valid_zip(int i) -{ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return zip_drives[i].bus_type != 0; -} - -static inline int -is_valid_mo(int i) -{ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return mo_drives[i].bus_type != 0; -} - -void -media_menu_reset(void) -{ - /* Remove existing entries. */ - int c = GetMenuItemCount(media_menu); - - for (int i = 0; i < c; i++) - RemoveMenu(media_menu, 0, MF_BYPOSITION); - - /* Add new ones. */ - int curr = 0; - - if (cassette_enable) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cassette(); - } - curr++; - - for (int i = 0; i < 2; i++) { - if (is_valid_cartridge()) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cartridge(i); - } - curr++; - } - - for (int i = 0; i < FDD_NUM; i++) { - if (is_valid_fdd(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_floppy(i); - } - curr++; - } - - for (int i = 0; i < CDROM_NUM; i++) { - if (is_valid_cdrom(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cdrom(i); - } - curr++; - } - - for (int i = 0; i < ZIP_NUM; i++) { - if (is_valid_zip(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_zip(i); - } - curr++; - } - - for (int i = 0; i < MO_NUM; i++) { - if (is_valid_mo(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_mo(i); - } - curr++; - } -} - -/* Initializes the Media menu in the main menu bar. */ -static void -media_menu_main_init(void) -{ - HMENU hMenu; - LPWSTR lpMenuName; - - hMenu = GetMenu(hwndMain); - media_menu = CreatePopupMenu(); - - /* Get the menu name */ - int len = GetMenuString(hMenu, IDM_MEDIA, NULL, 0, MF_BYCOMMAND); - lpMenuName = malloc((len + 1) * sizeof(WCHAR)); - GetMenuString(hMenu, IDM_MEDIA, lpMenuName, len + 1, MF_BYCOMMAND); - - /* Replace the placeholder menu item */ - ModifyMenu(hMenu, IDM_MEDIA, MF_BYCOMMAND | MF_STRING | MF_POPUP, (UINT_PTR) media_menu, lpMenuName); - - /* Clean up */ - DrawMenuBar(hwndMain); - free(lpMenuName); -} - -void -media_menu_init(void) -{ - /* Initialize the main menu bar menu */ - media_menu_main_init(); - - /* Initialize the dummy status bar menu. */ - stbar_menu = CreateMenu(); - AppendMenu(stbar_menu, MF_POPUP, (UINT_PTR) media_menu, NULL); - - /* Load the submenus for each drive type. */ - media_menu_load_submenus(); - - /* Populate the Media and status bar menus. */ - media_menu_reset(); -} - -int -media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - int id = 0; - int ret = 0; - int wp = 0; - -#ifdef __clang__ - BROWSEINFO bi; -#endif - - id = LOWORD(wParam) & 0x00ff; - - switch (LOWORD(wParam) & 0xff00) { - case IDM_CASSETTE_IMAGE_NEW: - ret = file_dlg_st(hwnd, IDS_2150, "", NULL, 1); - if (!ret) { - if (strlen(openfilestring) == 0) - cassette_mount(NULL, wp); - else - cassette_mount(openfilestring, wp); - } - break; - - case IDM_CASSETTE_RECORD: - pc_cas_set_mode(cassette, 1); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - break; - case IDM_CASSETTE_PLAY: - pc_cas_set_mode(cassette, 0); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED); - break; - case IDM_CASSETTE_REWIND: - pc_cas_rewind(cassette); - break; - case IDM_CASSETTE_FAST_FORWARD: - pc_cas_append(cassette); - break; - - case IDM_CASSETTE_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_CASSETTE_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2150, cassette_fname, NULL, 0); - if (!ret) { - if (strlen(openfilestring) == 0) - cassette_mount(NULL, wp); - else - cassette_mount(openfilestring, wp); - } - break; - - case IDM_CASSETTE_EJECT: - cassette_eject(); - break; - - case IDM_CARTRIDGE_IMAGE: - ret = file_dlg_st(hwnd, IDS_2152, cart_fns[id], NULL, 0); - if (!ret) - cartridge_mount(id, openfilestring, wp); - break; - - case IDM_CARTRIDGE_EJECT: - cartridge_eject(id); - break; - - case IDM_FLOPPY_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id, 0); - break; - - case IDM_FLOPPY_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_FLOPPY_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2110, floppyfns[id], NULL, 0); - if (!ret) - floppy_mount(id, openfilestring, wp); - break; - - case IDM_FLOPPY_EJECT: - floppy_eject(id); - break; - - case IDM_FLOPPY_EXPORT_TO_86F: - ret = file_dlg_st(hwnd, IDS_2076, floppyfns[id], NULL, 1); - if (!ret) { - plat_pause(1); - ret = d86f_export(id, openfilestring); - if (!ret) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); - plat_pause(0); - } - break; - - case IDM_CDROM_MUTE: - cdrom[id].sound_on ^= 1; - config_save(); - media_menu_update_cdrom(id); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_EMPTY: - cdrom_eject(id); - break; - - case IDM_CDROM_RELOAD: - cdrom_reload(id); - break; - - case IDM_CDROM_IMAGE: - if (!file_dlg_st(hwnd, IDS_2141, cdrom[id].is_dir ? NULL : cdrom[id].image_path, NULL, 0)) { - cdrom_mount(id, openfilestring); - } - break; - - case IDM_CDROM_DIR: -#ifndef __clang__ - BROWSEINFO bi = { - .hwndOwner = hwnd, - .ulFlags = BIF_EDITBOX - }; -#else - bi.hwndOwner = hwnd; - bi.ulFlags = BIF_EDITBOX; -#endif - OleInitialize(NULL); - int old_dopause = dopause; - plat_pause(1); - LPITEMIDLIST pidl = SHBrowseForFolder(&bi); - plat_pause(old_dopause); - plat_chdir(usr_path); - if (pidl) { - wchar_t wbuf[MAX_PATH + 1]; - if (SHGetPathFromIDList(pidl, wbuf)) { - char buf[MAX_PATH + 1]; - c16stombs(buf, wbuf, sizeof(buf) - 1); - cdrom_mount(id, buf); - } - } - break; - - case IDM_ZIP_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id | 0x80, 0); /* NewZIPDialogCreate */ - break; - - case IDM_ZIP_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_ZIP_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2058, zip_drives[id].image_path, NULL, 0); - if (!ret) - zip_mount(id, openfilestring, wp); - break; - - case IDM_ZIP_EJECT: - zip_eject(id); - break; - - case IDM_ZIP_RELOAD: - zip_reload(id); - break; - - case IDM_MO_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id | 0x100, 0); /* NewZIPDialogCreate */ - break; - - case IDM_MO_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_MO_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2117, mo_drives[id].image_path, NULL, 0); - if (!ret) - mo_mount(id, openfilestring, wp); - break; - - case IDM_MO_EJECT: - mo_eject(id); - break; - - case IDM_MO_RELOAD: - mo_reload(id); - break; - - default: - return 0; - } - - return 1; -} - -HMENU -media_menu_get_cassette(void) -{ - return menus[CASSETTE_FIRST]; -} - -HMENU -media_menu_get_cartridge(int id) -{ - return menus[CARTRIDGE_FIRST + id]; -} - -HMENU -media_menu_get_floppy(int id) -{ - return menus[FDD_FIRST + id]; -} - -HMENU -media_menu_get_cdrom(int id) -{ - return menus[CDROM_FIRST + id]; -} - -HMENU -media_menu_get_zip(int id) -{ - return menus[ZIP_FIRST + id]; -} - -HMENU -media_menu_get_mo(int id) -{ - return menus[MO_FIRST + id]; -} diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c deleted file mode 100644 index f2b185eaa..000000000 --- a/src/win/win_mouse.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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. - * - * RawInput mouse interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2017 Miran Grca. - * Copyright 2019 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mouse.h> -#include <86box/pic.h> -#include <86box/plat.h> -#include <86box/win.h> - -int mouse_capture; - -void -win_mouse_init(void) -{ - atexit(win_mouse_close); - - mouse_capture = 0; - - /* Initialize the RawInput (mouse) module. */ - RAWINPUTDEVICE ridev; - ridev.dwFlags = 0; - ridev.hwndTarget = NULL; - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x02; - if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) - fatal("plat_mouse_init: RegisterRawInputDevices failed\n"); -} - -void -win_mouse_handle(PRAWINPUT raw) -{ - RAWMOUSE state = raw->data.mouse; - static int x; - static int delta_x; - static int y; - static int delta_y; - static int b; - static int delta_z; - - b = mouse_get_buttons_ex(); - - /* read mouse buttons and wheel */ - if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - b |= 1; - else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - b &= ~1; - - if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - b |= 4; - else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - b &= ~4; - - if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - b |= 2; - else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - b &= ~2; - - if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - b |= 8; - else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - b &= ~8; - - if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - b |= 16; - else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - b &= ~16; - - mouse_set_buttons_ex(b); - - if (state.usButtonFlags & RI_MOUSE_WHEEL) { - delta_z = (SHORT) state.usButtonData / 120; - mouse_set_z(delta_z); - } else - delta_z = 0; - - if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { - /* absolute mouse, i.e. RDP or VNC - * seems to work fine for RDP on Windows 10 - * Not sure about other environments. - */ - delta_x = (state.lLastX - x) / 25; - delta_y = (state.lLastY - y) / 25; - x = state.lLastX; - y = state.lLastY; - } else { - /* relative mouse, i.e. regular mouse */ - delta_x = state.lLastX; - delta_y = state.lLastY; - } - - mouse_scale(delta_x, delta_y); -} - -void -win_mouse_close(void) -{ - RAWINPUTDEVICE ridev; - ridev.dwFlags = RIDEV_REMOVE; - ridev.hwndTarget = NULL; - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x02; - RegisterRawInputDevices(&ridev, 1, sizeof(ridev)); -} diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c deleted file mode 100644 index d0a245a45..000000000 --- a/src/win/win_new_floppy.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * 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. - * - * Handle the New Floppy Image dialog. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/disksizes.h> -#include <86box/plat.h> -#include <86box/random.h> -#include <86box/ui.h> -#include <86box/scsi_device.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/win.h> - -static unsigned char *empty; - -static int -create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) -{ - FILE *fp; - - uint32_t magic = 0x46423638; - uint16_t version = 0x020C; - uint16_t dflags = 0; - uint16_t tflags = 0; - uint32_t index_hole_pos = 0; - uint32_t tarray[512]; - uint32_t array_size; - uint32_t track_base; - uint32_t track_size; - int i; - uint32_t shift = 0; - - dflags = 0; /* Has surface data? - Assume no for now. */ - dflags |= (disk_size.hole << 1); /* Hole */ - dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ - dflags |= (0 << 4); /* Write protect? - Assume no for now. */ - dflags |= (rpm_mode << 5); /* RPM mode. */ - dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ - - tflags = disk_size.data_rate; /* Data rate. */ - tflags |= (disk_size.encoding << 3); /* Encoding. */ - tflags |= (disk_size.rpm << 5); /* RPM. */ - - switch (disk_size.hole) { - default: - case 0: - case 1: - switch (rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch (rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; - } - - empty = (unsigned char *) malloc(array_size); - - memset(tarray, 0, 2048); - memset(empty, 0, array_size); - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - fwrite(&magic, 4, 1, fp); - fwrite(&version, 2, 1, fp); - fwrite(&dflags, 2, 1, fp); - - track_size = array_size + 6; - - track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); - - if (disk_size.tracks <= 43) - shift = 1; - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); - - fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, fp); - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, fp); - fwrite(&index_hole_pos, 4, 1, fp); - fwrite(empty, 1, array_size, fp); - } - - free(empty); - - fclose(fp); - - return 1; -} - -static int is_zip; -static int is_mo; - -static int -create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) -{ - FILE *fp; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - if (!is_zip && !is_mo && is_fdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, base, fp); - free(empty); - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (!is_zip && !is_mo) { - memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); - - empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ - empty[0x01] = 0x58; - empty[0x02] = 0x90; - - empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ - empty[0x04] = 0x36; - empty[0x05] = 0x42; - empty[0x06] = 0x4F; - empty[0x07] = 0x58; - empty[0x08] = 0x35; - empty[0x09] = 0x2E; - empty[0x0A] = 0x30; - - *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; - *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; - *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; - *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; - *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; - *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; - *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; - - empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x27] = random_generate(); - empty[0x28] = random_generate(); - empty[0x29] = random_generate(); - empty[0x2A] = random_generate(); - - memset(&(empty[0x2B]), 0x20, 11); - - empty[0x36] = 'F'; - empty[0x37] = 'A'; - empty[0x38] = 'T'; - empty[0x39] = '1'; - empty[0x3A] = '2'; - memset(&(empty[0x3B]), 0x20, 0x0003); - - empty[0x1FE] = 0x55; - empty[0x1FF] = 0xAA; - - empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15]; - empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = 0xFF; - empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF; - } - - fwrite(empty, 1, total_size, fp); - free(empty); - - fclose(fp); - - return 1; -} - -static int -create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, HWND hwnd) -{ - HWND h; - FILE *fp; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; - MSG msg; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - pbar_max = total_size; - if (is_zdi) - pbar_max += base; - pbar_max >>= 11; - pbar_max--; - - h = GetDlgItem(hwnd, IDC_COMBO_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) pbar_max); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - h = GetDlgItem(hwnd, IDT_FLP_PROGRESS); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - pbar_max++; - - if (is_zdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - fwrite(&empty[0x0800], 1, 2048, fp); - free(empty); - - SendMessage(h, PBM_SETPOS, (WPARAM) 2, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - pbar_max -= 2; - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (total_sectors == ZIP_SECTORS) { - /* ZIP 100 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; - *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; - *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E90644LL; - *(uint64_t *) &(empty[0x01B6]) = 0xED08BBE5014E0135LL; - *(uint64_t *) &(empty[0x01BE]) = 0xFFFFFE06FFFFFE80LL; - *(uint64_t *) &(empty[0x01C6]) = 0x0002FFE000000020LL; - - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 31 sectors filled with 0x48 */ - memset(&(empty[0x0200]), 0x48, 0x3E00); - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0008040200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000FF003FLL; - *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - memset(&(empty[0x403B]), 0x20, 0x0003); - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x5000] = empty[0x1D000] = empty[0x4015]; - empty[0x5001] = empty[0x1D001] = 0xFF; - empty[0x5002] = empty[0x1D002] = 0xFF; - empty[0x5003] = empty[0x1D003] = 0xFF; - - /* Root directory = 0x35000 - Data = 0x39000 */ - } else { - /* ZIP 250 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; - *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; - *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL; - *(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL; - - *(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL; - *(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL; - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 31 sectors filled with 0x48 */ - memset(&(empty[0x0200]), 0x48, 0x3E00); - - /* The second sector begins with some strange data - in my reference image. */ - *(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL; - *(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL; - *(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL; - *(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL; - *(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL; - *(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL; - *(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL; - *(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL; - *(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL; - *(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL; - *(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL; - *(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL; - *(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL; - *(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL; - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL; - *(uint32_t *) &(empty[0x4020]) = 0x000777E0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - memset(&(empty[0x403B]), 0x20, 0x0003); - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x4200] = empty[0x22000] = empty[0x4015]; - empty[0x4201] = empty[0x22001] = 0xFF; - empty[0x4202] = empty[0x22002] = 0xFF; - empty[0x4203] = empty[0x22003] = 0xFF; - - /* Root directory = 0x3FE00 - Data = 0x38200 */ - } - - for (uint32_t i = 0; i < pbar_max; i++) { - fwrite(&empty[i << 11], 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - free(empty); - - fclose(fp); - - return 1; -} - -static int -create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND hwnd) -{ - HWND h; - FILE *fp; - const mo_type_t *dp = &mo_types[disk_size]; - uint8_t *empty; - uint8_t *empty2 = NULL; - uint32_t total_size = 0; - uint32_t total_size2; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; - uint32_t blocks_num; - uint32_t j; - MSG msg; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = dp->bytes_per_sector; - total_sectors = dp->sectors; - total_size = total_sectors * sector_bytes; - - total_size2 = (total_size >> 20) << 20; - total_size2 = total_size - total_size2; - - pbar_max = total_size; - pbar_max >>= 20; - blocks_num = pbar_max; - if (is_mdi) - pbar_max++; - if (total_size2 == 0) - pbar_max++; - - j = is_mdi ? 1 : 0; - - h = GetDlgItem(hwnd, IDC_COMBO_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) pbar_max - 1); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - h = GetDlgItem(hwnd, IDT_FLP_PROGRESS); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - - if (is_mdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; - *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; - - fwrite(empty, 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - fwrite(&empty[0x0800], 1, 2048, fp); - free(empty); - - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - empty = (unsigned char *) malloc(1048576); - memset(empty, 0x00, 1048576); - - if (total_size2 > 0) { - empty2 = (unsigned char *) malloc(total_size2); - memset(empty, 0x00, total_size2); - } - - for (uint32_t i = 0; i < blocks_num; i++) { - fwrite(empty, 1, 1048576, fp); - - SendMessage(h, PBM_SETPOS, (WPARAM) i + j, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (total_size2 > 0) { - fwrite(empty2, 1, total_size2, fp); - - SendMessage(h, PBM_SETPOS, (WPARAM) pbar_max - 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (empty2 != NULL) - free(empty2); - free(empty); - - fclose(fp); - - return 1; -} - -static int fdd_id; -static int sb_part; - -static int file_type = 0; /* 0 = IMG, 1 = Japanese FDI, 2 = 86F */ -static char fd_file_name[1024]; - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -new_floppy_msgbox_header(HWND hwnd, int flags, void *header, void *message) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwnd; - - i = ui_msgbox_header(flags, header, message); - - hwndMain = h; - - return i; -} - -static int -new_floppy_msgbox_ex(HWND hwnd, int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwnd; - - i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); - - hwndMain = h; - - return i; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - int i = 0; - int wcs_len; - int ext_offs; - const wchar_t *ext; - uint8_t disk_size; - uint8_t rpm_mode; - int ret; - FILE *fp; - int zip_types; - int mo_types; - int floppy_types; - wchar_t *twcs; - - switch (message) { - case WM_INITDIALOG: - plat_pause(1); - memset(fd_file_name, 0, 1024); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (is_zip) { - zip_types = zip_drives[fdd_id].is_250 ? 2 : 1; - for (i = 0; i < zip_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5900 + i)); - } else if (is_mo) { - mo_types = 10; - /* TODO: Proper string ID's. */ - for (i = 0; i < mo_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5902 + i)); - } else { - floppy_types = 12; - for (i = 0; i < floppy_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5888 + i)); - } - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - for (i = 0; i < 4; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_6144 + i)); - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_FLP_PROGRESS); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - disk_size = SendMessage(h, CB_GETCURSEL, 0, 0); - if (is_zip) - disk_size += 12; - if (!is_zip && !is_mo && (file_type == 2)) { - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - rpm_mode = SendMessage(h, CB_GETCURSEL, 0, 0); - ret = create_86f(fd_file_name, disk_sizes[disk_size], rpm_mode); - } else { - if (is_zip) - ret = create_zip_sector_image(fd_file_name, disk_sizes[disk_size], file_type, hdlg); - if (is_mo) - ret = create_mo_sector_image(fd_file_name, disk_size, file_type, hdlg); - else - ret = create_sector_image(fd_file_name, disk_sizes[disk_size], file_type); - } - if (ret) { - if (is_zip) - zip_mount(fdd_id, fd_file_name, 0); - else if (is_mo) - mo_mount(fdd_id, fd_file_name, 0); - else - floppy_mount(fdd_id, fd_file_name, 0); - } else { - new_floppy_msgbox_header(hdlg, MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); - return TRUE; - } - fallthrough; - case IDCANCEL: - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2140 : (is_zip ? IDS_2055 : IDS_2062)), L"", NULL, 1)) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - if (!is_zip && !is_mo && (filterindex == 3)) { - twcs[1] = L'8'; - twcs[2] = L'6'; - twcs[3] = L'f'; - } else { - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - } - h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); - fp = _wfopen(wopenfilestring, L"rb"); - if (fp != NULL) { - fclose(fp); - if (new_floppy_msgbox_ex(hdlg, MBX_QUESTION, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ - return FALSE; - } - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(fd_file_name, 0, sizeof(fd_file_name)); - c16stombs(fd_file_name, wopenfilestring, sizeof(fd_file_name)); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (!is_zip || zip_drives[fdd_id].is_250) - EnableWindow(h, TRUE); - wcs_len = wcslen(wopenfilestring); - ext_offs = wcs_len - 4; - ext = &(wopenfilestring[ext_offs]); - if (is_zip) { - if ((wcs_len >= 4) && !wcsicmp(ext, L".ZDI")) - file_type = 1; - else - file_type = 0; - } else if (is_mo) { - if ((wcs_len >= 4) && !wcsicmp(ext, L".MDI")) - file_type = 1; - else - file_type = 0; - } else { - if ((wcs_len >= 4) && !wcsicmp(ext, L".FDI")) - file_type = 1; - else if (((wcs_len >= 4) && !wcsicmp(ext, L".86F")) || (filterindex == 3)) - file_type = 2; - else - file_type = 0; - } - h = GetDlgItem(hdlg, IDT_FLP_RPM_MODE); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, TRUE); - return TRUE; - } else - return FALSE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -NewFloppyDialogCreate(HWND hwnd, int id, int part) -{ - fdd_id = id & 0x7f; - sb_part = part; - is_zip = !!(id & 0x80); - is_mo = !!(id & 0x100); - if (is_zip && is_mo) { - fatal("Attempting to create a new image dialog that is for both ZIP and MO at the same time\n"); - return; - } - DialogBox(hinstance, (LPCTSTR) DLG_NEW_FLOPPY, hwnd, NewFloppyDialogProcedure); -} diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c deleted file mode 100644 index 094b3d063..000000000 --- a/src/win/win_opengl.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* - * 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. - * - * Rendering module for OpenGL - * - * TODO: More shader features - * - scaling - * - multipass - * - previous frames - * (UI) options - * More error handling - * - * - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#define UNICODE -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !defined(_MSC_VER) || defined(__clang__) -# include -#else -typedef LONG atomic_flag; -# define atomic_flag_clear(OBJ) InterlockedExchange(OBJ, 0) -# define atomic_flag_test_and_set(OBJ) InterlockedExchange(OBJ, 1) -#endif - -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/thread.h> -#include <86box/video.h> -#include <86box/win.h> -#include <86box/language.h> -#include <86box/win_opengl.h> -#include <86box/win_opengl_glslp.h> - -static const int INIT_WIDTH = 640; -static const int INIT_HEIGHT = 400; -static const int BUFFERPIXELS = 4194304; /* Same size as render_buffer, pow(2048 + 64, 2). */ -static const int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ -static const int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ -static const int ROW_LENGTH = 2048; /* Source buffer row lenght (including padding) */ - -/** - * @brief A dedicated OpenGL thread. - * OpenGL context's don't handle multiple threads well. - */ -static thread_t *thread = NULL; - -/** - * @brief A window usable with an OpenGL context - */ -static SDL_Window *window = NULL; - -/** - * @brief SDL window handle - */ -static HWND window_hwnd = NULL; - -/** - * @brief Parent window handle (hwndRender from win_ui) - */ -static HWND parent = NULL; - -/** - * @brief Events listened in OpenGL thread. - */ -static union { - struct - { - HANDLE closing; - HANDLE resize; - HANDLE reload; - HANDLE blit_waiting; - }; - HANDLE asArray[4]; -} sync_objects = { 0 }; - -/** - * @brief Blit event parameters. - */ -typedef struct -{ - int w, h; - void *buffer; /* Buffer for pixel transfer, allocated by gpu driver. */ - volatile atomic_flag in_use; /* Is buffer currently in use. */ - GLsync sync; /* Fence sync object used by opengl thread to track pixel transfer completion. */ -} blit_info_t; - -/** - * @brief Array of blit_infos, one for each buffer. - */ -static blit_info_t *blit_info = NULL; - -/** - * @brief Buffer index of next write operation. - */ -static int write_pos = 0; - -/** - * @brief Resize event parameters. - */ -static struct -{ - int width, height, fullscreen, scaling_mode; - mutex_t *mutex; -} resize_info = { 0 }; - -/** - * @brief Renderer options - */ -static struct -{ - int vsync; /* Vertical sync; 0 = off, 1 = on */ - int frametime; /* Frametime in microseconds, or -1 to sync with blitter */ - char shaderfile[512]; /* Shader file path. Match the length of openfilestring in win_dialog.c */ - int shaderfile_changed; /* Has shader file path changed. To prevent unnecessary shader recompilation. */ - int filter; /* 0 = Nearest, 1 = Linear */ - int filter_changed; /* Has filter changed. */ - mutex_t *mutex; -} options = { 0 }; - -/** - * @brief Identifiers to OpenGL objects and uniforms. - */ -typedef struct -{ - GLuint vertexArrayID; - GLuint vertexBufferID; - GLuint textureID; - GLuint unpackBufferID; - GLuint shader_progID; - - /* Uniforms */ - - GLint input_size; - GLint output_size; - GLint texture_size; - GLint frame_count; -} gl_identifiers; - -/** - * @brief Set or unset OpenGL context window as a child window. - * - * Modifies the window style and sets the parent window. - * WS_EX_NOACTIVATE keeps the window from stealing input focus. - */ -static void -set_parent_binding(int enable) -{ - long style = GetWindowLong(window_hwnd, GWL_STYLE); - long ex_style = GetWindowLong(window_hwnd, GWL_EXSTYLE); - - if (enable) { - style |= WS_CHILD; - ex_style |= WS_EX_NOACTIVATE; - } else { - style &= ~WS_CHILD; - ex_style &= ~WS_EX_NOACTIVATE; - } - - SetWindowLong(window_hwnd, GWL_STYLE, style); - SetWindowLong(window_hwnd, GWL_EXSTYLE, ex_style); - - SetParent(window_hwnd, enable ? parent : NULL); -} - -/** - * @brief Windows message handler for our window. - * @param message - * @param wParam - * @param lParam - * @param fullscreen - * @return Was message handled - */ -static int -handle_window_messages(UINT message, WPARAM wParam, LPARAM lParam, int fullscreen) -{ - switch (message) { - case WM_LBUTTONUP: - case WM_LBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - if (!fullscreen) { - /* Bring main window to front. */ - SetForegroundWindow(GetAncestor(parent, GA_ROOT)); - - /* Mouse events that enter and exit capture. */ - PostMessage(parent, message, wParam, lParam); - } - return 1; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - if (fullscreen) { - PostMessage(parent, message, wParam, lParam); - } - return 1; - case WM_INPUT: - if (fullscreen) { - /* Raw input handler from win_ui.c : input_proc */ - - UINT size = 0; - PRAWINPUT raw = NULL; - - /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = (PRAWINPUT) malloc(size); - if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { - switch (raw->header.dwType) { - case RIM_TYPEKEYBOARD: - keyboard_handle(raw); - break; - case RIM_TYPEMOUSE: - win_mouse_handle(raw); - break; - case RIM_TYPEHID: - win_joystick_handle(raw); - break; - } - } - free(raw); - } - return 1; - case WM_MOUSELEAVE: - if (fullscreen) { - /* Leave fullscreen if mouse leaves the renderer window. */ - PostMessage(GetAncestor(parent, GA_ROOT), WM_LEAVEFULLSCREEN, 0, 0); - } - return 0; - } - - return 0; -} - -/** - * @brief (Re-)apply shaders to OpenGL context. - * @param gl Identifiers from initialize - */ -static void -apply_shaders(gl_identifiers *gl) -{ - GLuint old_shader_ID = 0; - - if (gl->shader_progID != 0) - old_shader_ID = gl->shader_progID; - - if (strlen(options.shaderfile) > 0) - gl->shader_progID = load_custom_shaders(options.shaderfile); - else - gl->shader_progID = 0; - - if (gl->shader_progID == 0) - gl->shader_progID = load_default_shaders(); - - glUseProgram(gl->shader_progID); - - /* Delete old shader if one exists (changing shader) */ - if (old_shader_ID != 0) - glDeleteProgram(old_shader_ID); - - GLint vertex_coord = glGetAttribLocation(gl->shader_progID, "VertexCoord"); - if (vertex_coord != -1) { - glEnableVertexAttribArray(vertex_coord); - glVertexAttribPointer(vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); - } - - GLint tex_coord = glGetAttribLocation(gl->shader_progID, "TexCoord"); - if (tex_coord != -1) { - glEnableVertexAttribArray(tex_coord); - glVertexAttribPointer(tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat))); - } - - GLint color = glGetAttribLocation(gl->shader_progID, "Color"); - if (color != -1) { - glEnableVertexAttribArray(color); - glVertexAttribPointer(color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat))); - } - - GLint mvp_matrix = glGetUniformLocation(gl->shader_progID, "MVPMatrix"); - if (mvp_matrix != -1) { - static const GLfloat mvp[] = { - 1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f - }; - glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp); - } - - GLint frame_direction = glGetUniformLocation(gl->shader_progID, "FrameDirection"); - if (frame_direction != -1) - glUniform1i(frame_direction, 1); /* always forward */ - - gl->input_size = glGetUniformLocation(gl->shader_progID, "InputSize"); - gl->output_size = glGetUniformLocation(gl->shader_progID, "OutputSize"); - gl->texture_size = glGetUniformLocation(gl->shader_progID, "TextureSize"); - gl->frame_count = glGetUniformLocation(gl->shader_progID, "FrameCount"); -} - -/** - * @brief Initialize OpenGL context - * @return Identifiers - */ -static int -initialize_glcontext(gl_identifiers *gl) -{ - /* Vertex, texture 2d coordinates and color (white) making a quad as triangle strip */ - static const GLfloat surface[] = { - -1.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, - 1.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, - -1.f, -1.f, 0.f, 1.f, 1.f, 1.f, 1.f, 1.f, - 1.f, -1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f - }; - - glGenVertexArrays(1, &gl->vertexArrayID); - - glBindVertexArray(gl->vertexArrayID); - - glGenBuffers(1, &gl->vertexBufferID); - glBindBuffer(GL_ARRAY_BUFFER, gl->vertexBufferID); - glBufferData(GL_ARRAY_BUFFER, sizeof(surface), surface, GL_STATIC_DRAW); - - glGenTextures(1, &gl->textureID); - glBindTexture(GL_TEXTURE_2D, gl->textureID); - - static const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f }; - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, INIT_WIDTH, INIT_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - - glGenBuffers(1, &gl->unpackBufferID); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->unpackBufferID); - - void *buf_ptr = NULL; - - if (GLAD_GL_ARB_buffer_storage) { - /* Create persistent buffer for pixel transfer. */ - glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - - buf_ptr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - } else { - /* Fallback; create our own buffer. */ - buf_ptr = malloc(BUFFERBYTES * BUFFERCOUNT); - - glBufferData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_STREAM_DRAW); - } - - if (buf_ptr == NULL) - return 0; /* Most likely out of memory. */ - - /* Split the buffer area for each blit_info and set them available for use. */ - for (int i = 0; i < BUFFERCOUNT; i++) { - blit_info[i].buffer = (byte *) buf_ptr + BUFFERBYTES * i; - atomic_flag_clear(&blit_info[i].in_use); - } - - glClearColor(0.f, 0.f, 0.f, 1.f); - - apply_shaders(gl); - - return 1; -} - -/** - * @brief Clean up OpenGL context - * @param gl Identifiers from initialize - */ -static void -finalize_glcontext(gl_identifiers *gl) -{ - if (GLAD_GL_ARB_buffer_storage) - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - else - free(blit_info[0].buffer); - - glDeleteProgram(gl->shader_progID); - glDeleteBuffers(1, &gl->unpackBufferID); - glDeleteTextures(1, &gl->textureID); - glDeleteBuffers(1, &gl->vertexBufferID); - glDeleteVertexArrays(1, &gl->vertexArrayID); -} - -/** - * @brief Renders a frame and swaps the buffer - * @param gl Identifiers from initialize - */ -static void -render_and_swap(gl_identifiers *gl) -{ - static int frame_counter = 0; - - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - SDL_GL_SwapWindow(window); - - if (gl->frame_count != -1) - glUniform1i(gl->frame_count, frame_counter = (frame_counter + 1) & 1023); -} - -/** - * @brief Handle failure in OpenGL thread. - * Keeps the thread sleeping until closing. - */ -static void -opengl_fail(void) -{ - if (window != NULL) { - SDL_DestroyWindow(window); - window = NULL; - } - - const wchar_t *message = plat_get_string(IDS_2153); - const wchar_t *header = plat_get_string(IDS_2154); - MessageBox(parent, header, message, MB_OK); - - WaitForSingleObject(sync_objects.closing, INFINITE); - - _endthread(); -} - -static void __stdcall opengl_debugmsg_callback(UNUSED(GLenum source), UNUSED(GLenum type), UNUSED(GLuint id), UNUSED(GLenum severity), UNUSED(GLsizei length), const GLchar *message, UNUSED(const void *userParam)) -{ - pclog("OpenGL: %s\n", message); -} - -/** - * @brief Main OpenGL thread proc. - * - * OpenGL context should be accessed only from this single thread. - * Events are used to synchronize communication. - */ -static void -opengl_main(UNUSED(void *param)) -{ - /* Initialize COM library for this thread before SDL does so. */ - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - SDL_InitSubSystem(SDL_INIT_VIDEO); - - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); /* Is this actually doing anything...? */ - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - - if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - - window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); - - if (window == NULL) { - pclog("OpenGL: failed to create OpenGL window.\n"); - opengl_fail(); - } - - /* Keep track of certain parameters, only changed in this thread to avoid race conditions */ - int fullscreen = resize_info.fullscreen; - int video_width = INIT_WIDTH; - int video_height = INIT_HEIGHT; - int output_width = resize_info.width; - int output_height = resize_info.height; - int frametime = options.frametime; - - SDL_SysWMinfo wmi = { 0 }; - SDL_VERSION(&wmi.version); - SDL_GetWindowWMInfo(window, &wmi); - - if (wmi.subsystem != SDL_SYSWM_WINDOWS) { - pclog("OpenGL: subsystem is not SDL_SYSWM_WINDOWS.\n"); - opengl_fail(); - } - - window_hwnd = wmi.info.win.window; - - if (!fullscreen) - set_parent_binding(1); - else - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); - - SDL_GLContext context = SDL_GL_CreateContext(window); - - if (context == NULL) { - pclog("OpenGL: failed to create OpenGL context.\n"); - opengl_fail(); - } - - SDL_GL_SetSwapInterval(options.vsync); - - if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) { - pclog("OpenGL: failed to set OpenGL loader.\n"); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') { - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 0, 0, GL_FALSE); - glDebugMessageCallbackARB(opengl_debugmsg_callback, NULL); - } - - pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); - pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); - pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); - pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - /* Check that the driver actually reports version 3.0 or later */ - GLint major = -1; - glGetIntegerv(GL_MAJOR_VERSION, &major); - if (major < 3) { - pclog("OpenGL: Minimum OpenGL version 3.0 is required.\n"); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - /* Check if errors have been generated at this point */ - GLenum gl_error = glGetError(); - if (gl_error != GL_NO_ERROR) { - /* Log up to 10 errors */ - int i = 0; - do { - pclog("OpenGL: Error %u\n", gl_error); - i++; - } while ((gl_error = glGetError()) != GL_NO_ERROR && i < 10); - - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - gl_identifiers gl = { 0 }; - - if (!initialize_glcontext(&gl)) { - pclog("OpenGL: failed to initialize.\n"); - finalize_glcontext(&gl); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - if (gl.frame_count != -1) - glUniform1i(gl.frame_count, 0); - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - - uint32_t last_swap = plat_get_micro_ticks() - frametime; - - int read_pos = 0; /* Buffer index of next read operation. */ - - /* Render loop */ - int closing = 0; - while (!closing) { - /* Rendering is done right after handling an event. */ - if (frametime < 0) - render_and_swap(&gl); - - DWORD wait_result = WAIT_TIMEOUT; - - do { - /* Rendering is timed by frame capping. */ - if (frametime >= 0) { - uint32_t ticks = plat_get_micro_ticks(); - - uint32_t elapsed = ticks - last_swap; - - if (elapsed + 1000 > frametime) { - /* Spin the remaining time (< 1ms) to next frame */ - while (elapsed < frametime) { - Sleep(0); /* Yield processor time */ - ticks = plat_get_micro_ticks(); - elapsed = ticks - last_swap; - } - - render_and_swap(&gl); - last_swap = ticks; - } - } - - if (GLAD_GL_ARB_sync) { - /* Check if commands that use buffers have been completed. */ - for (int i = 0; i < BUFFERCOUNT; i++) { - if (blit_info[i].sync != NULL && glClientWaitSync(blit_info[i].sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_TIMEOUT_EXPIRED) { - glDeleteSync(blit_info[i].sync); - blit_info[i].sync = NULL; - atomic_flag_clear(&blit_info[i].in_use); - } - } - } - - /* Handle window messages */ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.hwnd != window_hwnd || !handle_window_messages(msg.message, msg.wParam, msg.lParam, fullscreen)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - /* Wait for synchronized events for 1ms before going back to window events */ - wait_result = WaitForMultipleObjects(sizeof(sync_objects) / sizeof(HANDLE), sync_objects.asArray, FALSE, 1); - - } while (wait_result == WAIT_TIMEOUT); - - const HANDLE sync_event = sync_objects.asArray[wait_result - WAIT_OBJECT_0]; - - if (sync_event == sync_objects.closing) { - closing = 1; - } else if (sync_event == sync_objects.blit_waiting) { - blit_info_t *info = &blit_info[read_pos]; - - if (video_width != info->w || video_height != info->h) { - video_width = info->w; - video_height = info->h; - - /* Resize the texture */ - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, video_width, video_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl.unpackBufferID); - - if (fullscreen) - SetEvent(sync_objects.resize); - } - - if (!GLAD_GL_ARB_buffer_storage) { - /* Fallback method, copy data to pixel buffer. */ - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->h * ROW_LENGTH * sizeof(uint32_t), info->buffer); - } - - /* Update texture from pixel buffer. */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * read_pos); - glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info->w, info->h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - - if (GLAD_GL_ARB_sync) { - /* Add fence to track when above gl commands are complete. */ - info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - } else { - /* No sync objects; block until commands are complete. */ - glFinish(); - atomic_flag_clear(&info->in_use); - } - - read_pos = (read_pos + 1) % BUFFERCOUNT; - - /* Update uniforms */ - if (gl.input_size != -1) - glUniform2f(gl.input_size, video_width, video_height); - if (gl.texture_size != -1) - glUniform2f(gl.texture_size, video_width, video_height); - } else if (sync_event == sync_objects.resize) { - thread_wait_mutex(resize_info.mutex); - - if (fullscreen != resize_info.fullscreen) { - fullscreen = resize_info.fullscreen; - - set_parent_binding(!fullscreen); - - SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - - if (fullscreen) { - SetForegroundWindow(window_hwnd); - SetFocus(window_hwnd); - - /* Clip cursor to prevent it moving to another monitor. */ - RECT rect; - GetWindowRect(window_hwnd, &rect); - ClipCursor(&rect); - } else - ClipCursor(NULL); - } - - if (fullscreen) { - int width; - int height; - int pad_x = 0; - int pad_y = 0; - int px_size = 1; - float ratio = 0; - const float ratio43 = 4.f / 3.f; - - SDL_GetWindowSize(window, &width, &height); - - if (video_width > 0 && video_height > 0) { - switch (resize_info.scaling_mode) { - case FULLSCR_SCALE_INT: - px_size = max(min(width / video_width, height / video_height), 1); - - pad_x = width - (video_width * px_size); - pad_y = height - (video_height * px_size); - break; - - case FULLSCR_SCALE_KEEPRATIO: - ratio = (float) video_width / (float) video_height; - case FULLSCR_SCALE_43: - if (ratio == 0) - ratio = ratio43; - if (ratio < ((float) width / (float) height)) - pad_x = width - (int) roundf((float) height * ratio); - else - pad_y = height - (int) roundf((float) width / ratio); - break; - - case FULLSCR_SCALE_FULL: - default: - break; - } - } - - output_width = width - pad_x; - output_height = height - pad_y; - - glViewport(pad_x / 2, pad_y / 2, output_width, output_height); - - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - } else { - SDL_SetWindowSize(window, resize_info.width, resize_info.height); - - /* SWP_NOZORDER is needed for child window and SDL doesn't enable it. */ - SetWindowPos(window_hwnd, parent, 0, 0, resize_info.width, resize_info.height, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE); - - output_width = resize_info.width; - output_height = resize_info.height; - - glViewport(0, 0, resize_info.width, resize_info.height); - - if (gl.output_size != -1) - glUniform2f(gl.output_size, resize_info.width, resize_info.height); - } - - thread_release_mutex(resize_info.mutex); - } else if (sync_event == sync_objects.reload) { - thread_wait_mutex(options.mutex); - - frametime = options.frametime; - - SDL_GL_SetSwapInterval(options.vsync); - - if (options.shaderfile_changed) { - /* Change shader program. */ - apply_shaders(&gl); - - /* Uniforms need to be updated after proram change. */ - if (gl.input_size != -1) - glUniform2f(gl.input_size, video_width, video_height); - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - if (gl.texture_size != -1) - glUniform2f(gl.texture_size, video_width, video_height); - if (gl.frame_count != -1) - glUniform1i(gl.frame_count, 0); - - options.shaderfile_changed = 0; - } - - if (options.filter_changed) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - - options.filter_changed = 0; - } - - thread_release_mutex(options.mutex); - } - - /* Keep cursor hidden in full screen and mouse capture */ - int show_cursor = !(fullscreen || !!mouse_capture); - if (SDL_ShowCursor(-1) != show_cursor) - SDL_ShowCursor(show_cursor); - } - - if (GLAD_GL_ARB_sync) { - for (int i = 0; i < BUFFERCOUNT; i++) { - if (blit_info[i].sync != NULL) - glDeleteSync(blit_info[i].sync); - } - } - - finalize_glcontext(&gl); - - SDL_GL_DeleteContext(context); - - set_parent_binding(0); - - SDL_DestroyWindow(window); - - window = NULL; - - CoUninitialize(); -} - -static void -opengl_blit(int x, int y, int w, int h, int monitor_index) -{ - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (thread == NULL) || atomic_flag_test_and_set(&blit_info[write_pos].in_use) || monitor_index >= 1) { - video_blit_complete_monitor(monitor_index); - return; - } - - for (int row = 0; row < h; ++row) - video_copy(&(((uint8_t *) blit_info[write_pos].buffer)[row * ROW_LENGTH * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH); - - video_blit_complete(); - - blit_info[write_pos].w = w; - blit_info[write_pos].h = h; - - write_pos = (write_pos + 1) % BUFFERCOUNT; - - ReleaseSemaphore(sync_objects.blit_waiting, 1, NULL); -} - -static int -framerate_to_frametime(int framerate) -{ - if (framerate < 0) - return -1; - - return (int) ceilf(1.e6f / (float) framerate); -} - -int -opengl_init(HWND hwnd) -{ - if (thread != NULL) - return 0; - - for (int i = 0; i < sizeof(sync_objects) / sizeof(HANDLE); i++) - sync_objects.asArray[i] = CreateEvent(NULL, FALSE, FALSE, NULL); - - sync_objects.closing = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.resize = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.reload = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.blit_waiting = CreateSemaphore(NULL, 0, BUFFERCOUNT * 2, NULL); - - parent = hwnd; - - RECT parent_size; - - GetWindowRect(parent, &parent_size); - - resize_info.width = parent_size.right - parent_size.left; - resize_info.height = parent_size.bottom - parent_size.top; - resize_info.fullscreen = video_fullscreen & 1; - resize_info.scaling_mode = video_fullscreen_scale; - resize_info.mutex = thread_create_mutex(); - - options.vsync = video_vsync; - options.frametime = framerate_to_frametime(video_framerate); - strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader); - options.shaderfile_changed = 0; - options.filter = video_filter_method; - options.filter_changed = 0; - options.mutex = thread_create_mutex(); - - blit_info = (blit_info_t *) malloc(BUFFERCOUNT * sizeof(blit_info_t)); - memset(blit_info, 0, BUFFERCOUNT * sizeof(blit_info_t)); - - /* Buffers are not yet allocated, set them as in use. */ - for (int i = 0; i < BUFFERCOUNT; i++) - atomic_flag_test_and_set(&blit_info[i].in_use); - - write_pos = 0; - - thread = thread_create(opengl_main, NULL); - - atexit(opengl_close); - - video_setblit(opengl_blit); - - return 1; -} - -int -opengl_pause(void) -{ - return 0; -} - -void -opengl_close(void) -{ - if (thread == NULL) - return; - - SetEvent(sync_objects.closing); - - thread_wait(thread); - - thread_close_mutex(resize_info.mutex); - thread_close_mutex(options.mutex); - - thread = NULL; - - free(blit_info); - - for (int i = 0; i < sizeof(sync_objects) / sizeof(HANDLE); i++) { - CloseHandle(sync_objects.asArray[i]); - sync_objects.asArray[i] = NULL; - } - - parent = NULL; -} - -void -opengl_set_fs(int fs) -{ - if (thread == NULL) - return; - - thread_wait_mutex(resize_info.mutex); - - resize_info.fullscreen = fs; - resize_info.scaling_mode = video_fullscreen_scale; - - thread_release_mutex(resize_info.mutex); - - SetEvent(sync_objects.resize); -} - -void -opengl_resize(int w, int h) -{ - if (thread == NULL) - return; - - thread_wait_mutex(resize_info.mutex); - - resize_info.width = w; - resize_info.height = h; - resize_info.scaling_mode = video_fullscreen_scale; - - thread_release_mutex(resize_info.mutex); - - SetEvent(sync_objects.resize); -} - -void -opengl_reload(void) -{ - if (thread == NULL) - return; - - thread_wait_mutex(options.mutex); - - options.vsync = video_vsync; - options.frametime = framerate_to_frametime(video_framerate); - - if (strcmp(video_shader, options.shaderfile) != 0) { - strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader); - options.shaderfile_changed = 1; - } - - if (video_filter_method != options.filter) { - options.filter = video_filter_method; - options.filter_changed = 1; - } - - thread_release_mutex(options.mutex); - - SetEvent(sync_objects.reload); -} diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c deleted file mode 100644 index 9689f3ab2..000000000 --- a/src/win/win_opengl_glslp.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * 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. - * - * File parser for .glslp and .glsl shader files - * in the format of libretro. - * - * TODO: Read .glslp files for multipass shaders and settings. - * - * - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include - -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/win_opengl_glslp.h> - -/** - * @brief Default vertex shader. - */ -static const GLchar *vertex_shader = "#version 130\n\ -in vec2 VertexCoord;\n\ -in vec2 TexCoord;\n\ -out vec2 tex;\n\ -void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ -}\n"; - -/** - * @brief Default fragment shader. - */ -static const GLchar *fragment_shader = "#version 130\n\ -in vec2 tex;\n\ -uniform sampler2D texsampler;\n\ -out vec4 color;\n\ -void main() {\n\ - color = texture(texsampler, tex);\n\ -}\n"; - -/** - * @brief OpenGL shader program build targets - */ -typedef enum { - OPENGL_BUILD_TARGET_VERTEX, - OPENGL_BUILD_TARGET_FRAGMENT, - OPENGL_BUILD_TARGET_LINK -} opengl_build_target_t; - -/** - * @brief Reads a whole file into a null terminated string. - * @param Path Path to the file relative to executable path. - * @return Pointer to the string or NULL on error. Remember to free() after use. - */ -static char * -read_file_to_string(const char *path) -{ - FILE *fp = plat_fopen(path, "rb"); - - if (fp != NULL) { - /* get file size */ - fseek(fp, 0, SEEK_END); - - size_t file_size = (size_t) ftell(fp); - - fseek(fp, 0, SEEK_SET); - - /* read to buffer and close */ - char *content = (char *) malloc(sizeof(char) * (file_size + 1)); - - if (!content) - return NULL; - - size_t length = fread(content, sizeof(char), file_size, fp); - - fclose(fp); - - content[length] = 0; - - return content; - } - return NULL; -} - -static int -check_status(GLuint id, opengl_build_target_t build_target, const char *shader_path) -{ - GLint status = GL_FALSE; - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderiv(id, GL_COMPILE_STATUS, &status); - else - glGetProgramiv(id, GL_LINK_STATUS, &status); - - if (status == GL_FALSE) { - int info_log_length; - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length); - else - glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length); - - GLchar *info_log_text = (GLchar *) malloc(sizeof(GLchar) * info_log_length); - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderInfoLog(id, info_log_length, NULL, info_log_text); - else - glGetProgramInfoLog(id, info_log_length, NULL, info_log_text); - - const char *reason = NULL; - - switch (build_target) { - case OPENGL_BUILD_TARGET_VERTEX: - reason = "compiling vertex shader"; - break; - case OPENGL_BUILD_TARGET_FRAGMENT: - reason = "compiling fragment shader"; - break; - case OPENGL_BUILD_TARGET_LINK: - reason = "linking shader program"; - break; - } - - /* Shader compilation log can be lengthy, mark begin and end */ - const char *line = "--------------------"; - - pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line); - - free(info_log_text); - - return 0; - } - - return 1; -} - -/** - * @brief Compile custom shaders into a program. - * @return Shader program identifier. - */ -GLuint -load_custom_shaders(const char *path) -{ - char *shader = read_file_to_string(path); - - if (shader != NULL) { - int success = 1; - - const char *vertex_sources[3] = { "#version 130\n", "#define VERTEX\n", shader }; - const char *fragment_sources[3] = { "#version 130\n", "#define FRAGMENT\n", shader }; - - /* Check if the shader program defines version directive */ - char *version_start = strstr(shader, "#version"); - - /* If the shader program contains a version directive, - it must be captured and placed as the first statement. */ - if (version_start != NULL) { - /* Version directive found, search the line end */ - const char *version_end = strchr(version_start, '\n'); - - if (version_end != NULL) { - char version[30] = ""; - - size_t version_len = MIN(version_end - version_start + 1, 29); - - strncat(version, version_start, version_len); - - /* replace the default version directive */ - vertex_sources[0] = version; - fragment_sources[0] = version; - } - - /* Comment out the original version directive - as only one is allowed. */ - memset(version_start, '/', 2); - } - - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 3, vertex_sources, NULL); - glCompileShader(vertex_id); - success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path); - - glShaderSource(fragment_id, 3, fragment_sources, NULL); - glCompileShader(fragment_id); - success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path); - - free(shader); - - GLuint prog_id = 0; - - if (success) { - prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - glLinkProgram(prog_id); - check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path); - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - } - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; - } - return 0; -} - -/** - * @brief Compile default shaders into a program. - * @return Shader program identifier. - */ -GLuint -load_default_shaders(void) -{ - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 1, &vertex_shader, NULL); - glCompileShader(vertex_id); - - glShaderSource(fragment_id, 1, &fragment_shader, NULL); - glCompileShader(fragment_id); - - GLuint prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - - glLinkProgram(prog_id); - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; -} diff --git a/src/win/win_preferences.c b/src/win/win_preferences.c deleted file mode 100644 index ee93321a8..000000000 --- a/src/win/win_preferences.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 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. - * - * Handle the dialog for changing the program's language and other global settings. - * - * - * - * Authors: Laci bá' - * - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/sound.h> -#include <86box/win.h> -#include <86box/ui.h> -#include <86box/resource.h> - -/* Language */ -static LCID temp_language; - -static char temp_icon_set[256] = { 0 }; - -int enum_helper; -int c; - -HWND hwndPreferences; - -BOOL CALLBACK -EnumResLangProc(UNUSED(HMODULE hModule), UNUSED(LPCTSTR lpszType), UNUSED(LPCTSTR lpszName), WORD wIDLanguage, LONG_PTR lParam) -{ - wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1]; - LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0); - wchar_t dispname[MAX_PATH + 1]; - GetLocaleInfoEx(temp, LOCALE_SENGLISHDISPLAYNAME, dispname, MAX_PATH); - SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) dispname); - SendMessage((HWND) lParam, CB_SETITEMDATA, c, (LPARAM) wIDLanguage); - - if (wIDLanguage == lang_id) - enum_helper = c; - c++; - - return 1; -} - -/* Load available languages */ -static void -preferences_fill_languages(HWND hdlg) -{ - temp_language = GetThreadUILanguage(); - HWND lang_combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - - SendMessage(lang_combo, CB_RESETCONTENT, 0, 0); - SendMessage(lang_combo, CB_ADDSTRING, 0, win_get_string(IDS_7168)); - SendMessage(lang_combo, CB_SETITEMDATA, 0, 0xFFFF); - - enum_helper = 0; - c = 1; - // if no one is selected, then it was 0xFFFF or unsupported language, in either case go with index enum_helper=0 - // also start enum index from c=1 - EnumResourceLanguages(hinstance, RT_MENU, L"MainMenu", &EnumResLangProc, (LPARAM) lang_combo); - - SendMessage(lang_combo, CB_SETCURSEL, enum_helper, 0); -} - -/* Load available iconsets */ -static void -preferences_fill_iconsets(HWND hdlg) -{ - HWND icon_combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - - /* Add the default one */ - wchar_t buffer[512] = L"("; - wcscat(buffer, plat_get_string(IDS_DEFAULT)); - wcscat(buffer, L")"); - - SendMessage(icon_combo, CB_RESETCONTENT, 0, 0); - SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) buffer); - SendMessage(icon_combo, CB_SETITEMDATA, 0, (LPARAM) strdup("")); - - int combo_index = -1; - - /* Find for extra ones */ - HANDLE hFind; - WIN32_FIND_DATA data; - - char icon_path_root[512]; - win_get_icons_path(icon_path_root); - - wchar_t search[512]; - mbstoc16s(search, icon_path_root, strlen(icon_path_root) + 1); - wcscat(search, L"*.*"); - - hFind = FindFirstFile((LPCWSTR) search, &data); - - if (hFind != INVALID_HANDLE_VALUE) { - do { - if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..") && (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - wchar_t temp[512] = { 0 }; - wchar_t dispname[512] = { 0 }; - mbstoc16s(temp, icon_path_root, strlen(icon_path_root) + 1); - wcscat(temp, data.cFileName); - wcscat(temp, L"\\iconinfo.txt"); - - wcscpy(dispname, data.cFileName); - FILE *fp = _wfopen(temp, L"r"); - if (fp) { - char line[512] = { 0 }; - if (fgets(line, 511, fp)) { - mbstoc16s(dispname, line, strlen(line) + 1); - } - - fclose(fp); - } - - char filename[512]; - c16stombs(filename, data.cFileName, 511); - - int index = SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) dispname); - SendMessage(icon_combo, CB_SETITEMDATA, index, (LPARAM) (strdup(filename))); - - if (!strcmp(filename, icon_set)) - combo_index = index; - } - } while (FindNextFile(hFind, &data)); - FindClose(hFind); - } - - if (combo_index == -1) { - combo_index = 0; - strcpy(temp_icon_set, ""); - } - - SendMessage(icon_combo, CB_SETCURSEL, combo_index, 0); -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int -preferences_settings_changed(void) -{ - int i = 0; - - /* Language */ - i = i || has_language_changed(temp_language); - i = i || strcmp(temp_icon_set, icon_set); - - return i; -} - -/* IndexOf by ItemData */ -static int -preferences_indexof(HWND combo, LPARAM itemdata) -{ - for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) - if (SendMessage(combo, CB_GETITEMDATA, i, 0) == itemdata) - return i; - - return -1; -} - -/* This saves the settings back to the global variables. */ -static void -preferences_settings_save(void) -{ - /* Language */ - set_language(temp_language); - - /* Iconset */ - strcpy(icon_set, temp_icon_set); - win_load_icon_set(); - - /* Update title bar */ - update_mouse_msg(); - - /* Update status bar */ - config_changed = 1; - ui_sb_set_ready(-1); - ui_sb_update_panes(); - ui_sb_update_text(); - - /* Save the language changes */ - config_save(); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - switch (message) { - case WM_INITDIALOG: - hwndPreferences = hdlg; - /* Language */ - temp_language = lang_id; - strcpy(temp_icon_set, icon_set); - preferences_fill_languages(hdlg); - preferences_fill_iconsets(hdlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (preferences_settings_changed()) - preferences_settings_save(); - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - case IDC_COMBO_LANG: - if (HIWORD(wParam) == CBN_SELCHANGE) { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - int index = SendMessage(combo, CB_GETCURSEL, 0, 0); - temp_language = SendMessage(combo, CB_GETITEMDATA, index, 0); - } - break; - - case IDC_COMBO_ICON: - if (HIWORD(wParam) == CBN_SELCHANGE) { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - int index = SendMessage(combo, CB_GETCURSEL, 0, 0); - strcpy(temp_icon_set, (char *) SendMessage(combo, CB_GETITEMDATA, index, 0)); - } - break; - - case IDC_BUTTON_DEFAULT: - { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - int index = preferences_indexof(combo, DEFAULT_LANGUAGE); - SendMessage(combo, CB_SETCURSEL, index, 0); - temp_language = DEFAULT_LANGUAGE; - break; - } - - case IDC_BUTTON_DEFICON: - { - SendMessage(GetDlgItem(hdlg, IDC_COMBO_ICON), CB_SETCURSEL, 0, 0); - strcpy(temp_icon_set, ""); - break; - } - default: - break; - } - break; - - case WM_DESTROY: - { - LRESULT temp; - HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) { - temp = SendMessage(combo, CB_GETITEMDATA, i, 0); - if (temp) { - free((void *) temp); - SendMessage(combo, CB_SETITEMDATA, i, 0); - } - } - } - break; - } - - return FALSE; -} - -void -PreferencesDlgCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_PREFERENCES, hwnd, PreferencesDlgProcedure); -} diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c deleted file mode 100644 index ea9c8455d..000000000 --- a/src/win/win_sdl.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * 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. - * - * Rendering module for libSDL2 - * - * NOTE: Given all the problems reported with FULLSCREEN use of SDL, - * we will not use that, but, instead, use a new window which - * covers the entire desktop. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2020 Fred N. van Kempen. - * Copyright 2018-2020 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#define UNICODE -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#include -#include -#include -#include -/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ -#undef HAVE_STDARG_H -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/video.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/win_sdl.h> -#include <86box/version.h> - -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 - -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static HWND sdl_parent_hwnd = NULL; -static int sdl_w; -static int sdl_h; -static int sdl_fs; -static int sdl_flags = -1; -static int cur_w; -static int cur_h; -static int cur_wx = 0; -static int cur_wy = 0; -static int cur_ww = 0; -static int cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex *sdl_mutex = NULL; - -typedef struct -{ - const void *magic; - Uint32 id; - char *title; - SDL_Surface *icon; - int x, y; - int w, h; - int min_w, min_h; - int max_w, max_h; - Uint32 flags; - Uint32 last_fullscreen_flags; - - /* Stored position and size for windowed mode */ - SDL_Rect windowed; - - SDL_DisplayMode fullscreen_mode; - - float brightness; - Uint16 *gamma; - Uint16 *saved_gamma; /* (just offset into gamma) */ - - SDL_Surface *surface; - SDL_bool surface_valid; - - SDL_bool is_hiding; - SDL_bool is_destroying; - - void *shaper; - - SDL_HitTest hit_test; - void *hit_test_data; - - void *data; - - void *driverdata; - - SDL_Window *prev; - SDL_Window *next; -} SDL_Window_Ex; - -#ifdef ENABLE_SDL_LOG -int sdl_do_log = ENABLE_SDL_LOG; - -static void -sdl_log(const char *fmt, ...) -{ - va_list ap; - - if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define sdl_log(fmt, ...) -#endif - -static void -sdl_integer_scale(double *d, double *g) -{ - double ratio; - - if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; - } else { - ratio = ceil(*d / *g); - *d = *g / ratio; - } -} - -static void -sdl_stretch(int *w, int *h, int *x, int *y) -{ - double hw; - double gw; - double hh; - double gh; - double dx; - double dy; - double dw; - double dh; - double gsr; - double hsr; - - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; - hsr = hw / hh; - - switch (video_fullscreen_scale) { - default: - case FULLSCR_SCALE_FULL: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - } -} - -static void -sdl_blit(int x, int y, int w, int h, int monitor_index) -{ - SDL_Rect r_src; - int ret; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL) || monitor_index >= 1) { - video_blit_complete_monitor(monitor_index); - return; - } - - SDL_LockMutex(sdl_mutex); - - r_src.x = x; - r_src.y = y; - r_src.w = w; - r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), 2048 * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot(buffer32->dat, x, y, 2048); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = x; - r_src.y = y; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); - - SDL_RenderPresent(sdl_render); - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_blit_ex(int x, int y, int w, int h, UNUSED(int monitor_index)) -{ - SDL_Rect r_src; - void *pixeldata; - int pitch; - int ret; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { - video_blit_complete(); - return; - } - - SDL_LockMutex(sdl_mutex); - - SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - - for (int row = 0; row < h; ++row) - video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); - - SDL_UnlockTexture(sdl_tex); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = 0; - r_src.y = 0; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); - - SDL_RenderPresent(sdl_render); - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_destroy_window(void) -{ - if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; - } -} - -static void -sdl_destroy_texture(void) -{ - if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; - } - - /* SDL_DestroyRenderer also automatically destroys all associated textures. */ - if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; - } -} - -void -sdl_close(void) -{ - if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); - - /* Unregister our renderer! */ - video_setblit(NULL); - - if (sdl_enabled) - sdl_enabled = 0; - - if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; - } - - sdl_destroy_texture(); - sdl_destroy_window(); - ImmAssociateContext(hwndMain, NULL); - SetFocus(hwndMain); - - if (sdl_parent_hwnd != NULL) { - DestroyWindow(sdl_parent_hwnd); - sdl_parent_hwnd = NULL; - } - - /* Quit. */ - SDL_Quit(); - sdl_flags = -1; -} - -static int old_capture = 0; - -static void -sdl_select_best_hw_driver(void) -{ - SDL_RendererInfo renderInfo; - - for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (renderInfo.flags & SDL_RENDERER_ACCELERATED) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name); - return; - } - } -} - -static void -sdl_init_texture(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - } else - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); -} - -static void -sdl_reinit_texture(void) -{ - if (sdl_flags == -1) - return; - - sdl_destroy_texture(); - sdl_init_texture(); -} - -void -sdl_set_fs(int fs) -{ - int w = 0; - int h = 0; - int x = 0; - int y = 0; - RECT rect; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = 0; - - if (fs) { - ShowWindow(sdl_parent_hwnd, TRUE); - SetParent(hwndRender, sdl_parent_hwnd); - ShowWindow(hwndRender, TRUE); - MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE); - - /* Show the window, make it topmost, and give it focus. */ - w = unscaled_size_x; - h = efscrnsz_y; - sdl_stretch(&w, &h, &x, &y); - MoveWindow(hwndRender, x, y, w, h, TRUE); - ImmAssociateContext(sdl_parent_hwnd, NULL); - SetFocus(sdl_parent_hwnd); - - /* Redirect RawInput to this new window. */ - old_capture = mouse_capture; - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - mouse_capture = 1; - } else { - SetParent(hwndRender, hwndMain); - ShowWindow(sdl_parent_hwnd, FALSE); - ShowWindow(hwndRender, TRUE); - ImmAssociateContext(hwndMain, NULL); - SetFocus(hwndMain); - mouse_capture = old_capture; - - if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - } else - ClipCursor(&oldclip); - } - - sdl_fs = fs; - - if (fs) - sdl_flags |= RENDERER_FULL_SCREEN; - else - sdl_flags &= ~RENDERER_FULL_SCREEN; - -#if 0 - sdl_reinit_texture(); -#endif - sdl_enabled = 1; - SDL_UnlockMutex(sdl_mutex); -} - -static int -sdl_init_common(int flags) -{ - wchar_t temp[128]; - SDL_version ver; - - sdl_log("SDL: init (flags=%d)\n", flags); - - /* Get and log the version of the DLL we are using. */ - SDL_GetVersion(&ver); - sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); - - /* Initialize the SDL system. */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return 0; - } - - if (flags & RENDERER_HARDWARE) { - if (flags & RENDERER_OPENGL) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); - else - sdl_select_best_hw_driver(); - } - - /* Get the size of the (current) desktop. */ - sdl_w = GetSystemMetrics(SM_CXSCREEN); - sdl_h = GetSystemMetrics(SM_CYSCREEN); - - /* Create the desktop-covering window. */ - _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_FULL_W); - sdl_parent_hwnd = CreateWindow(SDL_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h, - HWND_DESKTOP, NULL, hinstance, NULL); - ShowWindow(sdl_parent_hwnd, FALSE); - - sdl_flags = flags; - - if (sdl_win == NULL) { - sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); - } - - sdl_win = SDL_CreateWindowFrom((void *) hwndRender); - sdl_init_texture(); - sdl_set_fs(video_fullscreen & 1); - - /* Make sure we get a clean exit. */ - atexit(sdl_close); - - /* Register our renderer! */ - video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit); - - sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); - - return 1; -} - -int -sdl_inits(UNUSED(HWND h)) -{ - return sdl_init_common(0); -} - -int -sdl_inith(UNUSED(HWND h)) -{ - return sdl_init_common(RENDERER_HARDWARE); -} - -int -sdl_initho(UNUSED(HWND h)) -{ - return sdl_init_common(RENDERER_HARDWARE | RENDERER_OPENGL); -} - -int -sdl_pause(void) -{ - return 0; -} - -void -sdl_resize(int x, int y) -{ - int ww = 0; - int wh = 0; - int wx = 0; - int wy = 0; - - if (video_fullscreen & 2) - return; - - if ((x == cur_w) && (y == cur_h)) - return; - - SDL_LockMutex(sdl_mutex); - - ww = x; - wh = y; - - if (sdl_fs) { - sdl_stretch(&ww, &wh, &wx, &wy); - MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); - } - - cur_w = x; - cur_h = y; - - cur_wx = wx; - cur_wy = wy; - cur_ww = ww; - cur_wh = wh; - - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy); - - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_enable(int enable) -{ - if (sdl_flags == -1) - return; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = !!enable; - - if (enable == 1) { - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - } - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_reload(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); - } - - video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit); -} diff --git a/src/win/win_settings.c b/src/win/win_settings.c deleted file mode 100644 index 139c387a8..000000000 --- a/src/win/win_settings.c +++ /dev/null @@ -1,5708 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows 86Box Settings dialog handler. - * - * - * - * Authors: Miran Grca, - * David Hrdlička, - * Jasmine Iwanek, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#undef BITMAP -#ifdef ENABLE_SETTINGS_LOG -# include -#endif -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include "cpu.h" -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/nvr.h> -#include <86box/machine.h> -#include <86box/gameport.h> -#include <86box/isamem.h> -#include <86box/isartc.h> -#include <86box/lpt.h> -#include <86box/mouse.h> -#include <86box/serial.h> -#include <86box/scsi.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/hdd.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/zip.h> -#include <86box/mo.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/fdc_ext.h> -#include <86box/thread.h> -#include <86box/network.h> -#include <86box/sound.h> -#include <86box/midi.h> -#include <86box/snd_mpu401.h> -#include <86box/snd_opl.h> -#include <86box/video.h> -#include <86box/vid_xga_device.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/serial_passthrough.h> -#include "../disk/minivhd/minivhd.h" - -/* Icon, Bus, File, C, H, S, Size, Speed */ -#define C_COLUMNS_HARD_DISKS 7 - -#define C_COLUMNS_FLOPPY_DRIVES 3 -#define C_COLUMNS_CDROM_DRIVES 3 -#define C_COLUMNS_MO_DRIVES 2 -#define C_COLUMNS_ZIP_DRIVES 2 - -static int first_cat = 0; - -/* Machine category */ -static int temp_machine_type; -static int temp_machine; -static int temp_cpu; -static int temp_wait_states; -static int temp_fpu; -static int temp_sync; -static cpu_family_t *temp_cpu_f; -static uint32_t temp_mem_size; -#ifdef USE_DYNAREC -static int temp_dynarec; -#endif -static int temp_fpu_softfloat; - -/* Video category */ -static int temp_gfxcard[2]; -static int temp_ibm8514; -static int temp_voodoo; -static int temp_xga; - -/* Input devices category */ -static int temp_mouse; -static int temp_joystick; - -/* Sound category */ -static int temp_sound_card[SOUND_CARD_MAX]; -static int temp_midi_output_device; -static int temp_midi_input_device; -static int temp_mpu401; -static int temp_float; -static int temp_fm_driver; - -/* Network category */ -static int temp_net_type[NET_CARD_MAX]; -static uint16_t temp_net_card[NET_CARD_MAX]; -static char temp_pcap_dev[NET_CARD_MAX][128]; - -/* Ports category */ -static int temp_lpt_devices[PARALLEL_MAX]; -static uint8_t temp_serial[SERIAL_MAX]; -static uint8_t temp_lpt[PARALLEL_MAX]; -static int temp_serial_passthrough_enabled[SERIAL_MAX]; - -/* Other peripherals category */ -static int temp_fdc_card; -static int temp_hdc; -static int temp_ide_ter; -static int temp_ide_qua; -static int temp_cassette; -static int temp_scsi_card[SCSI_BUS_MAX]; -static int temp_bugger; -static int temp_postcard; -static int temp_isartc; -static int temp_isamem[ISAMEM_MAX]; - -static uint8_t temp_deviceconfig; - -/* Hard disks category */ -static hard_disk_t temp_hdd[HDD_NUM]; - -/* Floppy drives category */ -static int temp_fdd_types[FDD_NUM]; -static int temp_fdd_turbo[FDD_NUM]; -static int temp_fdd_check_bpb[FDD_NUM]; - -/* Other removable devices category */ -static cdrom_t temp_cdrom[CDROM_NUM]; -static zip_drive_t temp_zip_drives[ZIP_NUM]; -static mo_drive_t temp_mo_drives[MO_NUM]; - -static HWND hwndParentDialog; -static HWND hwndChildDialog; - -static uint32_t displayed_category = 0; - -extern int is486; -static int listtomachinetype[256]; -static int listtomachine[256]; -static int listtocpufamily[256]; -static int listtocpu[256]; -static int settings_list_to_device[2][256]; -static int settings_list_to_fdc[20]; -static int settings_list_to_midi[20]; -static int settings_list_to_midi_in[20]; -static int settings_list_to_hdc[20]; - -static int max_spt = 63; -static int max_hpc = 255; -static int max_tracks = 266305; -static uint64_t mfm_tracking; -static uint64_t esdi_tracking; -static uint64_t xta_tracking; -static uint64_t ide_tracking; -static uint64_t scsi_tracking[8]; -static uint64_t size; -static int hd_listview_items; -static int hdc_id_to_listview_index[HDD_NUM]; -static int no_update = 0; -static int existing = 0; -static int chs_enabled = 0; -static int lv1_current_sel; -static int lv2_current_sel; -static int hard_disk_added = 0; -static int next_free_id = 0; -static int selection = 127; -static int spt; -static int hpc; -static int tracks; -static int ignore_change = 0; - -static hard_disk_t new_hdd; -static hard_disk_t *hdd_ptr; - -static wchar_t hd_file_name[512]; -static WCHAR device_name[512]; - -static int -settings_get_check(HWND hdlg, int id) -{ - return SendMessage(GetDlgItem(hdlg, id), BM_GETCHECK, 0, 0); -} - -static int -settings_get_cur_sel(HWND hdlg, int id) -{ - return SendMessage(GetDlgItem(hdlg, id), CB_GETCURSEL, 0, 0); -} - -static void -settings_set_check(HWND hdlg, int id, int val) -{ - SendMessage(GetDlgItem(hdlg, id), BM_SETCHECK, val, 0); -} - -static void -settings_set_cur_sel(HWND hdlg, int id, int val) -{ - SendMessage(GetDlgItem(hdlg, id), CB_SETCURSEL, val, 0); -} - -static void -settings_reset_content(HWND hdlg, int id) -{ - SendMessage(GetDlgItem(hdlg, id), CB_RESETCONTENT, 0, 0); -} - -static void -settings_add_string(HWND hdlg, int id, LPARAM string) -{ - SendMessage(GetDlgItem(hdlg, id), CB_ADDSTRING, 0, string); -} - -static void -settings_enable_window(HWND hdlg, int id, int condition) -{ - EnableWindow(GetDlgItem(hdlg, id), condition ? TRUE : FALSE); -} - -static void -settings_show_window(HWND hdlg, int id, int condition) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - EnableWindow(h, condition ? TRUE : FALSE); - ShowWindow(h, condition ? SW_SHOW : SW_HIDE); -} - -static void -settings_listview_enable_styles(HWND hdlg, int id) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - SetWindowTheme(h, L"Explorer", NULL); - ListView_SetExtendedListViewStyle(h, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); -} - -static void -settings_listview_select(HWND hdlg, int id, int selection) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - ListView_SetItemState(h, selection, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); -} - -static void -settings_process_messages(void) -{ - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -static BOOL -image_list_init(HWND hdlg, int id, const uint8_t *icon_ids) -{ - HICON hiconItem; - HIMAGELIST hSmall; - HWND hwndList = GetDlgItem(hdlg, id); - - int i = 0; - - hSmall = ListView_GetImageList(hwndList, LVSIL_SMALL); - if (hSmall != 0) - ImageList_Destroy(hSmall); - - hSmall = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi), - win_get_system_metrics(SM_CYSMICON, dpi), - ILC_MASK | ILC_COLOR32, 1, 1); - - while (1) { - if (icon_ids[i] == 0) - break; - - hiconItem = hIcon[icon_ids[i]]; - ImageList_AddIcon(hSmall, hiconItem); - - i++; - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -settings_msgbox_header(int flags, void *header, void *message) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwndParentDialog; - - i = ui_msgbox_header(flags, header, message); - - hwndMain = h; - - return i; -} - -static int -settings_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwndParentDialog; - - i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); - - hwndMain = h; - - return i; -} - -/* This does the initial read of global variables into the temporary ones. */ -static void -win_settings_init(void) -{ - int i = 0; - - /* Machine category */ - temp_machine_type = machine_get_type(machine); - temp_machine = machine; - temp_cpu_f = cpu_f; - temp_wait_states = cpu_waitstates; - temp_cpu = cpu; - temp_mem_size = mem_size; -#ifdef USE_DYNAREC - temp_dynarec = cpu_use_dynarec; -#endif - temp_fpu_softfloat = fpu_softfloat; - temp_fpu = fpu_type; - temp_sync = time_sync; - - /* Video category */ - temp_gfxcard[0] = gfxcard[0]; - temp_gfxcard[1] = gfxcard[1]; - temp_voodoo = voodoo_enabled; - temp_ibm8514 = ibm8514_standalone_enabled; - temp_xga = xga_standalone_enabled; - - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; - - /* Sound category */ - for (i = 0; i < SOUND_CARD_MAX; i++) - temp_sound_card[i] = sound_card_current[i]; - temp_midi_output_device = midi_output_device_current; - temp_midi_input_device = midi_input_device_current; - temp_mpu401 = mpu401_standalone_enable; - temp_float = sound_is_float; - temp_fm_driver = fm_driver; - - /* Network category */ - for (i = 0; i < NET_CARD_MAX; i++) { - temp_net_type[i] = net_cards_conf[i].net_type; - memset(temp_pcap_dev[i], 0, sizeof(temp_pcap_dev[i])); -#ifdef ENABLE_SETTINGS_LOG - assert(sizeof(temp_pcap_dev[i]) == sizeof(net_cards_conf[i].host_dev_name)); -#endif - memcpy(temp_pcap_dev[i], net_cards_conf[i].host_dev_name, sizeof(net_cards_conf[i].host_dev_name)); - temp_net_card[i] = net_cards_conf[i].device_num; - } - - /* Ports category */ - for (i = 0; i < PARALLEL_MAX; i++) { - temp_lpt_devices[i] = lpt_ports[i].device; - temp_lpt[i] = lpt_ports[i].enabled; - } - for (i = 0; i < SERIAL_MAX; i++) { - temp_serial[i] = com_ports[i].enabled; - temp_serial_passthrough_enabled[i] = serial_passthrough_enabled[i]; - } - - /* Storage devices category */ - for (i = 0; i < SCSI_BUS_MAX; i++) - temp_scsi_card[i] = scsi_card_current[i]; - temp_fdc_card = fdc_type; - temp_hdc = hdc_current; - temp_ide_ter = ide_ter_enabled; - temp_ide_qua = ide_qua_enabled; - temp_cassette = cassette_enable; - - mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; - for (i = 0; i < SCSI_LUN_MAX; i++) - scsi_tracking[i] = 0; - - /* Hard disks category */ - memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == HDD_BUS_MFM) - mfm_tracking |= (1 << (hdd[i].mfm_channel << 3)); - else if (hdd[i].bus == HDD_BUS_XTA) - xta_tracking |= (1 << (hdd[i].xta_channel << 3)); - else if (hdd[i].bus == HDD_BUS_ESDI) - esdi_tracking |= (1 << (hdd[i].esdi_channel << 3)); - else if ((hdd[i].bus == HDD_BUS_IDE) || (hdd[i].bus == HDD_BUS_ATAPI)) - ide_tracking |= (1 << (hdd[i].ide_channel << 3)); - else if (hdd[i].bus == HDD_BUS_SCSI) - scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3)); - } - - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) { - temp_fdd_types[i] = fdd_get_type(i); - temp_fdd_turbo[i] = fdd_get_turbo(i); - temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); - } - - /* Other removable devices category */ - memcpy(temp_cdrom, cdrom, CDROM_NUM * sizeof(cdrom_t)); - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom[i].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (cdrom[i].ide_channel << 3)); - else if (cdrom[i].bus_type == CDROM_BUS_SCSI) - scsi_tracking[cdrom[i].scsi_device_id >> 3] |= (1 << ((cdrom[i].scsi_device_id & 0x07) << 3)); - } - memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (4 << (zip_drives[i].ide_channel << 3)); - else if (zip_drives[i].bus_type == ZIP_BUS_SCSI) - scsi_tracking[zip_drives[i].scsi_device_id >> 3] |= (1 << ((zip_drives[i].scsi_device_id & 0x07) << 3)); - } - memcpy(temp_mo_drives, mo_drives, MO_NUM * sizeof(mo_drive_t)); - for (i = 0; i < MO_NUM; i++) { - if (mo_drives[i].bus_type == MO_BUS_ATAPI) - ide_tracking |= (1 << (mo_drives[i].ide_channel << 3)); - else if (mo_drives[i].bus_type == MO_BUS_SCSI) - scsi_tracking[mo_drives[i].scsi_device_id >> 3] |= (1 << ((mo_drives[i].scsi_device_id & 0x07) << 3)); - } - - /* Other peripherals category */ - temp_bugger = bugger_enabled; - temp_postcard = postcard_enabled; - temp_isartc = isartc_type; - - /* ISA memory boards. */ - for (i = 0; i < ISAMEM_MAX; i++) - temp_isamem[i] = isamem_type[i]; - - temp_deviceconfig = 0; -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int -win_settings_changed(void) -{ - int i = 0; - - /* Machine category */ - i = i || (machine != temp_machine); - i = i || (cpu_f != temp_cpu_f); - i = i || (cpu_waitstates != temp_wait_states); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); -#ifdef USE_DYNAREC - i = i || (temp_dynarec != cpu_use_dynarec); -#endif - i = i || (temp_fpu_softfloat != fpu_softfloat); - i = i || (temp_fpu != fpu_type); - i = i || (temp_sync != time_sync); - - /* Video category */ - i = i || (gfxcard[0] != temp_gfxcard[0]); - i = i || (gfxcard[1] != temp_gfxcard[1]); - i = i || (voodoo_enabled != temp_voodoo); - i = i || (ibm8514_standalone_enabled != temp_ibm8514); - i = i || (xga_standalone_enabled != temp_xga); - - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); - - /* Sound category */ - for (uint8_t j = 0; j < SOUND_CARD_MAX; j++) - i = i || (sound_card_current[j] != temp_sound_card[j]); - i = i || (midi_output_device_current != temp_midi_output_device); - i = i || (midi_input_device_current != temp_midi_input_device); - i = i || (mpu401_standalone_enable != temp_mpu401); - i = i || (sound_is_float != temp_float); - i = i || (fm_driver != temp_fm_driver); - - /* Network category */ - for (uint8_t j = 0; j < NET_CARD_MAX; j++) { - i = i || (net_cards_conf[j].net_type != temp_net_type[j]); - i = i || strcmp(temp_pcap_dev[j], net_cards_conf[j].host_dev_name); - i = i || (net_cards_conf[j].device_num != temp_net_card[j]); - } - - /* Ports category */ - for (uint8_t j = 0; j < PARALLEL_MAX; j++) { - i = i || (temp_lpt_devices[j] != lpt_ports[j].device); - i = i || (temp_lpt[j] != lpt_ports[j].enabled); - } - for (uint8_t j = 0; j < SERIAL_MAX; j++) { - i = i || (temp_serial[j] != com_ports[j].enabled); - i = i || (temp_serial_passthrough_enabled[i] != serial_passthrough_enabled[i]); - } - - /* Storage devices category */ - for (uint8_t j = 0; j < SCSI_BUS_MAX; j++) - i = i || (temp_scsi_card[j] != scsi_card_current[j]); - i = i || (fdc_type != temp_fdc_card); - i = i || (hdc_current != temp_hdc); - i = i || (temp_ide_ter != ide_ter_enabled); - i = i || (temp_ide_qua != ide_qua_enabled); - i = i || (temp_cassette != cassette_enable); - - /* Hard disks category */ - i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - - /* Floppy drives category */ - for (uint8_t j = 0; j < FDD_NUM; j++) { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); - i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j)); - } - - /* Other removable devices category */ - i = i || memcmp(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t)); - i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - i = i || memcmp(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t)); - - /* Other peripherals category */ - i = i || (temp_bugger != bugger_enabled); - i = i || (temp_postcard != postcard_enabled); - i = i || (temp_isartc != isartc_type); - - /* ISA memory boards. */ - for (uint8_t j = 0; j < ISAMEM_MAX; j++) - i = i || (temp_isamem[j] != isamem_type[j]); - - i = i || !!temp_deviceconfig; - - return i; -} - -/* This saves the settings back to the global variables. */ -static void -win_settings_save(void) -{ - pc_reset_hard_close(); - - /* Machine category */ - machine = temp_machine; - cpu_f = temp_cpu_f; - cpu_waitstates = temp_wait_states; - cpu = temp_cpu; - mem_size = temp_mem_size; -#ifdef USE_DYNAREC - cpu_use_dynarec = temp_dynarec; -#endif - fpu_softfloat = temp_fpu_softfloat; - fpu_type = temp_fpu; - time_sync = temp_sync; - - /* Video category */ - gfxcard[0] = temp_gfxcard[0]; - gfxcard[1] = temp_gfxcard[1]; - voodoo_enabled = temp_voodoo; - ibm8514_standalone_enabled = temp_ibm8514; - xga_standalone_enabled = temp_xga; - - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; - - /* Sound category */ - for (uint8_t i = 0; i < SOUND_CARD_MAX; i++) - sound_card_current[i] = temp_sound_card[i]; - midi_output_device_current = temp_midi_output_device; - midi_input_device_current = temp_midi_input_device; - mpu401_standalone_enable = temp_mpu401; - sound_is_float = temp_float; - fm_driver = temp_fm_driver; - - /* Network category */ - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - net_cards_conf[i].net_type = temp_net_type[i]; - memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); - strcpy(net_cards_conf[i].host_dev_name, temp_pcap_dev[i]); - net_cards_conf[i].device_num = temp_net_card[i]; - } - - /* Ports category */ - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - lpt_ports[i].device = temp_lpt_devices[i]; - lpt_ports[i].enabled = temp_lpt[i]; - } - for (uint8_t i = 0; i < SERIAL_MAX; i++) { - com_ports[i].enabled = temp_serial[i]; - serial_passthrough_enabled[i] = temp_serial_passthrough_enabled[i]; - } - - /* Storage devices category */ - for (uint8_t i = 0; i < SCSI_BUS_MAX; i++) - scsi_card_current[i] = temp_scsi_card[i]; - hdc_current = temp_hdc; - fdc_type = temp_fdc_card; - ide_ter_enabled = temp_ide_ter; - ide_qua_enabled = temp_ide_qua; - cassette_enable = temp_cassette; - - /* Hard disks category */ - memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - for (uint8_t i = 0; i < HDD_NUM; i++) - hdd[i].priv = NULL; - - /* Floppy drives category */ - for (uint8_t i = 0; i < FDD_NUM; i++) { - fdd_set_type(i, temp_fdd_types[i]); - fdd_set_turbo(i, temp_fdd_turbo[i]); - fdd_set_check_bpb(i, temp_fdd_check_bpb[i]); - } - - /* Removable devices category */ - memcpy(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t)); - for (uint8_t i = 0; i < CDROM_NUM; i++) { - cdrom[i].is_dir = 0; - cdrom[i].priv = NULL; - cdrom[i].ops = NULL; - cdrom[i].image = NULL; - cdrom[i].insert = NULL; - cdrom[i].close = NULL; - cdrom[i].get_volume = NULL; - cdrom[i].get_channel = NULL; - } - memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (uint8_t i = 0; i < ZIP_NUM; i++) { - zip_drives[i].fp = NULL; - zip_drives[i].priv = NULL; - } - memcpy(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t)); - for (uint8_t i = 0; i < MO_NUM; i++) { - mo_drives[i].fp = NULL; - mo_drives[i].priv = NULL; - } - - /* Other peripherals category */ - bugger_enabled = temp_bugger; - postcard_enabled = temp_postcard; - isartc_type = temp_isartc; - - /* ISA memory boards. */ - for (uint8_t i = 0; i < ISAMEM_MAX; i++) - isamem_type[i] = temp_isamem[i]; - - /* Mark configuration as changed. */ - config_changed = 2; - - pc_reset_hard_init(); -} - -static void -win_settings_machine_recalc_softfloat(HWND hdlg) -{ - if (temp_fpu == FPU_NONE) { - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); - settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); - } else { - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? TRUE : temp_fpu_softfloat)); - settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? FALSE : TRUE)); - } -} - -static void -win_settings_machine_recalc_fpu(HWND hdlg) -{ - int c; - int type; - LPTSTR lptsTemp; - const char *stransi; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_FPU); - c = 0; - while (1) { - stransi = fpu_get_name_from_index(temp_cpu_f, temp_cpu, c); - type = fpu_get_type_from_index(temp_cpu_f, temp_cpu, c); - if (!stransi) - break; - - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_FPU, (LPARAM) (LPCSTR) lptsTemp); - if (!c || (type == temp_fpu)) - settings_set_cur_sel(hdlg, IDC_COMBO_FPU, c); - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_FPU, c > 1); - - temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); - - win_settings_machine_recalc_softfloat(hdlg); -} - -static void -win_settings_machine_recalc_cpu(HWND hdlg) -{ - int cpu_type; -#ifdef USE_DYNAREC - int cpu_flags; -#endif - - cpu_type = temp_cpu_f->cpus[temp_cpu].cpu_type; - settings_enable_window(hdlg, IDC_COMBO_WS, (cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)); - -#ifdef USE_DYNAREC - cpu_flags = temp_cpu_f->cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || ((cpu_flags & CPU_REQUIRES_DYNAREC) && !cpu_override)) { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - temp_dynarec = 0; - if (cpu_flags & CPU_REQUIRES_DYNAREC) - temp_dynarec = 1; - settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec); - settings_enable_window(hdlg, IDC_CHECK_DYNAREC, FALSE); - } else { - settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec); - settings_enable_window(hdlg, IDC_CHECK_DYNAREC, TRUE); - } -#endif - - win_settings_machine_recalc_fpu(hdlg); -} - -static void -win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - int c; - int i; - int first_eligible = -1; - int current_eligible = 0; - int last_eligible = 0; - LPTSTR lptsTemp; - const char *stransi; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_CPU_SPEED); - c = i = 0; - while (temp_cpu_f->cpus[c].cpu_type != 0) { - if (cpu_is_eligible(temp_cpu_f, c, temp_machine)) { - stransi = (char *) temp_cpu_f->cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_CPU_SPEED, (LPARAM) (LPCSTR) lptsTemp); - - if (first_eligible == -1) - first_eligible = i; - if (temp_cpu == c) - current_eligible = i; - last_eligible = i; - - listtocpu[i++] = c; - } - c++; - } - if (i == 0) - fatal("No eligible CPUs for the selected family\n"); - settings_enable_window(hdlg, IDC_COMBO_CPU_SPEED, i != 1); - if (current_eligible < first_eligible) - current_eligible = first_eligible; - else if (current_eligible > last_eligible) - current_eligible = last_eligible; - temp_cpu = listtocpu[current_eligible]; - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_SPEED, current_eligible); - - win_settings_machine_recalc_cpu(hdlg); - - free(lptsTemp); -} - -static void -win_settings_machine_recalc_machine(HWND hdlg) -{ - HWND h; - int c; - int i; - int current_eligible; - LPTSTR lptsTemp; - char *stransi; - UDACCEL accel; - const device_t *d; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - d = (device_t *) machine_get_device(temp_machine); - settings_enable_window(hdlg, IDC_CONFIGURE_MACHINE, d && d->config); - - settings_reset_content(hdlg, IDC_COMBO_CPU_TYPE); - c = i = 0; - current_eligible = -1; - while (cpu_families[c].package != 0) { - if (cpu_family_is_eligible(&cpu_families[c], temp_machine)) { - stransi = malloc(strlen((char *) cpu_families[c].manufacturer) + strlen((char *) cpu_families[c].name) + 2); - sprintf(stransi, "%s %s", (char *) cpu_families[c].manufacturer, (char *) cpu_families[c].name); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - free(stransi); - settings_add_string(hdlg, IDC_COMBO_CPU_TYPE, (LPARAM) (LPCSTR) lptsTemp); - if (&cpu_families[c] == temp_cpu_f) - current_eligible = i; - listtocpufamily[i++] = c; - } - c++; - } - if (i == 0) - fatal("No eligible CPU families for the selected machine\n"); - settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, TRUE); - if (current_eligible == -1) { - temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[0]]; - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, 0); - } else { - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, current_eligible); - } - settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, i != 1); - - win_settings_machine_recalc_cpu_m(hdlg); - - if (machine_get_ram_granularity(temp_machine) & 1023) { - /* KB granularity */ - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 16) | machine_get_max_ram(temp_machine)); - - accel.nSec = 0; - accel.nInc = machine_get_ram_granularity(temp_machine); - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_KB)); - } else { - /* MB granularity */ - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 6) | (machine_get_max_ram(temp_machine) >> 10)); - - accel.nSec = 0; - accel.nInc = machine_get_ram_granularity(temp_machine) >> 10; - - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - - SendMessage(h, UDM_SETPOS, 0, temp_mem_size >> 10); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_MB)); - } - - settings_enable_window(hdlg, IDC_MEMSPIN, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); - settings_enable_window(hdlg, IDC_MEMTEXT, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); - - free(lptsTemp); -} - -static char * -machine_type_get_internal_name(int id) -{ - if (id < MACHINE_TYPE_MAX) - return ""; - else - return NULL; -} - -int -machine_type_available(int id) -{ - int c = 0; - - if ((id > 0) && (id < MACHINE_TYPE_MAX)) { - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == id)) - return 1; - c++; - } - } - - return 0; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - HWND h2; - int c; - int d; - int old_machine_type; - LPTSTR lptsTemp; - char *stransi; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MACHINE_TYPE); - memset(listtomachinetype, 0x00, sizeof(listtomachinetype)); - while (machine_type_get_internal_name(c) != NULL) { - if (machine_type_available(c)) { - stransi = (char *) machine_types[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE_TYPE, (LPARAM) lptsTemp); - listtomachinetype[d] = c; - if (c == temp_machine_type) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE, d); - d++; - } - c++; - } - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MACHINE); - memset(listtomachine, 0x00, sizeof(listtomachine)); - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = (char *) machine_getname_ex(c); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); - listtomachine[d] = c; - if (c == temp_machine) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d); - d++; - } - c++; - } - - settings_add_string(hdlg, IDC_COMBO_WS, win_get_string(IDS_DEFAULT)); - for (c = 0; c < 8; c++) { /* TODO */ - wsprintf(lptsTemp, plat_get_string(IDS_WS), c); - settings_add_string(hdlg, IDC_COMBO_WS, (LPARAM) lptsTemp); - } - - settings_set_cur_sel(hdlg, IDC_COMBO_WS, temp_wait_states); - -#ifdef USE_DYNAREC - settings_set_check(hdlg, IDC_CHECK_DYNAREC, 0); -#endif - - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, 0); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - h2 = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - - if (temp_sync & TIME_SYNC_ENABLED) { - if (temp_sync & TIME_SYNC_UTC) - settings_set_check(hdlg, IDC_RADIO_TS_UTC, BST_CHECKED); - else - settings_set_check(hdlg, IDC_RADIO_TS_LOCAL, BST_CHECKED); - } else - settings_set_check(hdlg, IDC_RADIO_TS_DISABLED, BST_CHECKED); - - win_settings_machine_recalc_machine(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MACHINE_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - old_machine_type = temp_machine_type; - temp_machine_type = listtomachinetype[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE)]; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_MACHINE); - c = d = 0; - memset(listtomachine, 0x00, sizeof(listtomachine)); - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = (char *) machine_getname_ex(c); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); - listtomachine[d] = c; - if (c == temp_machine) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d); - d++; - } - c++; - } - if (old_machine_type != temp_machine_type) { - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, 0); - temp_machine = listtomachine[0]; - - win_settings_machine_recalc_machine(hdlg); - } - - free(lptsTemp); - } - break; - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)]; - win_settings_machine_recalc_machine(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_TYPE)]]; - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU_SPEED: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_cpu = listtocpu[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_SPEED)]; - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_COMBO_FPU: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, - settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); - } - win_settings_machine_recalc_softfloat(hdlg); - break; - case IDC_CONFIGURE_MACHINE: - temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) machine_get_device(temp_machine)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - -#ifdef USE_DYNAREC - temp_dynarec = settings_get_check(hdlg, IDC_CHECK_DYNAREC); -#endif - - temp_fpu_softfloat = settings_get_check(hdlg, IDC_CHECK_SOFTFLOAT); - - if (settings_get_check(hdlg, IDC_RADIO_TS_DISABLED)) - temp_sync = TIME_SYNC_DISABLED; - - if (settings_get_check(hdlg, IDC_RADIO_TS_LOCAL)) - temp_sync = TIME_SYNC_ENABLED; - - if (settings_get_check(hdlg, IDC_RADIO_TS_UTC)) - temp_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; - - temp_wait_states = settings_get_cur_sel(hdlg, IDC_COMBO_WS); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_mem_size); - if (!(machine_get_ram_granularity(temp_machine) & 1023)) - temp_mem_size = temp_mem_size << 10; - temp_mem_size &= ~(machine_get_ram_granularity(temp_machine) - 1); - if (temp_mem_size < machine_get_min_ram(temp_machine)) - temp_mem_size = machine_get_min_ram(temp_machine); - else if (temp_mem_size > machine_get_max_ram(temp_machine)) - temp_mem_size = machine_get_max_ram(temp_machine); - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; -} - -static void -generate_device_name(const device_t *device, const char *internal_name, int bus) -{ - char temp[512]; - const WCHAR *wtemp; - - memset(device_name, 0x00, 512 * sizeof(WCHAR)); - memset(temp, 0x00, 512); - - if (!strcmp(internal_name, "none")) { - /* Translate "None". */ - wtemp = (WCHAR *) win_get_string(IDS_2104); - memcpy(device_name, wtemp, (wcslen(wtemp) + 1) * sizeof(WCHAR)); - return; - } else if (!strcmp(internal_name, "internal")) - memcpy(temp, "Internal", 9); - else - device_get_name(device, bus, temp); - - mbstowcs(device_name, temp, strlen(temp) + 1); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c = 0; - int d = 0; - int e; - - switch (message) { - case WM_INITDIALOG: - // Primary Video Card - settings_reset_content(hdlg, IDC_COMBO_VIDEO); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_gfxcard[0])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e)); - - // Secondary Video Card - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_VIDEO_2); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) { - c++; - continue; - } - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name); - settings_list_to_device[1][d] = c; - if ((c == 0) || (c == temp_gfxcard[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e)); - - settings_enable_window(hdlg, IDC_CHECK_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI)); - settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo); - settings_enable_window(hdlg, IDC_BUTTON_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI) && temp_voodoo); - - settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); - settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514); - - settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); - settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga); - settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_VIDEO: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(temp_gfxcard[0])); - - // Secondary Video Card - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_VIDEO_2); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) { - c++; - continue; - } - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name); - settings_list_to_device[1][d] = c; - if ((c == 0) || (c == temp_gfxcard[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e)); - break; - - case IDC_COMBO_VIDEO_2: - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(temp_gfxcard[1])); - break; - - case IDC_CHECK_VOODOO: - temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); - settings_enable_window(hdlg, IDC_BUTTON_VOODOO, temp_voodoo); - break; - - case IDC_CHECK_IBM8514: - temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); - break; - - case IDC_CHECK_XGA: - temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); - settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga); - break; - - case IDC_BUTTON_VOODOO: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &voodoo_device); - break; - - case IDC_BUTTON_XGA: - if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0) - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_device); - else - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_isa_device); - break; - - case IDC_CONFIGURE_VID: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[0])); - break; - - case IDC_CONFIGURE_VID_2: - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[1])); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); - temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); - temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); - - default: - return FALSE; - } - return FALSE; -} - -static int -mouse_valid(int num, int m) -{ - const device_t *dev; - - if ((num == MOUSE_TYPE_INTERNAL) && !machine_has_flags(m, MACHINE_MOUSE)) - return 0; - - dev = mouse_get_device(num); - return (device_is_valid(dev, m)); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - wchar_t str[128]; - const char *joy_name; - int c; - int d; - - switch (message) { - case WM_INITDIALOG: - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MOUSE); - for (c = 0; c < mouse_get_ndev(); c++) { - if (mouse_valid(c, temp_machine)) { - generate_device_name(mouse_get_device(c), mouse_get_internal_name(c), 0); - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_MOUSE, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_mouse)) - settings_set_cur_sel(hdlg, IDC_COMBO_MOUSE, d); - d++; - } - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse)); - - c = 0; - joy_name = joystick_get_name(c); - while (joy_name) { - mbstowcs(str, joy_name, strlen(joy_name) + 1); - settings_add_string(hdlg, IDC_COMBO_JOYSTICK, (LPARAM) str); - - c++; - joy_name = joystick_get_name(c); - } - settings_enable_window(hdlg, IDC_COMBO_JOYSTICK, TRUE); - settings_set_cur_sel(hdlg, IDC_COMBO_JOYSTICK, temp_joystick); - - for (c = 0; c < 4; c++) - settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MOUSE: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse)); - break; - - case IDC_CONFIGURE_MOUSE: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) mouse_get_device(temp_mouse)); - break; - - case IDC_COMBO_JOYSTICK: - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - - for (c = 0; c < MAX_JOYSTICKS; c++) - settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c); - break; - - case IDC_JOY1: - case IDC_JOY2: - case IDC_JOY3: - case IDC_JOY4: - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - temp_deviceconfig |= joystickconfig_open(hdlg, LOWORD(wParam) - IDC_JOY1, temp_joystick); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - - default: - return FALSE; - } - return FALSE; -} - -static int -mpu401_present(void) -{ - return temp_mpu401 ? 1 : 0; -} - -int -mpu401_standalone_allow(void) -{ - const char *mdout; - const char *mdin; - - if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA)) - return 0; - - mdout = midi_out_device_get_internal_name(temp_midi_output_device); - mdin = midi_in_device_get_internal_name(temp_midi_input_device); - - if (mdout != NULL) { - if (!strcmp(mdout, "none") && !strcmp(mdin, "none")) - return 0; - } - - return 1; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - uint16_t c; - uint16_t d; - LPTSTR lptsTemp; - const device_t *sound_dev[SOUND_CARD_MAX]; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND1); - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_SOUND)) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[0] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[0], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND1, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[0])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND1, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND1, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND2); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[1] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[1], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND2, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND2, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND2, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND3); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[2] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[2], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND3, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[2])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND3, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND3, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND4); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[3] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[3], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND4, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[3])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND4, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND4, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MIDI_OUT); - while (1) { - generate_device_name(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); - - if (!device_name[0]) - break; - - if (midi_out_device_available(c)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, (LPARAM) device_name); - settings_list_to_midi[d] = c; - if ((c == 0) || (c == temp_midi_output_device)) - settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_OUT, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MIDI_IN); - while (1) { - generate_device_name(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0); - - if (!device_name[0]) - break; - - if (midi_in_device_available(c)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_IN, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_MIDI_IN, (LPARAM) device_name); - settings_list_to_midi_in[d] = c; - if ((c == 0) || (c == temp_midi_input_device)) - settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_IN, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float); - - if (temp_fm_driver == FM_DRV_YMFM) - settings_set_check(hdlg, IDC_RADIO_FM_DRV_YMFM, BST_CHECKED); - else - settings_set_check(hdlg, IDC_RADIO_FM_DRV_NUKED, BST_CHECKED); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_SOUND1: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND1: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[0])); - break; - - case IDC_COMBO_SOUND2: - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND2: - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[1])); - break; - - case IDC_COMBO_SOUND3: - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND3: - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[2])); - break; - - case IDC_COMBO_SOUND4: - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND4: - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[3])); - break; - - case IDC_COMBO_MIDI_OUT: - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_MIDI_OUT: - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_out_device_getdevice(temp_midi_output_device)); - break; - - case IDC_COMBO_MIDI_IN: - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_MIDI_IN: - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_in_device_getdevice(temp_midi_input_device)); - break; - - case IDC_CHECK_MPU401: - temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401); - - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_present()); - break; - - case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= deviceconfig_open(hdlg, machine_has_bus(temp_machine, MACHINE_BUS_MCA) ? (void *) &mpu401_mca_device : (void *) &mpu401_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401); - temp_float = settings_get_check(hdlg, IDC_CHECK_FLOAT); - if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_NUKED)) - temp_fm_driver = FM_DRV_NUKED; - if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_YMFM)) - temp_fm_driver = FM_DRV_YMFM; - default: - return FALSE; - } - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int i; - const char *s; - LPTSTR lptsTemp; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = 0; i < PARALLEL_MAX; i++) { - c = 0; - while (1) { - s = (char *) lpt_device_get_name(c); - - if (!s) - break; - - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_LPT1 + i, win_get_string(IDS_2104)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - settings_add_string(hdlg, IDC_COMBO_LPT1 + i, (LPARAM) lptsTemp); - } - - c++; - } - settings_set_cur_sel(hdlg, IDC_COMBO_LPT1 + i, temp_lpt_devices[i]); - - settings_set_check(hdlg, IDC_CHECK_PARALLEL1 + i, temp_lpt[i]); - settings_enable_window(hdlg, IDC_COMBO_LPT1 + i, temp_lpt[i]); - } - - for (i = 0; i < SERIAL_MAX; i++) { - settings_set_check(hdlg, IDC_CHECK_SERIAL1 + i, temp_serial[i]); - settings_set_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i, temp_serial_passthrough_enabled[i]); - } - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CHECK_PARALLEL1: - case IDC_CHECK_PARALLEL2: - case IDC_CHECK_PARALLEL3: - case IDC_CHECK_PARALLEL4: - i = LOWORD(wParam) - IDC_CHECK_PARALLEL1; - settings_enable_window(hdlg, IDC_COMBO_LPT1 + i, - settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i) == BST_CHECKED); - break; - } - break; - - case WM_SAVESETTINGS: - for (i = 0; i < PARALLEL_MAX; i++) { - temp_lpt_devices[i] = settings_get_cur_sel(hdlg, IDC_COMBO_LPT1 + i); - temp_lpt[i] = settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i); - } - - for (i = 0; i < SERIAL_MAX; i++) { - temp_serial[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL1 + i); - temp_serial_passthrough_enabled[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i); - } - - default: - return FALSE; - } - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - int e; - int is_at; - LPTSTR lptsTemp; - char *stransi; - const device_t *scsi_dev; - const device_t *fdc_dev; - const device_t *hdc_dev; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - /*HD controller config*/ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_HDC); - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_HDC)) { - c++; - continue; - } - - generate_device_name(hdc_get_device(c), hdc_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (hdc_available(c)) { - hdc_dev = hdc_get_device(c); - - if (device_is_valid(hdc_dev, temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_HDC, (LPARAM) device_name); - settings_list_to_hdc[d] = c; - if ((c == 0) || (c == temp_hdc)) - settings_set_cur_sel(hdlg, IDC_COMBO_HDC, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_HDC, d); - settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc)); - - /*FD controller config*/ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_FDC); - while (1) { - generate_device_name(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (fdc_card_available(c)) { - fdc_dev = fdc_card_getdevice(c); - - if (device_is_valid(fdc_dev, temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_FDC, (LPARAM) device_name); - settings_list_to_fdc[d] = c; - if ((c == 0) || (c == temp_fdc_card)) - settings_set_cur_sel(hdlg, IDC_COMBO_FDC, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_FDC, d); - settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card)); - - /*SCSI config*/ - c = d = 0; - for (e = 0; e < SCSI_BUS_MAX; e++) - settings_reset_content(hdlg, IDC_COMBO_SCSI_1 + e); - while (1) { - generate_device_name(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (scsi_card_available(c)) { - scsi_dev = scsi_card_getdevice(c); - - if (device_is_valid(scsi_dev, temp_machine)) { - for (e = 0; e < SCSI_BUS_MAX; e++) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, (LPARAM) device_name); - - if ((c == 0) || (c == temp_scsi_card[e])) - settings_set_cur_sel(hdlg, IDC_COMBO_SCSI_1 + e, d); - } - - settings_list_to_device[0][d] = c; - d++; - } - } - - c++; - } - - for (c = 0; c < SCSI_BUS_MAX; c++) { - settings_enable_window(hdlg, IDC_COMBO_SCSI_1 + c, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c])); - } - is_at = IS_AT(temp_machine); - settings_enable_window(hdlg, IDC_CHECK_IDE_TER, is_at); - settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter); - settings_enable_window(hdlg, IDC_CHECK_IDE_QUA, is_at); - settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua); - settings_enable_window(hdlg, IDC_CHECK_CASSETTE, machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE)); - settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter); - settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua); - settings_set_check(hdlg, IDC_CHECK_CASSETTE, (temp_cassette && machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE))); - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIGURE_FDC: - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) fdc_card_getdevice(temp_fdc_card)); - break; - - case IDC_COMBO_FDC: - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card)); - break; - - case IDC_CONFIGURE_HDC: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) hdc_get_device(temp_hdc)); - break; - - case IDC_COMBO_HDC: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc)); - break; - - case IDC_CONFIGURE_SCSI_1 ... IDC_CONFIGURE_SCSI_4: - c = LOWORD(wParam) - IDC_CONFIGURE_SCSI_1; - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) scsi_card_getdevice(temp_scsi_card[c]), c + 1); - break; - - case IDC_COMBO_SCSI_1 ... IDC_COMBO_SCSI_4: - c = LOWORD(wParam) - IDC_COMBO_SCSI_1; - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c])); - break; - - case IDC_CHECK_IDE_TER: - temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER); - settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, temp_ide_ter); - break; - - case IDC_BUTTON_IDE_TER: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_ter_device); - break; - - case IDC_CHECK_IDE_QUA: - temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA); - settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, temp_ide_qua); - break; - - case IDC_BUTTON_IDE_QUA: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_qua_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - for (c = 0; c < SCSI_BUS_MAX; c++) - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER); - temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA); - temp_cassette = settings_get_check(hdlg, IDC_CHECK_CASSETTE); - - default: - return FALSE; - } - return FALSE; -} - -static void -network_recalc_combos(HWND hdlg) -{ - ignore_change = 1; - - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP); - settings_enable_window(hdlg, IDC_COMBO_NET1 + i, - (temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0))); - settings_enable_window(hdlg, IDC_CONFIGURE_NET1 + i, network_card_has_config(temp_net_card[i]) && ((temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0)))); - } - - ignore_change = 0; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - LPTSTR lptsTemp; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"Null Driver"); - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"SLiRP"); - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"PCap"); - settings_set_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i, temp_net_type[i]); - settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP); - - for (c = 0; c < network_ndev; c++) { - mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); - settings_add_string(hdlg, IDC_COMBO_PCAP1 + i, (LPARAM) lptsTemp); - } - settings_set_cur_sel(hdlg, IDC_COMBO_PCAP1 + i, network_dev_to_id(temp_pcap_dev[i])); - - /* NIC config */ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_NET1 + i); - while (1) { - generate_device_name(network_card_getdevice(c), network_card_get_internal_name(c), 1); - - if (device_name[0] == L'\0') - break; - - if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_NET1 + i, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_NET1 + i, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_net_card[i])) - settings_set_cur_sel(hdlg, IDC_COMBO_NET1 + i, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_NET1 + i, d); - network_recalc_combos(hdlg); - } - free(lptsTemp); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_NET1_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[0] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET2_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[1] = settings_get_cur_sel(hdlg, IDC_COMBO_NET2_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET3_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[2] = settings_get_cur_sel(hdlg, IDC_COMBO_NET3_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET4_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[3] = settings_get_cur_sel(hdlg, IDC_COMBO_NET4_TYPE); - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_PCAP1: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[0], '\0', sizeof(temp_pcap_dev[0])); - strcpy(temp_pcap_dev[0], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP2: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[1], '\0', sizeof(temp_pcap_dev[1])); - strcpy(temp_pcap_dev[1], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP2)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP3: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[2], '\0', sizeof(temp_pcap_dev[2])); - strcpy(temp_pcap_dev[2], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP3)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP4: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[3], '\0', sizeof(temp_pcap_dev[3])); - strcpy(temp_pcap_dev[3], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP4)].device); - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_NET1: - if (ignore_change) - return FALSE; - - temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET2: - if (ignore_change) - return FALSE; - - temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET3: - if (ignore_change) - return FALSE; - - temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET4: - if (ignore_change) - return FALSE; - - temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)]; - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURE_NET1: - if (ignore_change) - return FALSE; - - temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[0])); - break; - case IDC_CONFIGURE_NET2: - if (ignore_change) - return FALSE; - - temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[1])); - break; - case IDC_CONFIGURE_NET3: - if (ignore_change) - return FALSE; - - temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[2])); - break; - case IDC_CONFIGURE_NET4: - if (ignore_change) - return FALSE; - - temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[3])); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - temp_net_type[i] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i); - memset(temp_pcap_dev[i], '\0', sizeof(temp_pcap_dev[i])); - strcpy(temp_pcap_dev[i], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1 + i)].device); - temp_net_card[i] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1 + i)]; - } - default: - return FALSE; - } - - return FALSE; -} - -static void -normalize_hd_list(void) -{ - hard_disk_t ihdd[HDD_NUM]; - int j = 0; - - memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus != HDD_BUS_DISABLED) { - memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); - j++; - } - } - - memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); -} - -static int -get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int j = 0; - HWND h; - - if (hd_listview_items == 0) - return 0; - - for (int i = 0; i < hd_listview_items; i++) { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - hard_disk = i; - } - - return hard_disk; -} - -static void -add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = 0; i < 6; i++) - settings_add_string(hdlg, IDC_COMBO_HD_BUS, win_get_string(IDS_4352 + i)); - - for (i = 0; i < 2; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL, (LPARAM) lptsTemp); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_HD_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static uint8_t -next_free_binary_channel(uint64_t *tracking) -{ - for (int64_t i = 0; i < 2; i++) { - if (!(*tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 2; -} - -static uint8_t -next_free_ide_channel(void) -{ - for (int64_t i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - if (!(ide_tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 7; -} - -static void -next_free_scsi_id(uint8_t *id) -{ - for (int64_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) { - *id = i; - return; - } - } - - *id = 6; -} - -static void -recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) -{ - int bus = 0; - - for (uint16_t i = IDT_CHANNEL; i <= IDT_ID; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, FALSE); - - if ((hd_listview_items > 0) || is_add_dlg) { - bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - - switch (bus) { - case HDD_BUS_MFM: /* MFM */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[lv1_current_sel].mfm_channel); - break; - case HDD_BUS_XTA: /* XTA */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].xta_channel = next_free_binary_channel(&xta_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[lv1_current_sel].xta_channel); - break; - case HDD_BUS_ESDI: /* ESDI */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[lv1_current_sel].esdi_channel); - break; - case HDD_BUS_IDE: /* IDE */ - case HDD_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].ide_channel = next_free_ide_channel(); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, is_add_dlg ? new_hdd.ide_channel : temp_hdd[lv1_current_sel].ide_channel); - break; - case HDD_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_ID, TRUE); - settings_show_window(hdlg, IDT_LUN, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_ID, TRUE); - - if (assign_id) - next_free_scsi_id((is_add_dlg ? &(new_hdd.scsi_id) : &(temp_hdd[lv1_current_sel].scsi_id))); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, is_add_dlg ? new_hdd.scsi_id : temp_hdd[lv1_current_sel].scsi_id); - } - } - - settings_show_window(hdlg, IDT_BUS, (hd_listview_items != 0) || is_add_dlg); - settings_show_window(hdlg, IDC_COMBO_HD_BUS, (hd_listview_items != 0) || is_add_dlg); -} - -static int -bus_full(uint64_t *tracking, int count) -{ - int full = 0; - - switch (count) { - default: - case 2: - full = (*tracking & 0xFF00LL); - full = full && (*tracking & 0x00FFLL); - break; - case 8: - full = (*tracking & 0xFF00000000000000LL); - full = full && (*tracking & 0x00FF000000000000LL); - full = full && (*tracking & 0x0000FF0000000000LL); - full = full && (*tracking & 0x000000FF00000000LL); - full = full && (*tracking & 0x00000000FF000000LL); - full = full && (*tracking & 0x0000000000FF0000LL); - full = full && (*tracking & 0x000000000000FF00LL); - full = full && (*tracking & 0x00000000000000FFLL); - break; - } - - return full; -} - -static void -recalc_next_free_id(HWND hdlg) -{ - int i; - int enable_add = 0; - int c_mfm = 0; - int c_esdi = 0; - int c_xta = 0; - int c_ide = 0; - int c_atapi = 0; - int c_scsi = 0; - - next_free_id = -1; - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_MFM) - c_mfm++; - else if (temp_hdd[i].bus == HDD_BUS_ESDI) - c_esdi++; - else if (temp_hdd[i].bus == HDD_BUS_XTA) - c_xta++; - else if (temp_hdd[i].bus == HDD_BUS_IDE) - c_ide++; - else if (temp_hdd[i].bus == HDD_BUS_ATAPI) - c_atapi++; - else if (temp_hdd[i].bus == HDD_BUS_SCSI) - c_scsi++; - } - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_DISABLED) { - next_free_id = i; - break; - } - } - - enable_add = enable_add || (next_free_id >= 0); - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || (c_ide < IDE_NUM) || (c_ide < ATAPI_NUM) || (c_scsi < SCSI_NUM)); - enable_add = enable_add && (!bus_full(&mfm_tracking, 2) || !bus_full(&esdi_tracking, 2) || !bus_full(&xta_tracking, 2) || !bus_full(&ide_tracking, IDE_CHAN_MAX * IDE_BUS_MAX) || - !bus_full(&(scsi_tracking[0]), 8) || !bus_full(&(scsi_tracking[1]), 8) || !bus_full(&(scsi_tracking[2]), 8) || !bus_full(&(scsi_tracking[3]), 8) || - !bus_full(&(scsi_tracking[4]), 8) || !bus_full(&(scsi_tracking[5]), 8) || !bus_full(&(scsi_tracking[6]), 8) || !bus_full(&(scsi_tracking[7]), 8)); - - settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD_NEW, enable_add); - settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD, enable_add); - settings_enable_window(hdlg, IDC_BUTTON_HDD_REMOVE, - (c_mfm != 0) || (c_esdi != 0) || (c_xta != 0) || (c_ide != 0) || (c_atapi != 0) || (c_scsi != 0)); -} - -static void -win_settings_hard_disks_update_item(HWND hdlg, int i, int column) -{ - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - LVITEM lvI; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = column; - lvI.iItem = i; - - if (column == 0) { /* Bus */ - switch (temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_ATAPI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15); - break; - } - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 1) { /* File */ - if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) - mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); - else - mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText)); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 2) { /* Cylinders */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 3) { /* Heads */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 4) { /* Sectors */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 5) { /* Size (MB) */ - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 6) { /* Speed (RPM) */ - mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); - lvI.pszText = szText; - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static BOOL -win_settings_hard_disks_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int j = 0; - WCHAR szText[256]; - WCHAR usr_path_w[1024]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - - mbstoc16s(usr_path_w, usr_path, sizeof_w(usr_path_w)); - - hd_listview_items = 0; - lv1_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus > 0) { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - - /* Bus */ - switch (temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_ATAPI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - /* File */ - lvI.iSubItem = 1; - if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) - mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); - else - mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText)); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Cylinders */ - lvI.iSubItem = 2; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Heads */ - lvI.iSubItem = 3; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Sectors */ - lvI.iSubItem = 4; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Size (MB) */ - lvI.iSubItem = 5; - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Speed (RPM) */ - lvI.iSubItem = 6; - mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - j++; - } else - hdc_id_to_listview_index[i] = -1; - } - - hd_listview_items = j; - - return TRUE; -} - -#define C_COLUMNS_HARD_DISKS_BUS 104 -#define C_COLUMNS_HARD_DISKS_FILE 254 -#define C_COLUMNS_HARD_DISKS_CYLS 50 -#define C_COLUMNS_HARD_DISKS_HEADS 26 -#define C_COLUMNS_HARD_DISKS_SECT 32 -#define C_COLUMNS_HARD_DISKS_SIZE 50 -#define C_COLUMNS_HARD_DISKS_SPEED 100 - -static void -win_settings_hard_disks_resize_columns(HWND hdlg) -{ - /* Bus, File, Cylinders, Heads, Sectors, Size */ - int width[C_COLUMNS_HARD_DISKS] = { - C_COLUMNS_HARD_DISKS_BUS, - C_COLUMNS_HARD_DISKS_FILE, - C_COLUMNS_HARD_DISKS_CYLS, - C_COLUMNS_HARD_DISKS_HEADS, - C_COLUMNS_HARD_DISKS_SECT, - C_COLUMNS_HARD_DISKS_SIZE, - C_COLUMNS_HARD_DISKS_SPEED - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - RECT r; - - GetWindowRect(hwndList, &r); - for (int iCol = 0; iCol < (C_COLUMNS_HARD_DISKS - 1); iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_HARD_DISKS - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, C_COLUMNS_HARD_DISKS - 1, width[C_COLUMNS_HARD_DISKS - 1]); -} - -static BOOL -win_settings_hard_disks_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (int iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) { - lvc.iSubItem = iCol; - lvc.pszText = plat_get_string(IDS_BUS + iCol); - - switch (iCol) { - case 0: /* Bus */ - lvc.cx = C_COLUMNS_HARD_DISKS_BUS; - lvc.fmt = LVCFMT_LEFT; - break; - case 1: /* File */ - lvc.cx = C_COLUMNS_HARD_DISKS_FILE; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = C_COLUMNS_HARD_DISKS_CYLS; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - lvc.cx = C_COLUMNS_HARD_DISKS_HEADS; - lvc.fmt = LVCFMT_RIGHT; - break; - case 4: /* Sectors */ - lvc.cx = C_COLUMNS_HARD_DISKS_SECT; - lvc.fmt = LVCFMT_RIGHT; - break; - case 5: /* Size (MB) */ - lvc.cx = C_COLUMNS_HARD_DISKS_SIZE; - lvc.fmt = LVCFMT_RIGHT; - break; - case 6: /* Speed (RPM) */ - lvc.cx = C_COLUMNS_HARD_DISKS_SPEED; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - return FALSE; - } - - win_settings_hard_disks_resize_columns(hdlg); - return TRUE; -} - -static void -get_edit_box_contents(HWND hdlg, int id, uint32_t *val) -{ - HWND h; - WCHAR szText[256]; - char stransi[256]; - - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, 256); - sscanf(stransi, "%u", val); -} - -static void -set_edit_box_contents(HWND hdlg, int id, uint32_t val) -{ - HWND h; - WCHAR szText[256]; - - h = GetDlgItem(hdlg, id); - wsprintf(szText, plat_get_string(IDS_2107), val); - SendMessage(h, WM_SETTEXT, wcslen(szText), (LPARAM) szText); -} - -static void -set_edit_box_text_contents(HWND hdlg, int id, WCHAR *text) -{ - HWND h = GetDlgItem(hdlg, id); - SendMessage(h, WM_SETTEXT, wcslen(text), (LPARAM) text); -} - -static void -get_edit_box_text_contents(HWND hdlg, int id, WCHAR *text_buffer, int buffer_size) -{ - HWND h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, (WPARAM) buffer_size, (LPARAM) text_buffer); -} - -static int -hdconf_initialize_hdt_combo(HWND hdlg) -{ - uint64_t temp_size = 0; - uint32_t size_mb = 0; - WCHAR szText[256]; - - selection = 127; - - for (uint8_t i = 0; i < 127; i++) { - temp_size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; - size_mb = (uint32_t) (temp_size >> 11LL); - wsprintf(szText, plat_get_string(IDS_2108), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) szText); - if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2])) - selection = i; - } - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4100)); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4101)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection); - return selection; -} - -static void -recalc_selection(HWND hdlg) -{ - selection = 127; - for (uint8_t i = 0; i < 127; i++) { - if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2])) - selection = i; - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - selection = 128; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection); -} - -HWND vhd_progress_hdlg; - -static void -vhd_progress_callback(uint32_t current_sector, UNUSED(uint32_t total_sectors)) -{ - MSG msg; - HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETPOS, current_sector, (LPARAM) 0); - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry, - * we adjust it to the next-largest size that is compatible. On average, this will be a difference - * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more - * than a tenth of a percent change in size. - */ -static void -adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) -{ - if (_86box_geometry->cyl <= 65535) { - vhd_geometry->cyl = _86box_geometry->cyl; - vhd_geometry->heads = _86box_geometry->heads; - vhd_geometry->spt = _86box_geometry->spt; - return; - } - - int desired_sectors = _86box_geometry->cyl * _86box_geometry->heads * _86box_geometry->spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; - - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors += (85680 - remainder); - - _86box_geometry->cyl = desired_sectors / (16 * 63); - _86box_geometry->heads = 16; - _86box_geometry->spt = 63; - - vhd_geometry->cyl = desired_sectors / (16 * 255); - vhd_geometry->heads = 16; - vhd_geometry->spt = 255; -} - -static void -adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) -{ - if (vhd_geometry->spt <= 63) - return; - - int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; - - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors -= remainder; - - vhd_geometry->cyl = desired_sectors / (16 * 63); - vhd_geometry->heads = 16; - vhd_geometry->spt = 63; -} - -static MVHDGeom -create_drive_vhd_fixed(char *filename, int cyl, int heads, int spt) -{ - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; - MVHDGeom vhd_geometry; - adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - - HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE); - settings_show_window(vhd_progress_hdlg, IDT_FILE_NAME, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_CFILE, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE, TRUE); - settings_enable_window(vhd_progress_hdlg, IDT_PROGRESS, TRUE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) vhd_geometry.cyl * vhd_geometry.heads * vhd_geometry.spt); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - - int vhd_error = 0; - MVHDMeta *vhd = mvhd_create_fixed(filename, vhd_geometry, &vhd_error, vhd_progress_callback); - if (vhd == NULL) { - _86box_geometry.cyl = 0; - _86box_geometry.heads = 0; - _86box_geometry.spt = 0; - } else { - mvhd_close(vhd); - } - - return _86box_geometry; -} - -static MVHDGeom -create_drive_vhd_dynamic(char *filename, int cyl, int heads, int spt, int blocksize) -{ - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; - MVHDGeom vhd_geometry; - adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = filename; - options.size_in_bytes = 0; - options.geometry = vhd_geometry; - options.type = MVHD_TYPE_DYNAMIC; - - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - if (vhd == NULL) { - _86box_geometry.cyl = 0; - _86box_geometry.heads = 0; - _86box_geometry.spt = 0; - } else { - mvhd_close(vhd); - } - - return _86box_geometry; -} - -static MVHDGeom -create_drive_vhd_diff(char *filename, char *parent_filename, int blocksize) -{ - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = filename; - options.parent_path = parent_filename; - options.type = MVHD_TYPE_DIFF; - - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; - if (vhd == NULL) { - vhd_geometry.cyl = 0; - vhd_geometry.heads = 0; - vhd_geometry.spt = 0; - } else { - vhd_geometry = mvhd_get_geometry(vhd); - - if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); - vhd_geometry.heads = 16; - vhd_geometry.spt = 63; - } - - mvhd_close(vhd); - } - - return vhd_geometry; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - FILE *fp; - uint32_t temp; - uint32_t i = 0; - uint32_t sector_size = 512; - uint32_t zero = 0; - uint32_t base = 0x1000; - uint64_t signature = 0xD778A82044445459LL; - uint64_t r = 0; - char *big_buf; - char hd_file_name_multibyte[1200]; - int b = 0; - int vhd_error = 0; - uint8_t channel = 0; - uint8_t id = 0; - wchar_t *twcs; - int img_format; - int block_size; - WCHAR text_buf[256]; - RECT rect; - POINT point; - int dlg_height_adjust; - - switch (message) { - case WM_INITDIALOG: - memset(hd_file_name, 0, sizeof(hd_file_name)); - - hdd_ptr = &(temp_hdd[next_free_id]); - - SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102)); - - no_update = 1; - spt = (existing & 1) ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = (existing & 1) ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = (existing & 1) ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL)); - hdconf_initialize_hdt_combo(hdlg); - - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4122)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4123)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4124)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4125)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4126)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4127)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT, 0); - - settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4128)); - settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4129)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE, 0); - - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE); - - if (existing & 1) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_IMG_FORMAT, FALSE); - settings_show_window(hdlg, IDT_IMG_FORMAT, FALSE); - - /* adjust window size */ - GetWindowRect(hdlg, &rect); - OffsetRect(&rect, -rect.left, -rect.top); - dlg_height_adjust = rect.bottom / 5; - SetWindowPos(hdlg, NULL, 0, 0, rect.right, rect.bottom - dlg_height_adjust, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER); - h = GetDlgItem(hdlg, IDOK); - GetWindowRect(h, &rect); - point.x = rect.left; - point.y = rect.top; - ScreenToClient(hdlg, &point); - SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER); - h = GetDlgItem(hdlg, IDCANCEL); - GetWindowRect(h, &rect); - point.x = rect.left; - point.y = rect.top; - ScreenToClient(hdlg, &point); - SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER); - - chs_enabled = 0; - } else - chs_enabled = 1; - - add_locations(hdlg); - hdd_ptr->bus = HDD_BUS_IDE; - max_spt = 255; - max_hpc = 255; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, hdd_ptr->bus - 1); - max_tracks = 266305; - recalc_location_controls(hdlg, 1, 0); - - channel = next_free_ide_channel(); - next_free_scsi_id(&id); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, 0); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, id); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, channel); - - new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); - new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); - new_hdd.xta_channel = next_free_binary_channel(&xta_tracking); - new_hdd.ide_channel = channel; - new_hdd.scsi_id = id; - - settings_enable_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(hdlg, IDT_PROGRESS, FALSE); - settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, FALSE); - - no_update = 0; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - hdd_ptr->bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - - /* Make sure no file name is allowed with removable SCSI hard disks. */ - if (wcslen(hd_file_name) == 0) { - hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4112); - return TRUE; - } - - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); - spt = hdd_ptr->spt; - hpc = hdd_ptr->hpc; - tracks = hdd_ptr->tracks; - - switch (hdd_ptr->bus) { - case HDD_BUS_MFM: - hdd_ptr->mfm_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_ESDI: - hdd_ptr->esdi_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_XTA: - hdd_ptr->xta_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - hdd_ptr->ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - break; - case HDD_BUS_SCSI: - hdd_ptr->scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID); - break; - } - - memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); - c16stombs(hdd_ptr->fn, hd_file_name, sizeof(hdd_ptr->fn)); - strcpy(hd_file_name_multibyte, hdd_ptr->fn); - - sector_size = 512; - - if (!(existing & 1) && (wcslen(hd_file_name) > 0)) { - if (size > 0x1FFFFFFE00LL) { - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4105); - return TRUE; - } - - img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); - if (img_format < IMG_FMT_VHD_FIXED) { - fp = _wfopen(hd_file_name, L"wb"); - } else { - fp = (FILE *) 0; - } - - if (img_format == IMG_FMT_HDI) { /* HDI file */ - if (size >= 0x100000000LL) { - fclose(fp); - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104); - return TRUE; - } - - fwrite(&zero, 1, 4, fp); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, fp); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, fp); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, fp); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - fwrite(&zero, 1, 4, fp); - } else if (img_format == IMG_FMT_HDX) { /* HDX file */ - fwrite(&signature, 1, 8, fp); /* 00000000: Signature */ - fwrite(&size, 1, 8, fp); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, fp); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, fp); /* 00000004: [Translation] Heads per cylinder */ - } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ - MVHDGeom _86box_geometry; - block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; - switch (img_format) { - case IMG_FMT_VHD_FIXED: - vhd_progress_hdlg = hdlg; - _86box_geometry = create_drive_vhd_fixed(hd_file_name_multibyte, tracks, hpc, spt); - break; - case IMG_FMT_VHD_DYNAMIC: - _86box_geometry = create_drive_vhd_dynamic(hd_file_name_multibyte, tracks, hpc, spt, block_size); - break; - case IMG_FMT_VHD_DIFF: - if (file_dlg_w(hdlg, plat_get_string(IDS_4130), L"", plat_get_string(IDS_4131), 0)) { - return TRUE; - } - _86box_geometry = create_drive_vhd_diff(hd_file_name_multibyte, openfilestring, block_size); - break; - } - - if (img_format != IMG_FMT_VHD_DIFF) - settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); - - hdd_ptr->tracks = _86box_geometry.cyl; - hdd_ptr->hpc = _86box_geometry.heads; - hdd_ptr->spt = _86box_geometry.spt; - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - } - - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); - - r = size >> 20; - size &= 0xfffff; - - if (size || r) { - settings_show_window(hdlg, IDT_FILE_NAME, FALSE); - settings_show_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(hdlg, IDC_CFILE, FALSE); - settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, TRUE); - settings_enable_window(hdlg, IDT_PROGRESS, TRUE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - } - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - - if (size) { - if (fp) { - fwrite(big_buf, 1, size, fp); - } - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - } - - if (r) { - for (i = 0; i < r; i++) { - if (fp) { - fwrite(big_buf, 1, 1048576, fp); - } - SendMessage(h, PBM_SETPOS, (i + 1), (LPARAM) 0); - - settings_process_messages(); - } - } - - free(big_buf); - - if (fp) { - fclose(fp); - } - settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; - hdd_ptr->bus = HDD_BUS_DISABLED; - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", NULL, !(existing & 1))) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - - if (!(existing & 1)) { - fp = _wfopen(wopenfilestring, L"rb"); - if (fp != NULL) { - fclose(fp); - if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ - return FALSE; - } - } - - fp = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (fp == NULL) { -hdd_add_file_open_error: - fclose(fp); - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; - } - if (existing & 1) { - if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) { - fseeko64(fp, 0x10, SEEK_SET); - fread(§or_size, 1, 4, fp); - if (sector_size != 512) { - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4119, (wchar_t *) IDS_4109); - fclose(fp); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, fp); - fread(&hpc, 1, 4, fp); - fread(&tracks, 1, 4, fp); - } else if (image_is_vhd(openfilestring, 1)) { - fclose(fp); - MVHDMeta *vhd = mvhd_open(openfilestring, 0, &vhd_error); - if (vhd == NULL) { - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; - } else if (vhd_error == MVHD_ERR_TIMESTAMP) { - if (settings_msgbox_ex(MBX_QUESTION_YN | MBX_WARNING, plat_get_string(IDS_4133), plat_get_string(IDS_4132), NULL, NULL, NULL) != 0) { - int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhd_error); - if (ts_res != 0) { - settings_msgbox_header(MBX_ERROR, plat_get_string(IDS_2049), plat_get_string(IDS_4134)); - mvhd_close(vhd); - return TRUE; - } - } else { - mvhd_close(vhd); - return TRUE; - } - } - - MVHDGeom vhd_geom = mvhd_get_geometry(vhd); - adjust_vhd_geometry_for_86box(&vhd_geom); - tracks = vhd_geom.cyl; - hpc = vhd_geom.heads; - spt = vhd_geom.spt; - size = (uint64_t) tracks * hpc * spt * 512; - mvhd_close(vhd); - } else { - fseeko64(fp, 0, SEEK_END); - size = ftello64(fp); - if (((size % 17) == 0) && (size <= 142606336)) { - spt = 17; - if (size <= 26738688) - hpc = 4; - else if (((size % 3072) == 0) && (size <= 53477376)) - hpc = 6; - else { - for (i = 5; i < 16; i++) { - if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) - break; - if (i == 5) - i++; - } - hpc = i; - } - } else { - spt = 63; - hpc = 16; - } - - tracks = ((size >> 9) / hpc) / spt; - } - - if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) - goto hdd_add_file_open_error; - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE); - - chs_enabled = 1; - - no_update = 0; - } - - fclose(fp); - } - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(hd_file_name, 0, sizeof(hd_file_name)); - wcscpy(hd_file_name, wopenfilestring); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (tracks != (int64_t) temp) { - tracks = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_HPC: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (hpc != (int64_t) temp) { - hpc = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (spt != (int64_t) temp) { - spt = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (uint32_t) (size >> 20)) { - size = ((uint64_t) temp) << 20LL; - /* This is needed to ensure VHD standard compliance. */ - hdd_image_calc_chs((uint32_t *) &tracks, (uint32_t *) &hpc, (uint32_t *) &spt, temp); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - return FALSE; - - no_update = 1; - temp = settings_get_cur_sel(hdlg, IDC_COMBO_HD_TYPE); - if ((temp != selection) && (temp != 127) && (temp != 128)) { - selection = temp; - tracks = hdd_table[selection][0]; - hpc = hdd_table[selection][1]; - spt = hdd_table[selection][2]; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } else if ((temp != selection) && (temp == 127)) - selection = temp; - else if ((temp != selection) && (temp == 128)) { - selection = temp; - hpc = 16; - spt = 63; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - return FALSE; - - no_update = 1; - recalc_location_controls(hdlg, 1, 0); - b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - if (b != hdd_ptr->bus) { - hdd_ptr->bus = b; - - switch (hdd_ptr->bus) { - default: - case HDD_BUS_DISABLED: - max_spt = max_hpc = max_tracks = 0; - break; - case HDD_BUS_MFM: - max_spt = 26; /* 17 for MFM, 26 for RLL. */ - max_hpc = 15; - max_tracks = 2047; - break; - case HDD_BUS_XTA: - max_spt = 63; - max_hpc = 16; - max_tracks = 1023; - break; - case HDD_BUS_ESDI: - max_spt = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_hpc = 16; - max_tracks = 266305; - break; - case HDD_BUS_IDE: - max_spt = 255; - max_hpc = 255; - max_tracks = 266305; - break; - case HDD_BUS_ATAPI: - case HDD_BUS_SCSI: - max_spt = 255; - max_hpc = 255; - max_tracks = 266305; - break; - } - - if (!chs_enabled) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - } - - no_update = 0; - break; - case IDC_COMBO_HD_IMG_FORMAT: - img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); - - no_update = 1; - if (img_format == IMG_FMT_VHD_DIFF) { /* They switched to a diff VHD; disable the geometry fields. */ - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_HPC, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_CYL, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SIZE, L"(N/A)"); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - settings_reset_content(hdlg, IDC_COMBO_HD_TYPE); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) L"(use parent)"); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, 0); - } else { - get_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, text_buf, 256); - if (!wcscmp(text_buf, L"(N/A)")) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); - spt = 17; - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, 15); - hpc = 15; - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, 1023); - tracks = 1023; - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) ((uint64_t) 17 * 15 * 1023 * 512 >> 20)); - size = (uint64_t) 17 * 15 * 1023 * 512; - - settings_reset_content(hdlg, IDC_COMBO_HD_TYPE); - hdconf_initialize_hdt_combo(hdlg); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE); - } - } - no_update = 0; - - if (img_format == IMG_FMT_VHD_DYNAMIC || img_format == IMG_FMT_VHD_DIFF) { /* For dynamic and diff VHDs, show the block size dropdown. */ - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, TRUE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, TRUE); - } else { /* Hide it otherwise. */ - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE); - } - break; - } - - return FALSE; - } - - return FALSE; -} - -int -hard_disk_was_added(void) -{ - return hard_disk_added; -} - -void -hard_disk_add_open(HWND hwnd, int is_existing) -{ - existing = is_existing; - hard_disk_added = 0; - DialogBox(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); -} - -static void -hard_disk_track(uint8_t id) -{ - switch (temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id >> 3] |= (1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); - break; - } -} - -static void -hard_disk_untrack(uint8_t id) -{ - switch (temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id >> 3] &= ~(1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); - break; - } -} - -static void -hard_disk_track_all(void) -{ - for (uint8_t i = 0; i < HDD_NUM; i++) - hard_disk_track(i); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - const uint8_t hd_icons[2] = { 80, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - win_settings_hard_disks_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons); - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) { - settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0); - lv1_current_sel = 0; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1); - } else - lv1_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_HARD_DISKS); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_HARD_DISKS)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_hard_disk(hdlg); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[lv1_current_sel].bus - 1); - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD) && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD_NEW) && (LOWORD(wParam) != IDC_BUTTON_HDD_REMOVE)) - return FALSE; - switch (LOWORD(wParam)) { - case IDC_COMBO_HD_BUS: - ignore_change = 1; - b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - if (b != temp_hdd[lv1_current_sel].bus) { - hard_disk_untrack(lv1_current_sel); - assign = (temp_hdd[lv1_current_sel].bus == b) ? 0 : 1; - temp_hdd[lv1_current_sel].bus = b; - recalc_location_controls(hdlg, 0, assign); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - } - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL_IDE: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, (LOWORD(wParam) == IDC_BUTTON_HDD_ADD)); - if (hard_disk_added) { - ignore_change = 1; - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - temp_hdd[lv1_current_sel].fn[0] = '\0'; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ - ignore_change = 1; - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - if (hd_listview_items > 0) { - settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0); - lv1_current_sel = 0; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1); - } else - lv1_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - return FALSE; - } - - case WM_DPICHANGED_AFTERPARENT: - win_settings_hard_disks_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -static int -combo_id_to_string_id(int combo_id) -{ - return IDS_5376 + combo_id; -} - -static int -combo_id_to_format_string_id(int combo_id) -{ - return IDS_5632 + combo_id; -} - -static BOOL -win_settings_floppy_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - char s[256]; - const char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.state = 0; - - for (uint8_t i = 0; i < FDD_NUM; i++) { - lvI.iSubItem = 0; - if (temp_fdd_types[i] > 0) { - t = fdd_getname(temp_fdd_types[i]); - strncpy(s, t, sizeof(s) - 1); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL -win_settings_cdrom_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < CDROM_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_cdrom[i].bus_type) { - default: - case CDROM_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - wsprintf(szText, L"%ix", temp_cdrom[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - -#if 0 - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; -#endif - } - - return TRUE; -} - -static BOOL -win_settings_mo_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - char szType[30]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < MO_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_mo_drives[i].bus_type) { - default: - case MO_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case MO_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case MO_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - memset(szType, 0, 30); - memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4); - - mbstowcs(szText, szType, strlen(szType) + 1); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL -win_settings_zip_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < ZIP_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_zip_drives[i].bus_type) { - default: - case ZIP_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -#define C_COLUMNS_FLOPPY_DRIVES_TYPE 292 -#define C_COLUMNS_FLOPPY_DRIVES_TURBO 58 -#define C_COLUMNS_FLOPPY_DRIVES_BPB 89 - -static void -win_settings_floppy_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_FLOPPY_DRIVES] = { - C_COLUMNS_FLOPPY_DRIVES_TYPE, - C_COLUMNS_FLOPPY_DRIVES_TURBO, - C_COLUMNS_FLOPPY_DRIVES_BPB - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - for (uint8_t iCol = 0; iCol < C_COLUMNS_FLOPPY_DRIVES; iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_FLOPPY_DRIVES - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_FLOPPY_DRIVES - 1]); -} - -static BOOL -win_settings_floppy_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Type */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Turbo */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2059); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TURBO; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - /* Check BPB */ - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_BPB); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_BPB; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - return FALSE; - - win_settings_floppy_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_CDROM_DRIVES_BUS 292 -#define C_COLUMNS_CDROM_DRIVES_SPEED 58 -#define C_COLUMNS_CDROM_DRIVES_EARLIER 89 - -static void -win_settings_cdrom_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_CDROM_DRIVES] = { - C_COLUMNS_CDROM_DRIVES_BUS, - C_COLUMNS_CDROM_DRIVES_SPEED, - C_COLUMNS_CDROM_DRIVES_EARLIER - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - for (uint8_t iCol = 0; iCol < C_COLUMNS_CDROM_DRIVES; iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_CDROM_DRIVES - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_CDROM_DRIVES - 1]); -} - -static BOOL -win_settings_cdrom_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Speed */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2053); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_SPEED; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2162); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_EARLIER; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - return FALSE; - - win_settings_cdrom_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_MO_DRIVES_BUS 292 -#define C_COLUMNS_MO_DRIVES_TYPE 147 - -static void -win_settings_mo_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_MO_DRIVES] = { - C_COLUMNS_MO_DRIVES_BUS, - C_COLUMNS_MO_DRIVES_TYPE - }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - width[0] = MulDiv(width[0], dpi, 96); - ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[C_COLUMNS_MO_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_MO_DRIVES - 1]); -} - -static BOOL -win_settings_mo_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_MO_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_MO_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - win_settings_mo_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_ZIP_DRIVES_BUS 292 -#define C_COLUMNS_ZIP_DRIVES_TYPE 147 - -static void -win_settings_zip_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_ZIP_DRIVES] = { - C_COLUMNS_ZIP_DRIVES_BUS, - C_COLUMNS_ZIP_DRIVES_TYPE - }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - width[0] = MulDiv(width[0], dpi, 96); - ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[C_COLUMNS_ZIP_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_ZIP_DRIVES - 1]); -} - -static BOOL -win_settings_zip_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_ZIP_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_ZIP_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - win_settings_zip_drives_resize_columns(hdlg); - return TRUE; -} - -static int -get_selected_drive(HWND hdlg, int id, int max) -{ - int drive = -1; - int j = 0; - HWND h; - - for (int i = 0; i < max; i++) { - h = GetDlgItem(hdlg, id); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - drive = i; - } - - return drive; -} - -static void -win_settings_floppy_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - char s[256]; - const char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) { - t = fdd_getname(temp_fdd_types[i]); - strncpy(s, t, sizeof(s) - 1); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iImage = temp_fdd_types[i]; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -win_settings_cdrom_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type); - - switch (temp_cdrom[i].bus_type) { - default: - case CDROM_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - wsprintf(szText, L"%ix", temp_cdrom[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - -#if 0 - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -#endif -} - -static void -win_settings_mo_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - char szType[30]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - /* Bus */ - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type); - - switch (temp_mo_drives[i].bus_type) { - default: - case MO_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case MO_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case MO_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - /* Type */ - lvI.iSubItem = 1; - if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - memset(szType, 0, 30); - memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4); - mbstowcs(szText, szType, strlen(szType) + 1); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -win_settings_zip_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - switch (temp_zip_drives[i].bus_type) { - default: - case ZIP_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -cdrom_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) { - if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_CD_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 1; i <= 72; i++) { - wsprintf(lptsTemp, L"%ix", i); - settings_add_string(hdlg, IDC_COMBO_CD_SPEED, (LPARAM) lptsTemp); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_CD_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_CD_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void -cdrom_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_cdrom[lv2_current_sel].bus_type; - - for (uint16_t i = IDT_CD_ID; i <= IDT_CD_CHANNEL; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_SPEED, bus != CDROM_BUS_DISABLED); - settings_show_window(hdlg, IDT_CD_SPEED, bus != CDROM_BUS_DISABLED); -#if 0 - settings_show_window(hdlg, IDC_COMBO_CD_TYPE, bus != CDROM_BUS_DISABLED); -#endif - if (bus != CDROM_BUS_DISABLED) { - settings_set_cur_sel(hdlg, IDC_COMBO_CD_SPEED, temp_cdrom[lv2_current_sel].speed - 1); -#if 0 - settings_set_check(hdlg, IDC_COMBO_CD_TYPE, temp_cdrom[lv2_current_sel].early); -#endif - } - - switch (bus) { - case CDROM_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_CD_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_cdrom[lv2_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE, temp_cdrom[lv2_current_sel].ide_channel); - break; - case CDROM_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_CD_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_CD_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_cdrom[lv2_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_CD_ID, temp_cdrom[lv2_current_sel].scsi_device_id); - break; - } -} - -static void -mo_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - char *temp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - temp = (char *) malloc(30 * sizeof(char)); - - for (i = MO_BUS_DISABLED; i <= MO_BUS_SCSI; i++) { - if ((i == MO_BUS_DISABLED) || (i >= MO_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_MO_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_MO_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_MO_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - for (int i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { - memset(temp, 0, 30); - memcpy(temp, mo_drive_types[i].vendor, 8); - temp[strlen(temp)] = ' '; - memcpy(temp + strlen(temp), mo_drive_types[i].model, 16); - temp[strlen(temp)] = ' '; - memcpy(temp + strlen(temp), mo_drive_types[i].revision, 4); - - mbstowcs(lptsTemp, temp, strlen(temp) + 1); - settings_add_string(hdlg, IDC_COMBO_MO_TYPE, (LPARAM) lptsTemp); - } - - free(temp); - free(lptsTemp); -} - -static void -mo_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_mo_drives[lv1_current_sel].bus_type; - - for (int i = IDT_MO_ID; i <= IDT_MO_CHANNEL; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_TYPE, bus != MO_BUS_DISABLED); - settings_show_window(hdlg, IDT_MO_TYPE, bus != MO_BUS_DISABLED); - - if (bus != MO_BUS_DISABLED) - settings_set_cur_sel(hdlg, IDC_COMBO_MO_TYPE, temp_mo_drives[lv1_current_sel].type); - - switch (bus) { - case MO_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_MO_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_mo_drives[lv1_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE, temp_mo_drives[lv1_current_sel].ide_channel); - break; - case MO_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_MO_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_mo_drives[lv1_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_MO_ID, temp_mo_drives[lv1_current_sel].scsi_device_id); - break; - } -} - -static void -zip_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) { - if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_ZIP_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_LUN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_ZIP_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void -zip_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_zip_drives[lv2_current_sel].bus_type; - - for (int i = IDT_ZIP_ID; i <= IDT_ZIP_LUN; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_ZIP_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_CHECK250, bus != ZIP_BUS_DISABLED); - - if (bus != ZIP_BUS_DISABLED) - settings_set_check(hdlg, IDC_CHECK250, temp_zip_drives[lv2_current_sel].is_250); - - switch (bus) { - case ZIP_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_ZIP_LUN, TRUE); - settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_zip_drives[lv2_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, temp_zip_drives[lv2_current_sel].ide_channel); - break; - case ZIP_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_ZIP_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_zip_drives[lv2_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_ID, temp_zip_drives[lv2_current_sel].scsi_device_id); - break; - } -} - -static void -cdrom_track(uint8_t id) -{ - if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (temp_cdrom[id].ide_channel << 3)); - else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] |= (1 << (temp_cdrom[id].scsi_device_id & 0x07)); -} - -static void -cdrom_untrack(uint8_t id) -{ - if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking &= ~(2 << (temp_cdrom[id].ide_channel << 3)); - else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] &= ~(1 << (temp_cdrom[id].scsi_device_id & 0x07)); -} - -static void -zip_track(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] |= (1 << (temp_zip_drives[id].scsi_device_id & 0x07)); -} - -static void -zip_untrack(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_zip_drives[id].scsi_device_id & 0x07)); -} - -static void -mo_track(uint8_t id) -{ - if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking |= (1 << (temp_mo_drives[id].ide_channel << 3)); - else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) - scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] |= (1 << (temp_mo_drives[id].scsi_device_id & 0x07)); -} - -static void -mo_untrack(uint8_t id) -{ - if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking &= ~(1 << (temp_mo_drives[id].ide_channel << 3)); - else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) - scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_mo_drives[id].scsi_device_id & 0x07)); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - uint32_t b2 = 0; - WCHAR szText[256]; - const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 }; - const uint8_t cd_icons[3] = { 249, 32, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - lv1_current_sel = 0; - win_settings_floppy_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons); - win_settings_floppy_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_FLOPPY_DRIVES, 0); - for (uint8_t i = 0; i < 14; i++) { - if (i == 0) - settings_add_string(hdlg, IDC_COMBO_FD_TYPE, win_get_string(IDS_5376)); - else { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - settings_add_string(hdlg, IDC_COMBO_FD_TYPE, (LPARAM) szText); - } - } - settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]); - - settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]); - - settings_listview_enable_styles(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lv2_current_sel = 0; - win_settings_cdrom_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons); - win_settings_cdrom_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_CDROM_DRIVES, 0); - cdrom_add_locations(hdlg); - - switch (temp_cdrom[lv2_current_sel].bus_type) { - default: - case CDROM_BUS_DISABLED: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b); - cdrom_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_CDROM_DRIVES); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES, FDD_NUM); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]); - ignore_change = 0; - } else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) { - old_sel = lv2_current_sel; - lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES, CDROM_NUM); - if (lv2_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_cdrom[lv2_current_sel].bus_type) { - default: - case CDROM_BUS_DISABLED: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b); - - cdrom_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change) - return FALSE; - - ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_FD_TYPE: - temp_fdd_types[lv1_current_sel] = settings_get_cur_sel(hdlg, IDC_COMBO_FD_TYPE); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_CHECKTURBO: - temp_fdd_turbo[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKTURBO); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_CHECKBPB: - temp_fdd_check_bpb[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKBPB); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_CD_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_CD_BUS); - switch (b) { - case 0: - b2 = CDROM_BUS_DISABLED; - break; - case 1: - b2 = CDROM_BUS_ATAPI; - break; - case 2: - b2 = CDROM_BUS_SCSI; - break; - } - if (b2 == temp_cdrom[lv2_current_sel].bus_type) - break; - cdrom_untrack(lv2_current_sel); - assign = (temp_cdrom[lv2_current_sel].bus_type == b2) ? 0 : 1; - if (temp_cdrom[lv2_current_sel].bus_type == CDROM_BUS_DISABLED) - temp_cdrom[lv2_current_sel].speed = 8; - temp_cdrom[lv2_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg, assign); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_ID: - cdrom_untrack(lv2_current_sel); - temp_cdrom[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_CD_ID); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_CHANNEL_IDE: - cdrom_untrack(lv2_current_sel); - temp_cdrom[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_SPEED: - temp_cdrom[lv2_current_sel].speed = settings_get_cur_sel(hdlg, IDC_COMBO_CD_SPEED) + 1; - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - -#if 0 - case IDC_COMBO_CD_TYPE:: - temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_COMBO_CD_TYPE:); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; -#endif - } - ignore_change = 0; - - case WM_DPICHANGED_AFTERPARENT: - win_settings_floppy_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons); - win_settings_cdrom_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - uint32_t b2 = 0; - const uint8_t mo_icons[3] = { 251, 56, 0 }; - const uint8_t zip_icons[3] = { 250, 48, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - lv1_current_sel = 0; - win_settings_mo_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons); - win_settings_mo_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_MO_DRIVES, 0); - mo_add_locations(hdlg); - - switch (temp_mo_drives[lv1_current_sel].bus_type) { - default: - case MO_BUS_DISABLED: - b = 0; - break; - case MO_BUS_ATAPI: - b = 1; - break; - case MO_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b); - mo_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_MO_DRIVES); - - lv2_current_sel = 0; - win_settings_zip_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons); - win_settings_zip_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_ZIP_DRIVES, 0); - zip_add_locations(hdlg); - - switch (temp_zip_drives[lv2_current_sel].bus_type) { - default: - case ZIP_BUS_DISABLED: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b); - zip_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_ZIP_DRIVES); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_MO_DRIVES)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES, MO_NUM); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_mo_drives[lv1_current_sel].bus_type) { - default: - case MO_BUS_DISABLED: - b = 0; - break; - case MO_BUS_ATAPI: - b = 1; - break; - case MO_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b); - - mo_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) { - old_sel = lv2_current_sel; - lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES, ZIP_NUM); - if (lv2_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_zip_drives[lv2_current_sel].bus_type) { - default: - case ZIP_BUS_DISABLED: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b); - - zip_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change) - return FALSE; - - ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_MO_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_MO_BUS); - switch (b) { - case 0: - b2 = MO_BUS_DISABLED; - break; - case 1: - b2 = MO_BUS_ATAPI; - break; - case 2: - b2 = MO_BUS_SCSI; - break; - } - if (b2 == temp_mo_drives[lv1_current_sel].bus_type) - break; - mo_untrack(lv1_current_sel); - assign = (temp_mo_drives[lv1_current_sel].bus_type == b2) ? 0 : 1; - if (temp_mo_drives[lv1_current_sel].bus_type == MO_BUS_DISABLED) - temp_mo_drives[lv1_current_sel].type = 0; - temp_mo_drives[lv1_current_sel].bus_type = b2; - mo_recalc_location_controls(hdlg, assign); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_ID: - mo_untrack(lv1_current_sel); - temp_mo_drives[lv1_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_MO_ID); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_CHANNEL_IDE: - mo_untrack(lv1_current_sel); - temp_mo_drives[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_TYPE: - temp_mo_drives[lv1_current_sel].type = settings_get_cur_sel(hdlg, IDC_COMBO_MO_TYPE); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_ZIP_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_BUS); - switch (b) { - case 0: - b2 = ZIP_BUS_DISABLED; - break; - case 1: - b2 = ZIP_BUS_ATAPI; - break; - case 2: - b2 = ZIP_BUS_SCSI; - break; - } - if (b2 == temp_zip_drives[lv2_current_sel].bus_type) - break; - zip_untrack(lv2_current_sel); - assign = (temp_zip_drives[lv2_current_sel].bus_type == b2) ? 0 : 1; - temp_zip_drives[lv2_current_sel].bus_type = b2; - zip_recalc_location_controls(hdlg, assign); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_ZIP_ID: - zip_untrack(lv2_current_sel); - temp_zip_drives[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_ID); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_ZIP_CHANNEL_IDE: - zip_untrack(lv2_current_sel); - temp_zip_drives[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_CHECK250: - temp_zip_drives[lv2_current_sel].is_250 = settings_get_check(hdlg, IDC_CHECK250); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - } - ignore_change = 0; - - case WM_DPICHANGED_AFTERPARENT: - win_settings_mo_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons); - win_settings_zip_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - int e; - LPTSTR lptsTemp; - char *stransi; - const device_t *dev; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - /* Populate the ISA RTC card dropdown. */ - e = 0; - settings_reset_content(hdlg, IDC_COMBO_ISARTC); - for (d = 0;; d++) { - generate_device_name(isartc_get_device(d), isartc_get_internal_name(d), 0); - - if (!device_name[0]) - break; - dev = isartc_get_device(d); - if (device_is_valid(dev, temp_machine)) { - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2104)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name); - settings_list_to_device[1][e] = d; - if (d == temp_isartc) - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e); - e++; - } - } - settings_enable_window(hdlg, IDC_COMBO_ISARTC, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, ((temp_isartc != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - - /* Populate the ISA memory card dropdowns. */ - for (c = 0; c < ISAMEM_MAX; c++) { - e = 0; - settings_reset_content(hdlg, IDC_COMBO_ISAMEM_1 + c); - for (d = 0;; d++) { - generate_device_name(isamem_get_device(d), (char *) isamem_get_internal_name(d), 0); - - if (!device_name[0]) - break; - - dev = isamem_get_device(d); - if (device_is_valid(dev, temp_machine)) { - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2104)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name); - settings_list_to_device[0][e] = d; - if (d == temp_isamem[c]) - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, e); - e++; - } - } - settings_enable_window(hdlg, IDC_COMBO_ISAMEM_1 + c, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, ((temp_isamem[c] != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - } - - settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_set_check(hdlg, IDC_CHECK_BUGGER, (temp_bugger && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard); - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIGURE_ISARTC: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) isartc_get_device(temp_isartc)); - break; - - case IDC_COMBO_ISARTC: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, temp_isartc != 0); - break; - - case IDC_COMBO_ISAMEM_1: - case IDC_COMBO_ISAMEM_2: - case IDC_COMBO_ISAMEM_3: - case IDC_COMBO_ISAMEM_4: - c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1; - temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, LOWORD(wParam))]; - settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0); - break; - - case IDC_CONFIGURE_ISAMEM_1: - case IDC_CONFIGURE_ISAMEM_2: - case IDC_CONFIGURE_ISAMEM_3: - case IDC_CONFIGURE_ISAMEM_4: - c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1; - temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) isamem_get_device(temp_isamem[c]), c + 1); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - for (c = 0; c < ISAMEM_MAX; c++) { - temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c)]; - } - temp_bugger = settings_get_check(hdlg, IDC_CHECK_BUGGER); - temp_postcard = settings_get_check(hdlg, IDC_CHECK_POSTCARD); - - default: - return FALSE; - } - return FALSE; -} - -void -win_settings_show_child(HWND hwndParent, DWORD child_id) -{ - if (child_id == displayed_category) - return; - else - displayed_category = child_id; - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch (child_id) { - case SETTINGS_PAGE_MACHINE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case SETTINGS_PAGE_VIDEO: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); - break; - case SETTINGS_PAGE_INPUT: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_INPUT, hwndParent, win_settings_input_proc); - break; - case SETTINGS_PAGE_SOUND: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); - break; - case SETTINGS_PAGE_NETWORK: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); - break; - case SETTINGS_PAGE_PORTS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PORTS, hwndParent, win_settings_ports_proc); - break; - case SETTINGS_PAGE_STORAGE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_STORAGE, hwndParent, win_settings_storage_proc); - break; - case SETTINGS_PAGE_HARD_DISKS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case SETTINGS_PAGE_FLOPPY_AND_CDROM_DRIVES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_FLOPPY_AND_CDROM_DRIVES, hwndParent, win_settings_floppy_and_cdrom_drives_proc); - break; - case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc); - break; - case SETTINGS_PAGE_PERIPHERALS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); -} - -static BOOL -win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < 11; i++) { - lvI.pszText = plat_get_string(IDS_2065 + i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_confirm(HWND hdlg) -{ - int i; - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - if (win_settings_changed()) { - if (confirm_save && !settings_only) - i = settings_msgbox_ex(MBX_QUESTION_OK | MBX_WARNING | MBX_DONTASK, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123, (wchar_t *) IDS_2124, NULL, NULL); - else - i = 0; - - if (i == 10) { - confirm_save = 0; - i = 0; - } - - if (i == 0) - win_settings_save(); - else - return FALSE; - } - - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; -} - -static void -win_settings_categories_resize_columns(HWND hdlg) -{ - HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - RECT r; - - GetWindowRect(hwndList, &r); - ListView_SetColumnWidth(hwndList, 0, (r.right - r.left) + 1 - 5); -} - -static BOOL -win_settings_categories_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - int iCol = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(2048); - - lvc.cx = 171; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - return FALSE; - - win_settings_categories_resize_columns(hdlg); - return TRUE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h = NULL; - int category; - int j = 0; - const uint8_t cat_icons[12] = { 240, 241, 242, 243, 96, 244, 252, 80, 246, 247, 245, 0 }; - - hwndParentDialog = hdlg; - - switch (message) { - case WM_INITDIALOG: - dpi = win_get_dpi(hdlg); - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - win_settings_categories_init_columns(hdlg); - image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons); - win_settings_main_insert_categories(h); - settings_listview_select(hdlg, IDC_SETTINGSCATLIST, first_cat); - settings_listview_enable_styles(hdlg, IDC_SETTINGSCATLIST); - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_SETTINGSCATLIST)) { - category = -1; - for (uint8_t i = 0; i < 11; i++) { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - category = i; - } - if (category != -1) - win_settings_show_child(hdlg, category); - } - break; - case WM_CLOSE: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - return win_settings_confirm(hdlg); - case IDCANCEL: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; - } - break; - - case WM_DPICHANGED: - dpi = HIWORD(wParam); - win_settings_categories_resize_columns(hdlg); - image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -void -win_settings_open_ex(HWND hwnd, int category) -{ - win_notify_dlg_open(); - - first_cat = category; - DialogBox(hinstance, (LPCWSTR) DLG_CONFIG, hwnd, win_settings_main_proc); -} - -void -win_settings_open(HWND hwnd) -{ - win_settings_open_ex(hwnd, SETTINGS_PAGE_MACHINE); -} diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c deleted file mode 100644 index 5297661bf..000000000 --- a/src/win/win_snd_gain.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - * - * Handle the sound gain dialog. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/sound.h> -#include <86box/win.h> - -static uint8_t old_gain; - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - - switch (message) { - case WM_INITDIALOG: - old_gain = sound_gain; - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - SendMessage(h, TBM_SETRANGE, (WPARAM) 1, MAKELONG(0, 9)); - SendMessage(h, TBM_SETPOS, (WPARAM) 1, 9 - (sound_gain >> 1)); - SendMessage(h, TBM_SETTICFREQ, (WPARAM) 1, 0); - SendMessage(h, TBM_SETLINESIZE, (WPARAM) 0, 1); - SendMessage(h, TBM_SETPAGESIZE, (WPARAM) 0, 2); - break; - - case WM_VSCROLL: - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1; - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1; - config_save(); - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - sound_gain = old_gain; - config_save(); - EndDialog(hdlg, 0); - return TRUE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -SoundGainDialogCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_SND_GAIN, hwnd, SoundGainDialogProcedure); -} diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c deleted file mode 100644 index 5bedb846d..000000000 --- a/src/win/win_specify_dim.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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. - * - * Handle the dialog for specifying the dimensions of the main window. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/video.h> -#include <86box/sound.h> -#include <86box/win.h> - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - HWND h2; - HMENU hmenu; - UDACCEL accel; - UDACCEL accel2; - RECT r; - uint32_t temp_x = 0; - uint32_t temp_y = 0; - int dpi = 96; - int lock; - LPTSTR lptsTemp; - char *stransi; - - switch (message) { - case WM_INITDIALOG: - GetWindowRect(hwndRender, &r); - - h = GetDlgItem(hdlg, IDC_WIDTHSPIN); - h2 = GetDlgItem(hdlg, IDC_EDIT_WIDTH); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); - accel.nSec = 0; - accel.nInc = 8; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - SendMessage(h, UDM_SETPOS, 0, r.right - r.left); - - h = GetDlgItem(hdlg, IDC_HEIGHTSPIN); - h2 = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); - accel2.nSec = 0; - accel2.nInc = 8; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel2); - SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top); - - h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); - SendMessage(h, BM_SETCHECK, !!(vid_resize & 2), 0); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_EDIT_WIDTH); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_x); - fixed_size_x = temp_x; - - h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_y); - fixed_size_y = temp_y; - - h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); - lock = SendMessage(h, BM_GETCHECK, 0, 0); - - if (lock) { - vid_resize = 2; - window_remember = 0; - } else { - vid_resize = 1; - window_remember = 1; - } - hmenu = GetMenu(hwndMain); - CheckMenuItem(hmenu, IDM_VID_REMEMBER, (window_remember == 1) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize == 1) ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 2) ? MF_GRAYED : MF_ENABLED); - - if (vid_resize == 1) - SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); - else - SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); - - /* scale the screen base on DPI */ - if (dpi_scale) { - dpi = win_get_dpi(hwndMain); - temp_x = MulDiv(temp_x, dpi, 96); - temp_y = MulDiv(temp_y, dpi, 96); - } - - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height + tbar_height); - - if (vid_resize) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_5X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_6X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_7X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_8X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_9X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_10X, vid_resize ? MF_GRAYED : MF_ENABLED); - - scrnsz_x = fixed_size_x; - scrnsz_y = fixed_size_y; - atomic_store(&doresize_monitors[0], 1); - - GetWindowRect(hwndMain, &r); - - if (mouse_capture) - ClipCursor(&r); - - if (window_remember || (vid_resize & 2)) { - window_x = r.left; - window_y = r.top; - if (!(vid_resize & 2)) { - window_w = r.right - r.left; - window_h = r.bottom - r.top; - } - } - - config_save(); - - free(stransi); - free(lptsTemp); - - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -SpecifyDimensionsDialogCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_SPECIFY_DIM, hwnd, SpecifyDimensionsDialogProcedure); -} diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c deleted file mode 100644 index 2cf8d84f4..000000000 --- a/src/win/win_stbar.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * 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. - * - * Implement the application's Status Bar. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include "cpu.h" -#include <86box/device.h> -#include <86box/machine.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/hdd.h> -#include <86box/hdc.h> -#include <86box/fdd.h> -#include <86box/fdd_86f.h> -#include <86box/scsi.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/zip.h> -#include <86box/mo.h> -#include <86box/cdrom_image.h> -#include <86box/scsi_disk.h> -#include <86box/thread.h> -#include <86box/network.h> -#include <86box/video.h> -#include <86box/sound.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -HWND hwndSBAR; -int update_icons = 1; -int reset_occurred = 1; - -static LONG_PTR OriginalProcedure; -static WCHAR **sbTips; -static int *iStatusWidths; -static int *sb_part_meanings; -static uint8_t *sb_part_icons; -static int sb_parts = 0; -static int sb_ready = 0; -static uint8_t sb_map[256]; -static int icon_width = 24; -static wchar_t sb_text[512] = L"\0"; -static wchar_t sb_bugtext[512] = L"\0"; - -/* Also used by win_settings.c */ -intptr_t -fdd_type_to_icon(int type) -{ - int ret = 248; - - switch (type) { - case 0: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - ret = 16; - break; - - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - ret = 24; - break; - - default: - break; - } - - return ret; -} - -/* FIXME: should be hdd_count() in hdd.c */ -static int -hdd_count(int bus) -{ - int c = 0; - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == bus) - c++; - } - - return c; -} - -void -ui_sb_timer_callback(int pane) -{ - if (!(reset_occurred & 1)) { - sb_part_icons[pane] &= ~1; - - if (sb_part_icons && sb_part_icons[pane]) { - SendMessage(hwndSBAR, SB_SETICON, pane, - (LPARAM) hIcon[sb_part_icons[pane]]); - } - } else - reset_occurred &= ~1; - - reset_occurred &= ~2; -} - -/* API */ -/* API: update one of the icons after activity. */ -void -ui_sb_update_icon(int tag, int active) -{ - uint8_t found = 0xff; - - if (!update_icons || !sb_ready) - return; - - if ((tag & 0xf0) >= SB_TEXT) - return; - - found = sb_map[tag]; - if ((found != 0xff) && ((sb_part_icons[found] ^ active) & 1) && active) { - sb_part_icons[found] |= 1; - - PostMessage(hwndSBAR, SB_SETICON, found, - (LPARAM) hIcon[sb_part_icons[found]]); - - reset_occurred = 2; - SetTimer(hwndMain, 0x8000 | found, 75, NULL); - } -} - -/* API: This is for the drive state indicator. */ -void -ui_sb_update_icon_state(int tag, int state) -{ - uint8_t found = 0xff; - - if (!sb_ready || ((tag & 0xf0) >= SB_HDD)) - return; - - found = sb_map[tag]; - if (found != 0xff) { - sb_part_icons[found] &= ~128; - sb_part_icons[found] |= (state ? 128 : 0); - - SendMessage(hwndSBAR, SB_SETICON, found, - (LPARAM) hIcon[sb_part_icons[found]]); - } -} - -static void -StatusBarCreateCassetteTip(int part) -{ - WCHAR tempTip[512]; - WCHAR fn[512]; - - if (strlen(cassette_fname) == 0) - _swprintf(tempTip, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); - else { - mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2149), fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateCartridgeTip(int part) -{ - WCHAR tempTip[512]; - WCHAR fn[512]; - int drive = sb_part_meanings[part] & 0xf; - - if (strlen(cart_fns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2151), - drive + 1, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2151), - drive + 1, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateFloppyTip(int part) -{ - WCHAR wtext[512]; - WCHAR tempTip[512]; - WCHAR fn[512]; - - int drive = sb_part_meanings[part] & 0xf; - - mbstoc16s(wtext, fdd_getname(fdd_get_type(drive)), - strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (strlen(floppyfns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2109), - drive + 1, wtext, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2109), - drive + 1, wtext, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateCdromTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = cdrom[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - if (cdrom[drive].host_drive == 200) { - if (strlen(cdrom[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_5120), - drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cdrom[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_5120), - drive + 1, szText, fn); - } - } else - _swprintf(tempTip, plat_get_string(IDS_5120), drive + 1, szText, plat_get_string(IDS_2057)); - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 4); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateZIPTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = zip_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - int type = zip_drives[drive].is_250 ? 250 : 100; - - if (strlen(zip_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, zip_drives[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive + 1, szText, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateMOTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = mo_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2116), - drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2116), - drive + 1, szText, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateDiskTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int bus = sb_part_meanings[part] & 0xf; - - id = IDS_4352 + (bus - 1); - szText = plat_get_string(id); - - _swprintf(tempTip, plat_get_string(IDS_4096), szText); - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateNetworkTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2069)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateSoundTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2068)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -/* API */ -void -ui_sb_update_tip(int meaning) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) - return; - - part = sb_map[meaning]; - - if (part != 0xff) { - switch (meaning & 0xf0) { - case SB_CASSETTE: - StatusBarCreateCassetteTip(part); - break; - - case SB_CARTRIDGE: - StatusBarCreateCartridgeTip(part); - break; - - case SB_FLOPPY: - StatusBarCreateFloppyTip(part); - break; - - case SB_CDROM: - StatusBarCreateCdromTip(part); - break; - - case SB_ZIP: - StatusBarCreateZIPTip(part); - break; - - case SB_MO: - StatusBarCreateMOTip(part); - break; - - case SB_HDD: - StatusBarCreateDiskTip(part); - break; - - case SB_NETWORK: - StatusBarCreateNetworkTip(part); - break; - - case SB_SOUND: - StatusBarCreateSoundTip(part); - break; - - default: - break; - } - - SendMessage(hwndSBAR, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); - } -} - -static void -StatusBarDestroyTips(void) -{ - if (sb_parts == 0) - return; - - if (!sbTips) - return; - - for (int i = 0; i < sb_parts; i++) { - if (sbTips[i]) { - free(sbTips[i]); - sbTips[i] = NULL; - } - } - - free(sbTips); - sbTips = NULL; -} - -/* API: mark the status bar as not ready. */ -/* Values: -1 - not ready, but don't clear POST text - 0 - not ready - 1 - ready */ -void -ui_sb_set_ready(int ready) -{ - if (ready == 0) { - ui_sb_bugui(NULL); - ui_sb_set_text(NULL); - } - - if (ready == -1) - ready = 0; - - sb_ready = ready; -} - -/* API: update the status bar panes. */ -void -ui_sb_update_panes(void) -{ - int i; - int id; - int cart_int; - int mfm_int; - int xta_int; - int esdi_int; - int ide_int; - int scsi_int; - int edge = 0; - int c_mfm; - int c_esdi; - int c_xta; - int c_ide; - int c_scsi; - int do_net; - const char *hdc_name; - - if (!config_changed) - return; - - if (sb_ready) { - sb_ready = 0; - } - - cart_int = machine_has_cartridge(machine) ? 1 : 0; - mfm_int = machine_has_flags(machine, MACHINE_MFM) ? 1 : 0; - xta_int = machine_has_flags(machine, MACHINE_XTA) ? 1 : 0; - esdi_int = machine_has_flags(machine, MACHINE_ESDI) ? 1 : 0; - ide_int = machine_has_flags(machine, MACHINE_IDE_QUAD) ? 1 : 0; - scsi_int = machine_has_flags(machine, MACHINE_SCSI) ? 1 : 0; - - c_mfm = hdd_count(HDD_BUS_MFM); - c_esdi = hdd_count(HDD_BUS_ESDI); - c_xta = hdd_count(HDD_BUS_XTA); - c_ide = hdd_count(HDD_BUS_IDE); - c_scsi = hdd_count(HDD_BUS_SCSI); - do_net = network_available(); - - media_menu_reset(); - - if (sb_parts > 0) { - for (i = 0; i < sb_parts; i++) - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) NULL); - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) 0, (LPARAM) NULL); - - if (iStatusWidths) { - free(iStatusWidths); - iStatusWidths = NULL; - } - if (sb_part_meanings) { - free(sb_part_meanings); - sb_part_meanings = NULL; - } - if (sb_part_icons) { - free(sb_part_icons); - sb_part_icons = NULL; - } - StatusBarDestroyTips(); - } - - memset(sb_map, 0xff, sizeof(sb_map)); - - sb_parts = 0; - if (cassette_enable) - sb_parts++; - if (cart_int) - sb_parts += 2; - for (i = 0; i < FDD_NUM; i++) { - if (fdd_get_type(i) != 0) - sb_parts++; - } - hdc_name = hdc_get_internal_name(hdc_current); - for (i = 0; i < CDROM_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (cdrom[i].bus_type != 0) - sb_parts++; - } - for (i = 0; i < ZIP_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (zip_drives[i].bus_type != 0) - sb_parts++; - } - for (i = 0; i < MO_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (mo_drives[i].bus_type != 0) - sb_parts++; - } - if (c_mfm && (mfm_int || !memcmp(hdc_name, "st506", 5))) { - /* MFM drives, and MFM or Internal controller. */ - sb_parts++; - } - if (c_esdi && (esdi_int || !memcmp(hdc_name, "esdi", 4))) { - /* ESDI drives, and ESDI or Internal controller. */ - sb_parts++; - } - if (c_xta && (xta_int || !memcmp(hdc_name, "xta", 3))) - sb_parts++; - if (c_ide && (ide_int || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3))) - sb_parts++; - if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0))) - sb_parts++; - if (do_net) - sb_parts++; - sb_parts += 2; - - iStatusWidths = (int *) malloc(sb_parts * sizeof(int)); - memset(iStatusWidths, 0, sb_parts * sizeof(int)); - sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); - memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (uint8_t *) malloc(sb_parts * sizeof(uint8_t)); - memset(sb_part_icons, 0, sb_parts * sizeof(uint8_t)); - sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); - memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); - - sb_parts = 0; - if (cassette_enable) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CASSETTE; - sb_map[SB_CASSETTE] = sb_parts; - sb_parts++; - } - for (i = 0; i < 2; i++) { - if (cart_int) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CARTRIDGE | i; - sb_map[SB_CARTRIDGE | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < FDD_NUM; i++) { - if (fdd_get_type(i) != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_FLOPPY | i; - sb_map[SB_FLOPPY | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < CDROM_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (cdrom[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CDROM | i; - sb_map[SB_CDROM | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < ZIP_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (zip_drives[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_ZIP | i; - sb_map[SB_ZIP | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < MO_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (mo_drives[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_MO | i; - sb_map[SB_MO | i] = sb_parts; - sb_parts++; - } - } - if (c_mfm && (mfm_int || !memcmp(hdc_name, "st506", 5))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM; - sb_map[SB_HDD | HDD_BUS_MFM] = sb_parts; - sb_parts++; - } - if (c_esdi && (esdi_int || !memcmp(hdc_name, "esdi", 4))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI; - sb_map[SB_HDD | HDD_BUS_ESDI] = sb_parts; - sb_parts++; - } - if (c_xta && (xta_int || !memcmp(hdc_name, "xta", 3))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTA; - sb_map[SB_HDD | HDD_BUS_XTA] = sb_parts; - sb_parts++; - } - if (c_ide && (ide_int || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE; - sb_map[SB_HDD | HDD_BUS_IDE] = sb_parts; - sb_parts++; - } - if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI; - sb_map[SB_HDD | HDD_BUS_SCSI] = sb_parts; - sb_parts++; - } - if (do_net) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_NETWORK; - sb_map[SB_NETWORK] = sb_parts; - sb_parts++; - } - - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_SOUND; - sb_map[SB_SOUND] = sb_parts; - sb_parts++; - - if (sb_parts) - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = SB_TEXT; - sb_map[SB_TEXT] = sb_parts; - sb_parts++; - - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - - for (i = 0; i < sb_parts; i++) { - switch (sb_part_meanings[i] & 0xf0) { - case SB_CASSETTE: /* Cassette */ - sb_part_icons[i] = (strlen(cassette_fname) == 0) ? 128 : 0; - sb_part_icons[i] |= 64; - StatusBarCreateCassetteTip(i); - break; - - case SB_CARTRIDGE: /* Cartridge */ - sb_part_icons[i] = (strlen(cart_fns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0; - sb_part_icons[i] |= 104; - StatusBarCreateCartridgeTip(i); - break; - - case SB_FLOPPY: /* Floppy */ - sb_part_icons[i] = (strlen(floppyfns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0; - sb_part_icons[i] |= fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)); - StatusBarCreateFloppyTip(i); - break; - - case SB_CDROM: /* CD-ROM */ - id = sb_part_meanings[i] & 0xf; - if (cdrom[id].host_drive == 200) - sb_part_icons[i] = (strlen(cdrom[id].image_path) == 0) ? 128 : 0; - else - sb_part_icons[i] = 128; - sb_part_icons[i] |= 32; - StatusBarCreateCdromTip(i); - break; - - case SB_ZIP: /* Iomega ZIP */ - sb_part_icons[i] = (strlen(zip_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0; - sb_part_icons[i] |= 48; - StatusBarCreateZIPTip(i); - break; - - case SB_MO: /* Magneto-Optical disk */ - sb_part_icons[i] = (strlen(mo_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0; - sb_part_icons[i] |= 56; - StatusBarCreateMOTip(i); - break; - - case SB_HDD: /* Hard disk */ - sb_part_icons[i] = 80; - StatusBarCreateDiskTip(i); - break; - - case SB_NETWORK: /* Network */ - sb_part_icons[i] = 96; - StatusBarCreateNetworkTip(i); - break; - - case SB_SOUND: /* Sound */ - sb_part_icons[i] = 243; - StatusBarCreateSoundTip(i); - break; - - case SB_TEXT: /* Status text */ - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); - sb_part_icons[i] = 255; - break; - } - - if (sb_part_icons[i] != 255) { - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - SendMessage(hwndSBAR, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); - } else - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) NULL); - } - - sb_ready = 1; - if (reset_occurred & 2) - reset_occurred |= 1; -} - -static VOID APIENTRY -StatusBarPopupMenu(HWND hwnd, POINT pt, int id) -{ - HMENU menu; - - if (id >= (sb_parts - 1)) - return; - - pt.x = id * icon_width; /* Justify to the left. */ - pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, &pt); - - switch (sb_part_meanings[id] & 0xF0) { - case SB_CASSETTE: - menu = media_menu_get_cassette(); - break; - case SB_CARTRIDGE: - menu = media_menu_get_cartridge(sb_part_meanings[id] & 0x0F); - break; - case SB_FLOPPY: - menu = media_menu_get_floppy(sb_part_meanings[id] & 0x0F); - break; - case SB_CDROM: - menu = media_menu_get_cdrom(sb_part_meanings[id] & 0x0F); - break; - case SB_ZIP: - menu = media_menu_get_zip(sb_part_meanings[id] & 0x0F); - break; - case SB_MO: - menu = media_menu_get_mo(sb_part_meanings[id] & 0x0F); - break; - default: - return; - } - - TrackPopupMenu(menu, - TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, - pt.x, pt.y, 0, hwndSBAR, NULL); -} - -/* API: Load status bar icons */ -void -StatusBarLoadIcon(UNUSED(HINSTANCE hInst)) -{ - win_load_icon_set(); -} - -/* Handle messages for the Status Bar window. */ -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - POINT pt; - int item_id = 0; - int i; - HINSTANCE hInst; - - switch (message) { - case WM_COMMAND: - media_menu_proc(hwnd, message, wParam, lParam); - return 0; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - GetClientRect(hwnd, &rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect(&rc, pt)) - StatusBarPopupMenu(hwnd, pt, (pt.x / icon_width)); - break; - - case WM_LBUTTONDBLCLK: - GetClientRect(hwnd, &rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - item_id = (pt.x / icon_width); - if (PtInRect(&rc, pt) && (item_id < sb_parts)) { - if (sb_part_meanings[item_id] == SB_SOUND) - SoundGainDialogCreate(hwndMain); - } - break; - - case WM_DPICHANGED_AFTERPARENT: - /* DPI changed, reload icons */ - hInst = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE); - dpi = win_get_dpi(hwnd); - icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96); - StatusBarLoadIcon(hInst); - - for (i = 0; i < sb_parts; i++) { - if (sb_part_icons[i] != 255) { - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - } - - iStatusWidths[i] = (i + 1) * icon_width; - } - iStatusWidths[i - 1] = -1; - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - break; - - default: - return (CallWindowProc((WNDPROC) OriginalProcedure, - hwnd, message, wParam, lParam)); - } - - return 0; -} - -/* API: Create and set up the Status Bar window. */ -void -StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst) -{ - RECT rectDialog; - int dw; - int dh; - - /* Get current DPI and calculate icon sizes */ - dpi = win_get_dpi(hwndParent); - icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96); - - /* Load our icons into the cache for faster access. */ - StatusBarLoadIcon(hInst); - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - /* Load the Common Controls DLL if needed. */ - InitCommonControls(); - - /* Create the window, and make sure it's using the STATUS class. */ - hwndSBAR = CreateWindowEx(0, - STATUSCLASSNAME, - (LPCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, hInst, NULL); - - /* Replace the original procedure with ours. */ - OriginalProcedure = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); - SetWindowLongPtr(hwndSBAR, GWLP_WNDPROC, (LONG_PTR) &StatusBarProcedure); - - SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); - - /* Align the window with the parent (main) window. */ - GetWindowRect(hwndSBAR, &rectDialog); - SetWindowPos(hwndSBAR, - HWND_TOPMOST, - rectDialog.left, rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); - - /* Initialize the status bar. This is clumsy. */ - sb_parts = 1; - iStatusWidths = (int *) malloc(sb_parts * sizeof(int)); - memset(iStatusWidths, 0, sb_parts * sizeof(int)); - sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); - memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (uint8_t *) malloc(sb_parts * sizeof(uint8_t)); - memset(sb_part_icons, 0, sb_parts * sizeof(uint8_t)); - sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); - memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); - sb_parts = 0; - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = SB_TEXT; - sb_part_icons[sb_parts] = 255; - sb_parts++; - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS, - (LPARAM) plat_get_string(IDS_2118)); - - sb_ready = 1; -} - -void -ui_sb_update_text(void) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) - return; - - part = sb_map[SB_TEXT]; - - if (part != 0xff) - SendMessage(hwndSBAR, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) ((sb_text[0] != L'\0') ? sb_text : sb_bugtext)); -} - -/* API */ -void -ui_sb_set_text_w(wchar_t *wstr) -{ - if (wstr) - wcscpy(sb_text, wstr); - else - memset(sb_text, 0x00, sizeof(sb_text)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_set_text(char *str) -{ - if (str) - mbstowcs(sb_text, str, strlen(str) + 1); - else - memset(sb_text, 0x00, sizeof(sb_text)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_bugui(char *str) -{ - if (str) - mbstowcs(sb_bugtext, str, strlen(str) + 1); - else - memset(sb_bugtext, 0x00, sizeof(sb_bugtext)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_mt32lcd(UNUSED(char *str)) -{ - // -} diff --git a/src/win/win_thread.c b/src/win/win_thread.c deleted file mode 100644 index e874c4941..000000000 --- a/src/win/win_thread.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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. - * - * Implement threads and mutexes for the Win32 platform. - * - * - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/thread.h> - -typedef struct { - HANDLE handle; -} win_event_t; - -thread_t * -thread_create_named(void (*func)(void *param), void *param, const char *name) -{ - uintptr_t bt = _beginthread(func, 0, param); - plat_set_thread_name((void *) bt, name); - return ((thread_t *) bt); -} - -int -thread_test_mutex(thread_t *arg) -{ - if (arg == NULL) - return 0; - - return (WaitForSingleObject(arg, 0) == WAIT_OBJECT_0) ? 1 : 0; -} - -int -thread_wait(thread_t *arg) -{ - if (arg == NULL) - return 0; - - if (WaitForSingleObject(arg, INFINITE)) - return 1; - - return 0; -} - -event_t * -thread_create_event(void) -{ - win_event_t *ev = malloc(sizeof(win_event_t)); - - ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - - return ((event_t *) ev); -} - -void -thread_set_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - SetEvent(ev->handle); -} - -void -thread_reset_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - ResetEvent(ev->handle); -} - -int -thread_wait_event(event_t *arg, int timeout) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return 0; - - if (ev->handle == NULL) - return 0; - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(ev->handle, timeout)) - return 1; - - return 0; -} - -void -thread_destroy_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - CloseHandle(ev->handle); - - free(ev); -} - -mutex_t * -thread_create_mutex(void) -{ - mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); - - InitializeCriticalSection(mutex); - - return mutex; -} - -int -thread_wait_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return 0; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - EnterCriticalSection(critsec); - - return 1; -} - -int -thread_release_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return 0; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - LeaveCriticalSection(critsec); - - return 1; -} - -void -thread_close_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - DeleteCriticalSection(critsec); - - free(critsec); -} diff --git a/src/win/win_toolbar.c b/src/win/win_toolbar.c deleted file mode 100644 index 5c8621eea..000000000 --- a/src/win/win_toolbar.c +++ /dev/null @@ -1,208 +0,0 @@ -#define UNICODE -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/resource.h> -#include <86box/ui.h> -#include <86box/video.h> -#include <86box/win.h> - -HWND hwndRebar = NULL; -static HWND hwndToolbar = NULL; -static HIMAGELIST hImageList = NULL; -static wchar_t wTitle[512] = { 0 }; -static WNDPROC pOriginalProcedure = NULL; - -enum image_index { - RUN, - PAUSE, - CTRL_ALT_DEL, - CTRL_ALT_ESC, - HARD_RESET, - ACPI_SHUTDOWN, - SETTINGS -}; - -void -ToolBarLoadIcons(void) -{ - if (!hwndToolbar) - return; - - if (hImageList) - ImageList_Destroy(hImageList); - - hImageList = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi), - win_get_system_metrics(SM_CYSMICON, dpi), - ILC_MASK | ILC_COLOR32, 1, 1); - - // The icons must be loaded in the same order as the `image_index` - // enumeration above. - - ImageList_AddIcon(hImageList, hIcon[200]); // Run - ImageList_AddIcon(hImageList, hIcon[201]); // Pause - ImageList_AddIcon(hImageList, hIcon[202]); // Ctrl+Alt+Delete - ImageList_AddIcon(hImageList, hIcon[203]); // Ctrl+Alt+Esc - ImageList_AddIcon(hImageList, hIcon[204]); // Hard reset - ImageList_AddIcon(hImageList, hIcon[205]); // ACPI shutdown - ImageList_AddIcon(hImageList, hIcon[206]); // Settings - - SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM) hImageList); -} - -int -ToolBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case TTN_GETDISPINFO: - { - LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam; - - // Set the instance of the module that contains the resource. - lpttt->hinst = hinstance; - - uintptr_t idButton = lpttt->hdr.idFrom; - - switch (idButton) { - case IDM_ACTION_PAUSE: - if (dopause) - lpttt->lpszText = MAKEINTRESOURCE(IDS_2155); - else - lpttt->lpszText = MAKEINTRESOURCE(IDS_2156); - break; - - case IDM_ACTION_RESET_CAD: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2157); - break; - - case IDM_ACTION_CTRL_ALT_ESC: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2158); - break; - - case IDM_ACTION_HRESET: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2159); - break; - - case IDM_CONFIG: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2161); - break; - } - - return TRUE; - } - } - } - - return (CallWindowProc(pOriginalProcedure, hwnd, message, wParam, lParam)); -} - -void -ToolBarUpdatePause(int pause) -{ - TBBUTTONINFO tbbi; - - tbbi.cbSize = sizeof(tbbi); - tbbi.dwMask = TBIF_IMAGE; - tbbi.iImage = pause ? RUN : PAUSE; - - SendMessage(hwndToolbar, TB_SETBUTTONINFO, IDM_ACTION_PAUSE, (LPARAM) &tbbi); -} - -static TBBUTTON buttons[] = { - {PAUSE, IDM_ACTION_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { HARD_RESET, IDM_ACTION_HRESET, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { ACPI_SHUTDOWN, 0, TBSTATE_HIDDEN, BTNS_BUTTON, { 0 }, 0, 0}, - { 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0}, - { CTRL_ALT_DEL, IDM_ACTION_RESET_CAD, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { CTRL_ALT_ESC, IDM_ACTION_CTRL_ALT_ESC, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0}, - { SETTINGS, IDM_CONFIG, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0} -}; - -void -ToolBarCreate(HWND hwndParent, HINSTANCE hInst) -{ - REBARINFO rbi = { 0 }; - REBARBANDINFO rbbi = { 0 }; - int btnSize; - - // Create the toolbar. - hwndToolbar = CreateWindowEx(WS_EX_PALETTEWINDOW, TOOLBARCLASSNAME, NULL, - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER, - 0, 0, 0, 0, - hwndParent, NULL, hInst, NULL); - - ToolBarLoadIcons(); - - // Add buttons. - SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); - SendMessage(hwndToolbar, TB_ADDBUTTONS, sizeof(buttons) / sizeof(TBBUTTON), (LPARAM) &buttons); - - // Autosize the toolbar and determine its size. - btnSize = LOWORD(SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0, 0)); - - // Replace the original procedure with ours. - pOriginalProcedure = (WNDPROC) GetWindowLongPtr(hwndToolbar, GWLP_WNDPROC); - SetWindowLongPtr(hwndToolbar, GWLP_WNDPROC, (LONG_PTR) &ToolBarProcedure); - - // Make sure the Pause button is in the correct state. - ToolBarUpdatePause(dopause); - - // Create the containing Rebar. - hwndRebar = CreateWindowEx(0, REBARCLASSNAME, NULL, - WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT | CCS_NODIVIDER | CCS_NOPARENTALIGN, - 0, 0, scrnsz_x, 0, - hwndParent, NULL, hInst, NULL); - - // Create and send the REBARINFO structure. - rbi.cbSize = sizeof(rbi); - SendMessage(hwndRebar, RB_SETBARINFO, 0, (LPARAM) &rbi); - - // Add the toolbar to the rebar. - rbbi.cbSize = sizeof(rbbi); - rbbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE; - rbbi.hwndChild = hwndToolbar; - rbbi.cxMinChild = 0; - rbbi.cyMinChild = btnSize; - rbbi.fStyle = RBBS_NOGRIPPER; - SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi); - - // Add a label for machine information. - rbbi.fMask = RBBIM_TEXT | RBBIM_STYLE; - rbbi.lpText = TEXT("Test"); - rbbi.fStyle = RBBS_NOGRIPPER; - SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi); - - SendMessage(hwndRebar, RB_MAXIMIZEBAND, 0, 0); - ShowWindow(hwndRebar, TRUE); - - return; -} - -wchar_t * -ui_window_title(wchar_t *s) -{ - REBARBANDINFO rbbi = { 0 }; - if (!video_fullscreen) { - if (s != NULL) { - wcsncpy(wTitle, s, sizeof_w(wTitle) - 1); - } else - s = wTitle; - - rbbi.cbSize = sizeof(rbbi); - rbbi.fMask = RBBIM_TEXT; - rbbi.lpText = s; - SendMessage(hwndRebar, RB_SETBANDINFO, 1, (LPARAM) &rbbi); - } else { - if (s == NULL) - s = wTitle; - } - - return s; -} diff --git a/src/win/win_ui.c b/src/win/win_ui.c deleted file mode 100644 index ec4a785ab..000000000 --- a/src/win/win_ui.c +++ /dev/null @@ -1,1662 +0,0 @@ -/* - * 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. - * - * user Interface module for WinAPI on Windows. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Jasmine Iwanek, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2019-2020 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#define UNICODE -#include -#include -#include -#include -#include -#include -#include -#include -#include <86box/plat.h> -#include <86box/86box.h> -#include <86box/config.h> -#include "../cpu/cpu.h" -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mouse.h> -#include <86box/timer.h> -#include <86box/nvr.h> -#include <86box/video.h> -#include <86box/vid_ega.h> // for update_overscan -#include <86box/plat_dynld.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/version.h> -#ifdef DISCORD -# include <86box/discord.h> -#endif - -#ifdef MTR_ENABLED -# include -#endif - -#define TIMER_1SEC 1 /* ID of the one-second timer */ - -/* Platform Public data, specific. */ -HWND hwndMain = NULL; /* application main window */ -HWND hwndRender = NULL; /* machine render window */ -HWND hwndRender2 = NULL; /* machine second screen render window */ -HMENU menuMain; /* application main menu */ -RECT oldclip; /* mouse rect */ -int sbar_height = 23; /* statusbar height */ -int tbar_height = 23; /* toolbar height */ -int minimized = 0; -int infocus = 1; -int button_down = 0; -int rctrl_is_lalt = 0; -int user_resize = 0; -int fixed_size_x = 0; -int fixed_size_y = 0; -int kbd_req_capture = 0; -int hide_status_bar = 0; -int hide_tool_bar = 0; -int dpi = 96; - -extern char openfilestring[512]; -extern WCHAR wopenfilestring[512]; - -/* Local data. */ -static int manager_wm = 0; -static int save_window_pos = 0; -static int pause_state = 0; -static int padded_frame = 0; -static int vis = -1; - -/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */ -void *user32_handle = NULL; -static UINT(WINAPI *pGetDpiForWindow)(HWND); -static UINT(WINAPI *pGetSystemMetricsForDpi)(int i, UINT dpi); -static DPI_AWARENESS_CONTEXT(WINAPI *pGetWindowDpiAwarenessContext)(HWND); -static BOOL(WINAPI *pAreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT A, DPI_AWARENESS_CONTEXT B); -static dllimp_t user32_imports[] = { - {"GetDpiForWindow", &pGetDpiForWindow }, - { "GetSystemMetricsForDpi", &pGetSystemMetricsForDpi }, - { "GetWindowDpiAwarenessContext", &pGetWindowDpiAwarenessContext}, - { "AreDpiAwarenessContextsEqual", &pAreDpiAwarenessContextsEqual}, - { NULL, NULL } -}; - -/* Taskbar application ID API, Windows 7+ */ -void *shell32_handle = NULL; -static HRESULT(WINAPI *pSetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID); -static dllimp_t shell32_imports[] = { - {"SetCurrentProcessExplicitAppUserModelID", &pSetCurrentProcessExplicitAppUserModelID}, - { NULL, NULL } -}; - -int -win_get_dpi(HWND hwnd) -{ - if (user32_handle != NULL) { - return pGetDpiForWindow(hwnd); - } else { - HDC dc = GetDC(hwnd); - UINT dpi = GetDeviceCaps(dc, LOGPIXELSX); - ReleaseDC(hwnd, dc); - return dpi; - } -} - -int -win_get_system_metrics(int index, int dpi) -{ - if (user32_handle != NULL) { - /* Only call GetSystemMetricsForDpi when we are using PMv2 */ - DPI_AWARENESS_CONTEXT c = pGetWindowDpiAwarenessContext(hwndMain); - if (pAreDpiAwarenessContextsEqual(c, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) - return pGetSystemMetricsForDpi(index, dpi); - } - - return GetSystemMetrics(index); -} - -void -ResizeWindowByClientArea(HWND hwnd, int width, int height) -{ - if ((vid_resize == 1) || padded_frame) { - int padding = win_get_system_metrics(SM_CXPADDEDBORDER, dpi); - width += (win_get_system_metrics(SM_CXFRAME, dpi) + padding) * 2; - height += (win_get_system_metrics(SM_CYFRAME, dpi) + padding) * 2; - } else { - width += win_get_system_metrics(SM_CXFIXEDFRAME, dpi) * 2; - height += win_get_system_metrics(SM_CYFIXEDFRAME, dpi) * 2; - } - - height += win_get_system_metrics(SM_CYCAPTION, dpi); - height += win_get_system_metrics(SM_CYBORDER, dpi) + win_get_system_metrics(SM_CYMENUSIZE, dpi); - - SetWindowPos(hwnd, NULL, 0, 0, width, height, SWP_NOMOVE); -} - -/* Set host cursor visible or not. */ -void -show_cursor(int val) -{ - if (val == vis) - return; - - if (val == 0) { - while (1) - if (ShowCursor(FALSE) < 0) - break; - } else - ShowCursor(TRUE); - - vis = val; -} - -static void -video_toggle_option(HMENU h, int *val, int id) -{ - startblit(); - *val ^= 1; - CheckMenuItem(h, id, *val ? MF_CHECKED : MF_UNCHECKED); - endblit(); - config_save(); - device_force_redraw(); -} - -/* Recursively finds and deletes target submenu */ -static int -delete_submenu(HMENU parent, HMENU target) -{ - for (int i = 0; i < GetMenuItemCount(parent); i++) { - MENUITEMINFO mii; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_SUBMENU; - - if (GetMenuItemInfo(parent, i, TRUE, &mii) != 0) { - if (mii.hSubMenu == target) { - DeleteMenu(parent, i, MF_BYPOSITION); - return 1; - } else if (mii.hSubMenu != NULL) { - if (delete_submenu(mii.hSubMenu, target)) - return 1; - } - } - } - - return 0; -} - -static int menu_vidapi = -1; -static HMENU cur_menu = NULL; - -static void -show_render_options_menu(void) -{ - if (vid_api == menu_vidapi) - return; - - if (cur_menu != NULL) { - if (delete_submenu(menuMain, cur_menu)) - cur_menu = NULL; - } - - if (cur_menu == NULL) { - switch (IDM_VID_SDL_SW + vid_api) { - case IDM_VID_OPENGL_CORE: - cur_menu = LoadMenu(hinstance, VID_GL_SUBMENU); - InsertMenu(GetSubMenu(menuMain, 1), 6, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT_PTR) cur_menu, plat_get_string(IDS_2145)); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_BLITTER, video_framerate == -1 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_25, video_framerate == 25 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_30, video_framerate == 30 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_50, video_framerate == 50 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_60, video_framerate == 60 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_75, video_framerate == 75 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, strlen(video_shader) > 0 ? MF_ENABLED : MF_DISABLED); - break; - } - } - - menu_vidapi = vid_api; -} - -static void -video_set_filter_menu(HMENU menu) -{ - CheckMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 || video_filter_method == 0 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api != 0 && video_filter_method == 1 ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api == 0 ? MF_GRAYED : MF_ENABLED); -} - -void -ResetAllMenus(void) -{ - CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_UPDATE_ICONS, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDE_TOOLBAR, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FORCE43, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OVERSCAN, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_INVERT, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_SW, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_HW, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_OPENGL, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OPENGL_CORE, MF_UNCHECKED); - - menu_vidapi = -1; - cur_menu = NULL; - show_render_options_menu(); -#ifdef USE_VNC - CheckMenuItem(menuMain, IDM_VID_VNC, MF_UNCHECKED); -#endif - CheckMenuItem(menuMain, IDM_VID_FS_FULL, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_43, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_KEEPRATIO, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_INT, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SPECIFY_DIM, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_REMEMBER, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_1X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_2X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_3X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_4X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_5X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_6X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_7X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_8X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_9X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_10X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDPI, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_CGACON, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_601, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_709, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_AVE, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_RGB, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_MONO, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_AMBER, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_GREEN, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_WHITE, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDE_TOOLBAR, hide_tool_bar ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - - if (show_second_monitors == 1) - CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_CHECKED); - - if (vid_resize == 1) - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_SW + vid_api, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_1X + scale, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_601 + video_graytype, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_RGB + video_grayscale, MF_CHECKED); - - video_set_filter_menu(menuMain); - -#ifdef DISCORD - if (discord_loaded) - CheckMenuItem(menuMain, IDM_DISCORD, enable_discord ? MF_CHECKED : MF_UNCHECKED); - else - EnableMenuItem(menuMain, IDM_DISCORD, MF_DISABLED); -#endif - -#ifdef MTR_ENABLED - EnableMenuItem(menuMain, IDM_ACTION_END_TRACE, MF_DISABLED); -#endif - - if (vid_resize) { - if (vid_resize >= 2) { - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); - EnableMenuItem(menuMain, IDM_VID_RESIZE, MF_GRAYED); - } - - CheckMenuItem(menuMain, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_2X, MF_CHECKED); - EnableMenuItem(menuMain, IDM_VID_SCALE_1X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_2X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_3X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_4X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_5X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_6X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_7X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_8X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_9X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_10X, MF_GRAYED); - } -} - -void -win_notify_dlg_open(void) -{ - manager_wm = 1; - pause_state = dopause; - plat_pause(1); - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 1, (LPARAM) hwndMain); -} - -void -win_notify_dlg_closed(void) -{ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 0, (LPARAM) hwndMain); - plat_pause(pause_state); - manager_wm = 0; -} - -void -plat_power_off(void) -{ - confirm_exit_cmdl = 0; - nvr_save(); - config_save(); - - /* Deduct a sufficiently large number of cycles that no instructions will - run before the main thread is terminated */ - cycles -= 99999999; - - KillTimer(hwndMain, TIMER_1SEC); - PostQuitMessage(0); - - /* Cleanly terminate all of the emulator's components so as - to avoid things like threads getting stuck. */ -#if 0 - do_stop(); -#endif - cpu_thread_run = 0; - -#if 0 - exit(-1); -#endif -} - -#ifdef MTR_ENABLED -static void -handle_trace(HMENU hmenu, int trace) -{ - EnableMenuItem(hmenu, IDM_ACTION_BEGIN_TRACE, trace ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_ACTION_END_TRACE, trace ? MF_ENABLED : MF_GRAYED); - if (trace) { - init_trace(); - } else { - shutdown_trace(); - } -} -#endif - -/* Catch WM_INPUT messages for 'current focus' window. */ -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -input_proc(UNUSED(HWND hwnd), UINT message, UNUSED(WPARAM wParam), LPARAM lParam) -{ - switch (message) { - case WM_INPUT: - if (infocus) { - UINT size = 0; - PRAWINPUT raw = NULL; - - /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = (PRAWINPUT) malloc(size); - if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { - switch (raw->header.dwType) { - case RIM_TYPEKEYBOARD: - keyboard_handle(raw); - break; - case RIM_TYPEMOUSE: - win_mouse_handle(raw); - break; - case RIM_TYPEHID: - win_joystick_handle(raw); - break; - } - } - free(raw); - } - break; - case WM_SETFOCUS: - infocus = 1; - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - break; - - case WM_LBUTTONDOWN: - button_down |= 1; - break; - - case WM_LBUTTONUP: - if ((button_down & 1) && !video_fullscreen) - plat_mouse_capture(1); - button_down &= ~1; - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - - default: - return 1; -#if 0 - return(CallWindowProc((WNDPROC)input_orig_proc, - hwnd, message, wParam, lParam)); -#endif - } - - return 0; -} - -static LRESULT CALLBACK -MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HMENU hmenu; - - int i; - RECT rect; - RECT *rect_p; - - WINDOWPOS *pos; - - int temp_x; - int temp_y; - - if (input_proc(hwnd, message, wParam, lParam) == 0) - return 0; - - switch (message) { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - break; - - case WM_COMMAND: - hmenu = GetMenu(hwnd); - switch (LOWORD(wParam)) { - case IDM_ACTION_SCREENSHOT: - take_screenshot(); - break; - -#ifdef MTR_ENABLED - case IDM_ACTION_BEGIN_TRACE: - case IDM_ACTION_END_TRACE: - case IDM_ACTION_TRACE: - tracing_on = !tracing_on; - handle_trace(hmenu, tracing_on); - break; -#endif - - case IDM_ACTION_HRESET: - win_notify_dlg_open(); - if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); - else - i = 0; - if ((i % 10) == 0) { - pc_reset_hard(); - if (i == 10) { - confirm_reset = 0; - nvr_save(); - config_save(); - } - } - win_notify_dlg_closed(); - break; - - case IDM_ACTION_RESET_CAD: - pc_send_cad(); - break; - - case IDM_ACTION_EXIT: - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - break; - - case IDM_ACTION_CTRL_ALT_ESC: - pc_send_cae(); - break; - - case IDM_ACTION_RCTRL_IS_LALT: - rctrl_is_lalt ^= 1; - CheckMenuItem(hmenu, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_ACTION_KBD_REQ_CAPTURE: - kbd_req_capture ^= 1; - CheckMenuItem(hmenu, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_ACTION_PAUSE: - plat_pause(dopause ^ 1); - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); - break; - - case IDM_CONFIG: - win_settings_open(hwnd); - break; - - case IDM_SND_GAIN: - SoundGainDialogCreate(hwnd); - break; - - case IDM_ABOUT: - AboutDialogCreate(hwnd); - break; - - case IDM_DOCS: - ShellExecute(hwnd, L"open", EMU_DOCS_URL_W, NULL, NULL, SW_SHOW); - break; - - case IDM_UPDATE_ICONS: - update_icons ^= 1; - CheckMenuItem(hmenu, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_VID_HIDE_STATUS_BAR: - hide_status_bar ^= 1; - CheckMenuItem(hmenu, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED); - ShowWindow(hwndSBAR, hide_status_bar ? SW_HIDE : SW_SHOW); - GetWindowRect(hwnd, &rect); - if (hide_status_bar) - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - sbar_height, TRUE); - else - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + sbar_height, TRUE); - config_save(); - break; - - case IDM_VID_HIDE_TOOLBAR: - hide_tool_bar ^= 1; - CheckMenuItem(hmenu, IDM_VID_HIDE_TOOLBAR, hide_tool_bar ? MF_CHECKED : MF_UNCHECKED); - ShowWindow(hwndRebar, hide_tool_bar ? SW_HIDE : SW_SHOW); - GetWindowRect(hwnd, &rect); - if (hide_tool_bar) { - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - tbar_height, TRUE); - SetWindowPos(hwndRender, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } else { - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + tbar_height, TRUE); - SetWindowPos(hwndRender, NULL, 0, tbar_height, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - config_save(); - break; - - case IDM_VID_MONITORS: - show_second_monitors ^= 1; - CheckMenuItem(hmenu, IDM_VID_MONITORS, (show_second_monitors & 1) ? MF_CHECKED : MF_UNCHECKED); - break; - - case IDM_VID_RESIZE: - vid_resize ^= 1; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 1) ? MF_CHECKED : MF_UNCHECKED); - - if (vid_resize == 1) - SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); - else - SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); - - /* scale the screen base on DPI */ - if (dpi_scale) { - temp_x = MulDiv(unscaled_size_x, dpi, 96); - temp_y = MulDiv(unscaled_size_y, dpi, 96); - } else { - temp_x = unscaled_size_x; - temp_y = unscaled_size_y; - } - - ResizeWindowByClientArea(hwnd, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - - if (mouse_capture) { - ClipCursor(&rect); - } - - if (vid_resize) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_5X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_6X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_7X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_8X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_9X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_10X, vid_resize ? MF_GRAYED : MF_ENABLED); - - scrnsz_x = unscaled_size_x; - scrnsz_y = unscaled_size_y; - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember || (vid_resize & 2)) { - window_x = rect.left; - window_y = rect.top; - if (!(vid_resize & 2)) { - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - } - config_save(); - break; - - case IDM_VID_SDL_SW: - case IDM_VID_SDL_HW: - case IDM_VID_SDL_OPENGL: - case IDM_VID_OPENGL_CORE: -#ifdef USE_VNC - case IDM_VID_VNC: -#endif - CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_UNCHECKED); - plat_setvid(LOWORD(wParam) - IDM_VID_SDL_SW); - CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_CHECKED); - video_set_filter_menu(hmenu); - config_save(); - show_render_options_menu(); - break; - - case IDM_VID_GL_FPS_BLITTER: - case IDM_VID_GL_FPS_25: - case IDM_VID_GL_FPS_30: - case IDM_VID_GL_FPS_50: - case IDM_VID_GL_FPS_60: - case IDM_VID_GL_FPS_75: - { - static const int fps[] = { -1, 25, 30, 50, 60, 75 }; - int idx = 0; - for (; fps[idx] != video_framerate; idx++) - ; - CheckMenuItem(hmenu, IDM_VID_GL_FPS_BLITTER + idx, MF_UNCHECKED); - video_framerate = fps[LOWORD(wParam) - IDM_VID_GL_FPS_BLITTER]; - CheckMenuItem(hmenu, LOWORD(wParam), MF_CHECKED); - plat_vid_reload_options(); - config_save(); - break; - } - case IDM_VID_GL_VSYNC: - video_vsync = !video_vsync; - CheckMenuItem(hmenu, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED); - plat_vid_reload_options(); - config_save(); - break; - case IDM_VID_GL_SHADER: - win_notify_dlg_open(); - if (file_dlg_st(hwnd, IDS_2144, video_shader, NULL, 0) == 0) { - strcpy_s(video_shader, sizeof(video_shader), openfilestring); - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, strlen(video_shader) > 0 ? MF_ENABLED : MF_DISABLED); - } - win_notify_dlg_closed(); - plat_vid_reload_options(); - break; - case IDM_VID_GL_NOSHADER: - video_shader[0] = '\0'; - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, MF_DISABLED); - plat_vid_reload_options(); - break; - - case IDM_VID_FULLSCREEN: - plat_setfullscreen(1); - config_save(); - break; - - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_KEEPRATIO: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - case IDM_VID_SCALE_5X: - case IDM_VID_SCALE_6X: - case IDM_VID_SCALE_7X: - case IDM_VID_SCALE_8X: - case IDM_VID_SCALE_9X: - case IDM_VID_SCALE_10X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - reset_screen_size(); - device_force_redraw(); - video_force_resize_set(1); - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_VID_FILTER_NEAREST: - case IDM_VID_FILTER_LINEAR: - video_filter_method = LOWORD(wParam) - IDM_VID_FILTER_NEAREST; - video_set_filter_menu(hmenu); - plat_vid_reload_options(); - config_save(); - break; - - case IDM_VID_HIDPI: - dpi_scale = !dpi_scale; - CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_PREFERENCES: - PreferencesDlgCreate(hwnd); - break; - - case IDM_VID_SPECIFY_DIM: - SpecifyDimensionsDialogCreate(hwnd); - break; - - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - video_force_resize_set(1); - break; - - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; - plat_vidapi_reload(); - break; - - case IDM_VID_OVERSCAN: - update_overscan = 1; - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - video_force_resize_set(1); - break; - - case IDM_VID_CGACON: - vid_cga_contrast ^= 1; - CheckMenuItem(hmenu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); - cgapal_rebuild(); - config_save(); - break; - - case IDM_VID_GRAYCT_601: - case IDM_VID_GRAYCT_709: - case IDM_VID_GRAYCT_AVE: - CheckMenuItem(hmenu, IDM_VID_GRAYCT_601 + video_graytype, MF_UNCHECKED); - video_graytype = LOWORD(wParam) - IDM_VID_GRAYCT_601; - CheckMenuItem(hmenu, IDM_VID_GRAYCT_601 + video_graytype, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - - case IDM_VID_GRAY_RGB: - case IDM_VID_GRAY_MONO: - case IDM_VID_GRAY_AMBER: - case IDM_VID_GRAY_GREEN: - case IDM_VID_GRAY_WHITE: - CheckMenuItem(hmenu, IDM_VID_GRAY_RGB + video_grayscale, MF_UNCHECKED); - video_grayscale = LOWORD(wParam) - IDM_VID_GRAY_RGB; - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; - plat_vidapi_reload(); - CheckMenuItem(hmenu, IDM_VID_GRAY_RGB + video_grayscale, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - -#ifdef DISCORD - case IDM_DISCORD: - if (!discord_loaded) - break; - enable_discord ^= 1; - CheckMenuItem(hmenu, IDM_DISCORD, enable_discord ? MF_CHECKED : MF_UNCHECKED); - if (enable_discord) { - discord_init(); - discord_update_activity(dopause); - } else - discord_close(); - break; -#endif - - default: - media_menu_proc(hwnd, message, wParam, lParam); - break; - } - return 0; - - case WM_ENTERMENULOOP: - break; - - case WM_DPICHANGED: - dpi = HIWORD(wParam); - GetWindowRect(hwndSBAR, &rect); - sbar_height = rect.bottom - rect.top; - GetWindowRect(hwndRebar, &rect); - tbar_height = rect.bottom - rect.top; - rect_p = (RECT *) lParam; - if (vid_resize == 1) - MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE); - else if (vid_resize >= 2) { - temp_x = fixed_size_x; - temp_y = fixed_size_y; - if (dpi_scale) { - temp_x = MulDiv(temp_x, dpi, 96); - temp_y = MulDiv(temp_y, dpi, 96); - } - - /* Main Window. */ - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } else if (!user_resize) - atomic_store(&doresize_monitors[0], 1); - break; - - case WM_WINDOWPOSCHANGED: - if (video_fullscreen & 1) - PostMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); - - pos = (WINDOWPOS *) lParam; - GetClientRect(hwndMain, &rect); - - if (IsIconic(hwndMain)) { - plat_vidapi_enable(0); - minimized = 1; - return 0; - } else if (minimized) { - minimized = 0; - video_force_resize_set(1); - } - - if (!(pos->flags & SWP_NOSIZE) && (window_remember || (vid_resize & 2))) { - window_x = pos->x; - window_y = pos->y; - if (!(vid_resize & 2)) { - window_w = pos->cx; - window_h = pos->cy; - } - save_window_pos = 1; - config_save(); - } - - if (!(pos->flags & SWP_NOSIZE) || !user_resize) { - plat_vidapi_enable(0); - - if (!hide_status_bar) - MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, sbar_height, rect.right, TRUE); - - if (!hide_tool_bar) - MoveWindow(hwndRebar, 0, 0, rect.right, tbar_height, TRUE); - - MoveWindow(hwndRender, 0, hide_tool_bar ? 0 : tbar_height, rect.right, rect.bottom - (hide_status_bar ? 0 : sbar_height) - (hide_tool_bar ? 0 : tbar_height), TRUE); - - GetClientRect(hwndRender, &rect); - if (dpi_scale) { - temp_x = MulDiv(rect.right, 96, dpi); - temp_y = MulDiv(rect.bottom, 96, dpi); - - if (temp_x != scrnsz_x || temp_y != scrnsz_y) { - scrnsz_x = temp_x; - scrnsz_y = temp_y; - atomic_store(&doresize_monitors[0], 1); - } - } else { - if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { - scrnsz_x = rect.right; - scrnsz_y = rect.bottom; - atomic_store(&doresize_monitors[0], 1); - } - } - - plat_vidsize(rect.right, rect.bottom); - - if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - } - - plat_vidapi_enable(2); - } - - return 0; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - pc_onesec(); - else if ((wParam >= 0x8000) && (wParam <= 0x80ff)) - ui_sb_timer_callback(wParam & 0xff); - break; - - case WM_LEAVEFULLSCREEN: - plat_setfullscreen(0); - config_save(); - break; - - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - return 0; - - case WM_CLOSE: - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - break; - - case WM_DESTROY: - win_clear_icon_set(); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - break; - - case WM_SHOWSETTINGS: - if (manager_wm) - break; - manager_wm = 1; - win_settings_open(hwnd); - manager_wm = 0; - break; - - case WM_PAUSE: - if (manager_wm) - break; - manager_wm = 1; - plat_pause(dopause ^ 1); - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); - manager_wm = 0; - break; - - case WM_HARDRESET: - if (manager_wm) - break; - win_notify_dlg_open(); - if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); - else - i = 0; - if ((i % 10) == 0) { - pc_reset_hard(); - if (i == 10) { - confirm_reset = 0; - nvr_save(); - config_save(); - } - } - win_notify_dlg_closed(); - break; - - case WM_SHUTDOWN: - if (manager_wm) - break; - if (LOWORD(wParam) == 1) { - confirm_exit = 0; - nvr_save(); - config_save(); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } else { - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - } - break; - - case WM_CTRLALTDEL: - if (manager_wm) - break; - manager_wm = 1; - pc_send_cad(); - manager_wm = 0; - break; - - case WM_SYSCOMMAND: - /* - * Disable ALT key *ALWAYS*, - * I don't think there's any use for - * reaching the menu that way. - */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) { - return 0; /*disable ALT key for menu*/ - } - - default: - return (DefWindowProc(hwnd, message, wParam, lParam)); - - case WM_SETFOCUS: - infocus = 1; - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - break; - - case WM_ACTIVATE: - if ((wParam != WA_INACTIVE) && !(video_fullscreen & 2)) { - video_force_resize_set(1); - plat_vidapi_enable(0); - plat_vidapi_enable(1); - } - break; - - case WM_ACTIVATEAPP: - /* Leave full screen on switching application except - for OpenGL Core and VNC renderers. */ - if (video_fullscreen & 1 && wParam == FALSE && vid_api < 3) - PostMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); - break; - - case WM_ENTERSIZEMOVE: - user_resize = 1; - break; - - case WM_EXITSIZEMOVE: - user_resize = 0; - - /* If window is not resizable, then tell the main thread to - resize it, as sometimes, moves can mess up the window size. */ - if (!vid_resize) - atomic_store(&doresize_monitors[0], 1); - break; - } - - return 0; -} - -static LRESULT CALLBACK -SubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_LBUTTONDOWN: - button_down |= 2; - break; - - case WM_LBUTTONUP: - if ((button_down & 2) && !video_fullscreen) - plat_mouse_capture(1); - button_down &= ~2; - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - - default: - return (DefWindowProc(hwnd, message, wParam, lParam)); - } - - return 0; -} - -static LRESULT CALLBACK -SDLMainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - if (input_proc(hwnd, message, wParam, lParam) == 0) - return 0; - - return (DefWindowProc(hwnd, message, wParam, lParam)); -} - -static LRESULT CALLBACK -SDLSubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - return (DefWindowProc(hwnd, message, wParam, lParam)); -} - -static HRESULT CALLBACK -TaskDialogProcedure(HWND hwnd, UINT message, UNUSED(WPARAM wParam), LPARAM lParam, UNUSED(LONG_PTR lpRefData)) -{ - switch (message) { - case TDN_HYPERLINK_CLICKED: - /* open linked URL */ - ShellExecute(hwnd, L"open", (LPCWSTR) lParam, NULL, NULL, SW_SHOW); - break; - } - - return S_OK; -} - -int -ui_init(int nCmdShow) -{ - WCHAR title[200]; - WNDCLASSEX wincl; /* buffer for main window's class */ - RAWINPUTDEVICE ridev; /* RawInput device */ - MSG messages = { 0 }; /* received-messages buffer */ - HWND hwnd = NULL; /* handle for our window */ - HACCEL haccel; /* handle to accelerator table */ - RECT rect; - int bRet; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[] = { - {IDCANCEL, MAKEINTRESOURCE(IDS_2120)} - }; - uint32_t helper_lang; - static int fs_on_signal = 0; - static int fs_off_signal = 0; - - /* Load DPI related Windows 10 APIs */ - user32_handle = dynld_module("user32.dll", user32_imports); - - /* Set the application ID for the taskbar. */ - shell32_handle = dynld_module("shell32.dll", shell32_imports); - if (shell32_handle) - pSetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); - - /* Set up TaskDialog configuration. */ - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS; - tdconfig.dwCommonButtons = 0; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); - tdconfig.pszMainIcon = TD_ERROR_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); - tdconfig.cButtons = ARRAYSIZE(tdbuttons); - tdconfig.pButtons = tdbuttons; - tdconfig.pfCallback = TaskDialogProcedure; - - /* Load the desired iconset */ - win_load_icon_set(); - - /* Start settings-only mode if requested. */ - if (settings_only) { - if (!pc_init_modules()) { - /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 6; - } - - /* Load the desired language */ - helper_lang = lang_id; - lang_id = 0; - set_language(helper_lang); - - win_settings_open(NULL); - return 0; - } - -#ifdef DISCORD - if (!discord_load()) { - enable_discord = 0; - } else if (enable_discord) { - /* Initialize the Discord API */ - discord_init(); - - /* Update Discord status */ - discord_update_activity(dopause); - } -#endif - - /* Create our main window's class and register it. */ - wincl.hInstance = hinstance; - wincl.lpszClassName = CLASS_NAME; - wincl.lpfnWndProc = MainWindowProcedure; - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = NULL; - wincl.hIconSm = NULL; - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; - wincl.cbClsExtra = 0; - wincl.cbWndExtra = 0; - wincl.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); - - /* Load proper icons */ - wchar_t path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameW(hinstance, path, MAX_PATH); - ExtractIconExW(path, 0, &wincl.hIcon, &wincl.hIconSm, 1); - - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SUB_CLASS_NAME; - wincl.lpfnWndProc = SubWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SDL_CLASS_NAME; - wincl.lpfnWndProc = SDLMainWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SDL_SUB_CLASS_NAME; - wincl.lpfnWndProc = SDLSubWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - - /* Now create our main window. */ - swprintf_s(title, sizeof_w(title), L"%hs - %s %s", vm_name, EMU_NAME_W, EMU_VERSION_FULL_W); - hwnd = CreateWindowEx( - 0, /* no extended possibilites */ - CLASS_NAME, /* class name */ - title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX) | DS_3DLOOK, - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where window ends up on the screen */ - scrnsz_x + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), /* width */ - scrnsz_y + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1, /* and height in pixels */ - HWND_DESKTOP, /* window is a child to desktop */ - NULL, /* no menu (yet) */ - hinstance, /* Program Instance handler */ - NULL); /* no Window Creation data */ - hwndMain = tdconfig.hwndParent = hwnd; - - ui_window_title(title); - - /* Get the current DPI */ - dpi = win_get_dpi(hwndMain); - - /* Check if we have a padded window frame */ - padded_frame = (GetSystemMetrics(SM_CXPADDEDBORDER) != 0); - - /* Create the status bar window. */ - StatusBarCreate(hwndMain, IDC_STATUS, hinstance); - - /* Get the actual height of the status bar */ - GetWindowRect(hwndSBAR, &rect); - sbar_height = rect.bottom - rect.top; - if (hide_status_bar) - ShowWindow(hwndSBAR, SW_HIDE); - - /* Create the toolbar window. */ - ToolBarCreate(hwndMain, hinstance); - - /* Get the actual height of the toolbar */ - tbar_height = SendMessage(hwndRebar, RB_GETROWHEIGHT, 0, 0); - if (hide_tool_bar) - ShowWindow(hwndRebar, SW_HIDE); - - /* Set up main window for resizing if configured. */ - if (vid_resize == 1) - SetWindowLongPtr(hwnd, GWL_STYLE, - (WS_OVERLAPPEDWINDOW)); - else - SetWindowLongPtr(hwnd, GWL_STYLE, - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX)); - - /* Create the Machine Rendering window. */ - hwndRender = CreateWindow(/*L"STATIC"*/ SUB_CLASS_NAME, NULL, WS_CHILD | SS_BITMAP, - 0, 0, 1, 1, hwnd, NULL, hinstance, NULL); - - /* Initiate a resize in order to properly arrange all controls. - Move to the last-saved position if needed. */ - if ((vid_resize < 2) && window_remember) - MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); - else { - if (vid_resize >= 2) { - MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); - scrnsz_x = fixed_size_x; - scrnsz_y = fixed_size_y; - } - ResizeWindowByClientArea(hwnd, scrnsz_x, scrnsz_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } - - /* Load the desired language */ - helper_lang = lang_id; - lang_id = 0; - set_language(helper_lang); - - /* Make the window visible on the screen. */ - ShowWindow(hwnd, nCmdShow); - - /* Warn the user about unsupported configs. */ - if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void *) IDS_2146, (void *) IDS_2147, (void *) IDS_2148, (void *) IDS_2120, NULL)) { - DestroyWindow(hwnd); - return 0; - } - - GetClipCursor(&oldclip); - - /* Initialize the RawInput (keyboard) module. */ - memset(&ridev, 0x00, sizeof(ridev)); - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x06; - ridev.dwFlags = RIDEV_NOHOTKEYS; - ridev.hwndTarget = NULL; /* current focus window */ - if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2106); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 4; - } - keyboard_getkeymap(); - - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstance, ACCEL_NAME); - if (haccel == NULL) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 3; - } - - /* Initialize the mouse module. */ - if (!start_in_fullscreen) - win_mouse_init(); - - /* - * Before we can create the Render window, we first have - * to prepare some other things that it depends on. - */ - ghMutex = CreateMutex(NULL, FALSE, NULL); - - /* All done, fire up the actual emulated machine. */ - if (!pc_init_modules()) { - /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 6; - } - - /* Initialize the configured Video API. */ - if (!plat_setvid(vid_api)) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2090); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 5; - } - - /* Set up the current window size. */ - if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); - else - plat_resize(scrnsz_x, scrnsz_y); - - /* Initialize the rendering window, or fullscreen. */ - if (start_in_fullscreen) - plat_setfullscreen(3); - - /* Fire up the machine. */ - pc_reset_hard_init(); - - /* Set the PAUSE mode depending on the renderer. */ - plat_pause(0); - - /* If so requested via the command line, inform the - * application that started us of our HWND, using the - * the hWnd and unique ID the application has given - * us. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDHWND, (WPARAM) unique_id, (LPARAM) hwndMain); - - /* - * Everything has been configured, and all seems to work, - * so now it is time to start the main thread to do some - * real work, and we will hang in here, dealing with the - * UI until we're done. - */ - do_start(); - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (!is_quit) { - bRet = GetMessage(&messages, NULL, 0, 0); - if ((bRet == 0) || is_quit) - break; - - if (bRet == -1) { - fatal("bRet is -1\n"); - } - - /* On WM_QUIT, tell the CPU thread to stop running. That will then tell us - to stop running as well. */ - if (messages.message == WM_QUIT) - cpu_thread_run = 0; - - if (!TranslateAccelerator(hwnd, haccel, &messages)) { - /* Don't process other keypresses. */ - if (messages.message == WM_SYSKEYDOWN || messages.message == WM_SYSKEYUP || messages.message == WM_KEYDOWN || messages.message == WM_KEYUP) - continue; - - TranslateMessage(&messages); - DispatchMessage(&messages); - } - - if (mouse_capture && keyboard_ismsexit()) { - /* Release the in-app mouse. */ - plat_mouse_capture(0); - } - - if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { - /* Signal "exit fullscreen mode". */ - fs_off_signal = 1; - } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { - plat_setfullscreen(0); - fs_off_signal = 0; - } - - if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { - /* Signal "enter fullscreen mode". */ - fs_on_signal = 1; - } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { - plat_setfullscreen(1); - fs_on_signal = 0; - } - -#ifdef DISCORD - /* Run Discord API callbacks */ - if (enable_discord) - discord_run_callbacks(); -#endif - } - - timeEndPeriod(1); - - if (mouse_capture) - plat_mouse_capture(0); - - /* Close down the emulator. */ - do_stop(); - - UnregisterClass(SDL_SUB_CLASS_NAME, hinstance); - UnregisterClass(SDL_CLASS_NAME, hinstance); - UnregisterClass(SUB_CLASS_NAME, hinstance); - UnregisterClass(CLASS_NAME, hinstance); - - win_mouse_close(); - -#ifdef DISCORD - /* Shut down the Discord integration */ - discord_close(); -#endif - - if (user32_handle != NULL) - dynld_close(user32_handle); - - return (messages.wParam); -} - -/* We should have the language ID as a parameter. */ -void -plat_pause(int p) -{ - static wchar_t oldtitle[512]; - wchar_t title[512]; - - /* If un-pausing, as the renderer if that's OK. */ - if (p == 0) - p = get_vidpause(); - - /* If already so, done. */ - if (dopause == p) { - /* Send the WM to a manager if needed. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); - - return; - } - - if (p) { - if (mouse_capture) - plat_mouse_capture(0); - - wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); - wcscpy(title, oldtitle); - wcscat(title, plat_get_string(IDS_2051)); - ui_window_title(title); - } else - ui_window_title(oldtitle); - - /* If un-pausing, synchronize the internal clock with the host's time. */ - if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) - nvr_time_sync(); - - dopause = p; - - /* Update the actual menu. */ - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, - dopause ? MF_CHECKED : MF_UNCHECKED); - -#ifdef DISCORD - /* Update Discord status */ - if (enable_discord) - discord_update_activity(dopause); -#endif - - /* Update the toolbar */ - ToolBarUpdatePause(p); - - /* Send the WM to a manager if needed. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); -} - -/* Tell the UI about a new screen resolution. */ -void -plat_resize(int x, int y) -{ - /* First, see if we should resize the UI window. */ - if (!vid_resize) { - /* scale the screen base on DPI */ - if (dpi_scale) { - x = MulDiv(x, dpi, 96); - y = MulDiv(y, dpi, 96); - } - ResizeWindowByClientArea(hwndMain, x, y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } -} - -void -plat_resize_request(int w, int h, int monitor_index) -{ - atomic_store((&doresize_monitors[monitor_index]), 1); -} - -void -plat_mouse_capture(int on) -{ - RECT rect; - - if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse()) - return; - - if (on && !mouse_capture) { - /* Enable the in-app mouse. */ - GetClipCursor(&oldclip); - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - show_cursor(0); - mouse_capture = 1; - } else if (!on && mouse_capture) { - /* Disable the in-app mouse. */ - ClipCursor(&oldclip); - show_cursor(-1); - - mouse_capture = 0; - } -} - -void -ui_init_monitor(UNUSED(int monitor_index)) -{ - // Nothing done here yet -} - -void -ui_deinit_monitor(UNUSED(int monitor_index)) -{ - // Nothing done here yet -} - -void -ui_hard_reset_completed(void) -{ - // Nothing done here yet -} From 0fa576d8bb84db8696fb8ca237bf2ec0061ad0e7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 16 Mar 2024 01:45:23 +0600 Subject: [PATCH 261/690] Compile fixes for Qt6 on Windows --- src/qt/qt_main.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index f87f8b6a9..1523d9a62 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -17,6 +17,10 @@ * Copyright 2021-2022 Cacodemon345 * Copyright 2021-2022 Teemu Korhonen */ + +#ifdef _WIN32 +#define UNICODE 1 +#endif #include #include #include @@ -220,13 +224,13 @@ main(int argc, char *argv[]) #ifdef Q_OS_WINDOWS # if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) - HWND winbox = FindWindow("TWinBoxMain", NULL); + HWND winbox = FindWindow(L"TWinBoxMain", NULL); if (winbox && - FindWindowEx(winbox, NULL, "TToolBar", NULL) && - FindWindowEx(winbox, NULL, "TListBox", NULL) && - FindWindowEx(winbox, NULL, "TStatusBar", NULL) && - (winbox = FindWindowEx(winbox, NULL, "TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ - FindWindowEx(winbox, NULL, "TTabSheet", NULL)) + FindWindowEx(winbox, NULL, L"TToolBar", NULL) && + FindWindowEx(winbox, NULL, L"TListBox", NULL) && + FindWindowEx(winbox, NULL, L"TStatusBar", NULL) && + (winbox = FindWindowEx(winbox, NULL, L"TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ + FindWindowEx(winbox, NULL, L"TTabSheet", NULL)) # endif { QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("WinBox is no longer supported"), From 5d57026af423f54c01e116187b69e3147fb29ffe Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 04:07:27 +0500 Subject: [PATCH 262/690] Fix Ghostscript DLL filename in an error message on 64-bit Windows --- src/qt/qt_platform.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 46d50672e..385a8c56f 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,7 +581,11 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# define LIB_NAME_GS "gsdll32.dll" +# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define LIB_NAME_GS "gsdll64.dll" +# else +# define LIB_NAME_GS "gsdll32.dll" +#endif # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" From a46fb2e76b2f53ec29092c6fa52667b28cb61372 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:37:46 +0500 Subject: [PATCH 263/690] Fix up the arch check for the GS DLL filename --- src/qt/qt_platform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 385a8c56f..824f71023 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,11 +581,11 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) # define LIB_NAME_GS "gsdll64.dll" # else # define LIB_NAME_GS "gsdll32.dll" -#endif +# endif # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" From d212aad3179264a61ded8c91c83fdac78457e31a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:38:57 +0500 Subject: [PATCH 264/690] Add missing period to error messages to fix their translations --- src/qt/qt_harddiskdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 5dab101b8..187bf4ba2 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -567,7 +567,7 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } else if (image_is_vhd(fileNameUtf8.data(), 1)) { MVHDMeta *vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); if (vhd == nullptr) { - QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } else if (vhd_error == MVHD_ERR_TIMESTAMP) { QMessageBox::StandardButton btn = QMessageBox::warning(this, tr("Parent and child disk timestamps do not match"), tr("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?"), QMessageBox::Yes | QMessageBox::No); @@ -618,7 +618,7 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } if ((sectors > max_sectors) || (heads > max_heads) || (cylinders > max_cylinders)) { - QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } From 5b96375baf9da73b83765a21489ce01285b2b3c3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:39:17 +0500 Subject: [PATCH 265/690] Sort the language dropdown alphabetically --- src/qt/qt_progsettings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4dda901d7..164f69418 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -110,6 +110,7 @@ ProgSettings::ProgSettings(QWidget *parent) ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key())); } } + ui->comboBoxLanguage->model()->sort(Qt::AscendingOrder); mouseSensitivity = mouse_sensitivity; ui->horizontalSlider->setValue(mouseSensitivity * 100.); From 84cdb5ea3507fa7d6f906a348c440caa3e4bab20 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:46:49 +0500 Subject: [PATCH 266/690] CMake: hardcode the Qt UI option to ON on Windows --- CMakeLists.txt | 7 ++++++- src/CMakeLists.txt | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae39fbccf..1dfed3fb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,9 +136,14 @@ option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) option(GDBSTUB "Enable GDB stub server for debugging" OFF) option(DEV_BRANCH "Development branch" OFF) -option(QT "Qt GUI" ON) option(DISCORD "Discord Rich Presence support" ON) +if(WIN32) + set(QT ON) +else() + option(QT "Qt GUI" ON) +endif() + # Development branch features # # Option Description Def. Condition Otherwise diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec32d7548..7030e9f63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -226,8 +226,6 @@ endif() if (QT) add_subdirectory(qt) -elseif(WIN32) - add_subdirectory(win) else() add_compile_definitions(USE_SDL_UI) add_subdirectory(unix) From b3819f69629a585fe48b25cbec88ee157c8a6e90 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:47:59 +0500 Subject: [PATCH 267/690] Remove or trim leftover header files --- bumpversion.sh | 12 - src/include/86box/resource.h | 524 --------------------------- src/include/86box/win.h | 202 ----------- src/include/86box/win_opengl.h | 29 -- src/include/86box/win_opengl_glslp.h | 24 -- src/include/86box/win_sdl.h | 63 ---- src/include_make/86box/version.h | 49 --- 7 files changed, 903 deletions(-) delete mode 100644 src/include/86box/resource.h delete mode 100644 src/include/86box/win_opengl.h delete mode 100644 src/include/86box/win_opengl_glslp.h delete mode 100644 src/include/86box/win_sdl.h delete mode 100644 src/include_make/86box/version.h diff --git a/bumpversion.sh b/bumpversion.sh index 4681e72be..6e2536cbe 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -26,12 +26,6 @@ then fi shift -# Extract version components. -newversion_maj=$(echo "$newversion" | cut -d. -f1) -newversion_min=$(echo "$newversion" | cut -d. -f2) -newversion_patch=$(echo "$newversion" | cut -d. -f3) -[ -z "$newversion_patch" ] && newversion_patch=0 - if [ -z "${romversion}" ]; then # Get the latest ROM release from the GitHub API. romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | @@ -62,12 +56,6 @@ patch_file() { } patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/' patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/' -patch_file src/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/' -patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/' -patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/' -patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/' -patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/' -patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/' patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/' patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h deleted file mode 100644 index 2e6628c77..000000000 --- a/src/include/86box/resource.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows resource defines. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021-2022 Jasmine Iwanek. - */ - -#ifndef WIN_RESOURCE_H -#define WIN_RESOURCE_H - -/* Dialog IDs. */ -#define DLG_ABOUT 101 /* top-level dialog */ -#define DLG_STATUS 102 /* top-level dialog */ -#define DLG_SND_GAIN 103 /* top-level dialog */ -#define DLG_NEW_FLOPPY 104 /* top-level dialog */ -#define DLG_SPECIFY_DIM 105 /* top-level dialog */ -#define DLG_PREFERENCES 106 /* top-level dialog */ -#define DLG_CONFIG 110 /* top-level dialog */ -#define DLG_CFG_MACHINE 111 /* sub-dialog of config */ -#define DLG_CFG_VIDEO 112 /* sub-dialog of config */ -#define DLG_CFG_INPUT 113 /* sub-dialog of config */ -#define DLG_CFG_SOUND 114 /* sub-dialog of config */ -#define DLG_CFG_NETWORK 115 /* sub-dialog of config */ -#define DLG_CFG_PORTS 116 /* sub-dialog of config */ -#define DLG_CFG_STORAGE 117 /* sub-dialog of config */ -#define DLG_CFG_HARD_DISKS 118 /* sub-dialog of config */ -#define DLG_CFG_HARD_DISKS_ADD 119 /* sub-dialog of config */ -#define DLG_CFG_FLOPPY_AND_CDROM_DRIVES 120 /* sub-dialog of config */ -#define DLG_CFG_OTHER_REMOVABLE_DEVICES 121 /* sub-dialog of config */ -#define DLG_CFG_PERIPHERALS 122 /* sub-dialog of config */ - -/* Static text label IDs. */ - -/* DLG_SND_GAIN */ -#define IDT_GAIN 1700 /* Gain */ - -/* DLG_NEW_FLOPPY */ -#define IDT_FLP_FILE_NAME 1701 /* File name: */ -#define IDT_FLP_DISK_SIZE 1702 /* Disk size: */ -#define IDT_FLP_RPM_MODE 1703 /* RPM mode: */ -#define IDT_FLP_PROGRESS 1704 /* Progress: */ - -/* DLG_SPECIFY_DIM */ -#define IDT_WIDTH 1705 /* ??? */ -#define IDT_HEIGHT 1706 /* ??? */ - -/* DLG_CFG_MACHINE */ -#define IDT_MACHINE_TYPE 1707 /* Machine type: */ -#define IDT_MACHINE 1708 /* Machine: */ -#define IDT_CPU_TYPE 1709 /* CPU type: */ -#define IDT_CPU_SPEED 1710 /* CPU speed: */ -#define IDT_FPU 1711 /* FPU: */ -#define IDT_WAIT_STATES 1712 /* Wait states: */ -#define IDT_MB 1713 /* MB == IDC_TEXT_MB */ -#define IDT_MEMORY 1714 /* Memory: */ - -/* DLG_CFG_VIDEO */ -#define IDT_VIDEO 1715 /* Video: */ -#define IDT_VIDEO_2 1716 /* Video 2: */ - -/* DLG_CFG_INPUT */ -#define IDT_MOUSE 1717 /* Mouse: */ -#define IDT_JOYSTICK 1718 /* Joystick: */ - -/* DLG_CFG_SOUND */ -#define IDT_SOUND1 1719 /* Sound card #1: */ -#define IDT_SOUND2 1720 /* Sound card #2: */ -#define IDT_SOUND3 1721 /* Sound card #3: */ -#define IDT_SOUND4 1722 /* Sound card #4: */ -#define IDT_MIDI_OUT 1723 /* MIDI Out Device: */ -#define IDT_MIDI_IN 1724 /* MIDI In Device: */ - -/* DLG_CFG_NETWORK */ -#define IDT_NET_TYPE 1725 /* Network type: */ -#define IDT_PCAP 1726 /* PCap device: */ -#define IDT_NET 1727 /* Network adapter: */ -#define IDT_NET1 1728 /* Network adapter 1: */ -#define IDT_NET2 1729 /* Network adapter 2: */ -#define IDT_NET3 1730 /* Network adapter 3: */ -#define IDT_NET4 1731 /* Network adapter 4: */ - -/* DLG_CFG_PORTS */ -#define IDT_COM1 1732 /* COM1 Device: */ -#define IDT_COM2 1733 /* COM1 Device: */ -#define IDT_COM3 1734 /* COM1 Device: */ -#define IDT_COM4 1735 /* COM1 Device: */ - -#define IDT_LPT1 1736 /* LPT1 Device: */ -#define IDT_LPT2 1737 /* LPT2 Device: */ -#define IDT_LPT3 1738 /* LPT3 Device: */ -#define IDT_LPT4 1739 /* LPT4 Device: */ - -/* DLG_CFG_STORAGE */ -#define IDT_HDC 1740 /* HD Controller: */ -#define IDT_FDC 1741 /* Ext FD Controller: */ -#define IDT_SCSI_1 1742 /* SCSI Board #1: */ -#define IDT_SCSI_2 1743 /* SCSI Board #2: */ -#define IDT_SCSI_3 1744 /* SCSI Board #3: */ -#define IDT_SCSI_4 1745 /* SCSI Board #4: */ - -/* DLG_CFG_HARD_DISKS */ -#define IDT_HDD 1746 /* Hard disks: */ -#define IDT_BUS 1747 /* Bus: */ -#define IDT_CHANNEL 1748 /* Channel: */ -#define IDT_ID 1749 /* ID: */ -#define IDT_LUN 1750 /* LUN: */ -#define IDT_SPEED 1751 /* Speed: */ - -/* DLG_CFG_HARD_DISKS_ADD */ -#define IDT_SECTORS 1752 /* Sectors: */ -#define IDT_HEADS 1753 /* Heads: */ -#define IDT_CYLS 1754 /* Cylinders: */ -#define IDT_SIZE_MB 1755 /* Size (MB): */ -#define IDT_TYPE 1756 /* Type: */ -#define IDT_FILE_NAME 1757 /* File name: */ -#define IDT_IMG_FORMAT 1758 /* Image Format: */ -#define IDT_BLOCK_SIZE 1759 /* Block Size: */ -#define IDT_PROGRESS 1760 /* Progress: */ - -/* DLG_CFG_FLOPPY_AND_CDROM_DRIVES */ -#define IDT_FLOPPY_DRIVES 1761 /* Floppy drives: */ -#define IDT_FDD_TYPE 1762 /* Type: */ -#define IDT_CD_DRIVES 1763 /* CD-ROM drives: */ -#define IDT_CD_BUS 1764 /* Bus: */ -#define IDT_CD_ID 1765 /* ID: */ -#define IDT_CD_LUN 1766 /* LUN: */ -#define IDT_CD_CHANNEL 1767 /* Channel: */ -#define IDT_CD_SPEED 1768 /* Speed: */ -#define IDT_CD_TYPE 1769 /* Type: */ - -/* DLG_CFG_OTHER_REMOVABLE_DEVICES */ -#define IDT_MO_DRIVES 1770 /* MO drives: */ -#define IDT_MO_BUS 1771 /* Bus: */ -#define IDT_MO_ID 1772 /* ID: */ -#define IDT_MO_CHANNEL 1773 /* Channel */ -#define IDT_MO_TYPE 1774 /* Type: */ - -#define IDT_ZIP_DRIVES 1775 /* ZIP drives: */ -#define IDT_ZIP_BUS 1776 /* Bus: */ -#define IDT_ZIP_ID 1777 /* ID: */ -#define IDT_ZIP_LUN 1778 /* LUN: */ -#define IDT_ZIP_CHANNEL 1779 /* Channel: */ - -/* DLG_CFG_PERIPHERALS */ -#define IDT_ISARTC 1780 /* ISA RTC: */ -#define IDT_ISAMEM_1 1781 /* ISAMEM Board #1: */ -#define IDT_ISAMEM_2 1782 /* ISAMEM Board #2: */ -#define IDT_ISAMEM_3 1783 /* ISAMEM Board #3: */ -#define IDT_ISAMEM_4 1784 /* ISAMEM Board #4: */ - -/* - * To try to keep these organized, we now group the - * constants per dialog, as this allows easy adding - * and deleting items. - */ -#define IDC_SETTINGSCATLIST 1001 /* generic config */ -#define IDC_CFILE 1002 /* Select File dialog */ -#define IDC_TIME_SYNC 1005 -#define IDC_RADIO_TS_DISABLED 1006 -#define IDC_RADIO_TS_LOCAL 1007 -#define IDC_RADIO_TS_UTC 1008 - -#define IDC_COMBO_MACHINE_TYPE 1010 -#define IDC_COMBO_MACHINE 1011 /* machine/cpu config */ -#define IDC_CONFIGURE_MACHINE 1012 -#define IDC_COMBO_CPU_TYPE 1013 -#define IDC_COMBO_CPU_SPEED 1014 -#define IDC_COMBO_FPU 1015 -#define IDC_COMBO_WS 1016 -#ifdef USE_DYNAREC -# define IDC_CHECK_DYNAREC 1017 -#endif -#define IDC_CHECK_SOFTFLOAT 1018 -#define IDC_MEMTEXT 1019 -#define IDC_MEMSPIN 1020 -#define IDC_TEXT_MB IDT_MB - -#define IDC_VIDEO 1021 /* video config */ -#define IDC_COMBO_VIDEO 1022 -#define IDC_VIDEO_2 1023 -#define IDC_COMBO_VIDEO_2 1024 -#define IDC_CHECK_VOODOO 1025 -#define IDC_BUTTON_VOODOO 1026 -#define IDC_CHECK_IBM8514 1027 -#define IDC_CHECK_XGA 1028 -#define IDC_BUTTON_XGA 1029 - -#define IDC_INPUT 1030 /* input config */ -#define IDC_COMBO_MOUSE 1031 -#define IDC_COMBO_JOYSTICK 1032 -#define IDC_COMBO_JOY 1033 -#define IDC_CONFIGURE_MOUSE 1034 - -#define IDC_SOUND 1040 /* sound config */ -#define IDC_COMBO_SOUND1 1041 -#define IDC_COMBO_SOUND2 1042 -#define IDC_COMBO_SOUND3 1043 -#define IDC_COMBO_SOUND4 1044 -#define IDC_COMBO_MIDI_OUT 1045 -#define IDC_CHECK_MPU401 1046 -#define IDC_CONFIGURE_MPU401 1047 -#define IDC_CHECK_FLOAT 1048 -#define IDC_CONFIGURE_GUS 1049 -#define IDC_COMBO_MIDI_IN 1050 -#define IDC_CONFIGURE_CMS 1051 -#define IDC_CONFIGURE_SSI 1052 -#define IDC_FM_DRIVER 1053 -#define IDC_RADIO_FM_DRV_NUKED 1054 -#define IDC_RADIO_FM_DRV_YMFM 1055 - -#define IDC_COMBO_NET1_TYPE 1060 /* network config */ -#define IDC_COMBO_NET2_TYPE 1061 -#define IDC_COMBO_NET3_TYPE 1062 -#define IDC_COMBO_NET4_TYPE 1063 -#define IDC_COMBO_PCAP1 1064 -#define IDC_COMBO_PCAP2 1065 -#define IDC_COMBO_PCAP3 1066 -#define IDC_COMBO_PCAP4 1067 -#define IDC_COMBO_NET1 1068 -#define IDC_COMBO_NET2 1069 -#define IDC_COMBO_NET3 1070 -#define IDC_COMBO_NET4 1071 - -#define IDC_COMBO_LPT1 1080 /* ports config */ -#define IDC_COMBO_LPT2 1081 -#define IDC_COMBO_LPT3 1082 -#define IDC_COMBO_LPT4 1083 -#define IDC_CHECK_SERIAL1 1084 -#define IDC_CHECK_SERIAL2 1085 -#define IDC_CHECK_SERIAL3 1086 -#define IDC_CHECK_SERIAL4 1087 -#define IDC_CHECK_PARALLEL1 1088 -#define IDC_CHECK_PARALLEL2 1089 -#define IDC_CHECK_PARALLEL3 1090 -#define IDC_CHECK_PARALLEL4 1091 -#define IDC_CHECK_SERIAL_PASS1 1092 -#define IDC_CHECK_SERIAL_PASS2 1093 -#define IDC_CHECK_SERIAL_PASS3 1094 -#define IDC_CHECK_SERIAL_PASS4 1095 - -#define IDC_OTHER_PERIPH 1110 /* storage controllers config */ -#define IDC_COMBO_HDC 1111 -#define IDC_CONFIGURE_HDC 1112 -#define IDC_CHECK_IDE_TER 1113 -#define IDC_BUTTON_IDE_TER 1114 -#define IDC_CHECK_IDE_QUA 1115 -#define IDC_BUTTON_IDE_QUA 1116 -#define IDC_GROUP_SCSI 1117 -#define IDC_COMBO_SCSI_1 1118 -#define IDC_COMBO_SCSI_2 1119 -#define IDC_COMBO_SCSI_3 1120 -#define IDC_COMBO_SCSI_4 1121 -#define IDC_CONFIGURE_SCSI_1 1122 -#define IDC_CONFIGURE_SCSI_2 1123 -#define IDC_CONFIGURE_SCSI_3 1124 -#define IDC_CONFIGURE_SCSI_4 1125 -#define IDC_CHECK_CASSETTE 1126 - -#define IDC_HARD_DISKS 1130 /* hard disks config */ -#define IDC_LIST_HARD_DISKS 1131 -#define IDC_BUTTON_HDD_ADD_NEW 1132 -#define IDC_BUTTON_HDD_ADD 1133 -#define IDC_BUTTON_HDD_REMOVE 1134 -#define IDC_COMBO_HD_BUS 1135 -#define IDC_COMBO_HD_CHANNEL 1136 -#define IDC_COMBO_HD_ID 1137 -#define IDC_COMBO_HD_SPEED 1138 -#define IDC_COMBO_HD_CHANNEL_IDE 1139 - -#define IDC_EDIT_HD_FILE_NAME 1140 /* add hard disk dialog */ -#define IDC_EDIT_HD_SPT 1141 -#define IDC_EDIT_HD_HPC 1142 -#define IDC_EDIT_HD_CYL 1143 -#define IDC_EDIT_HD_SIZE 1144 -#define IDC_COMBO_HD_TYPE 1145 -#define IDC_PBAR_IMG_CREATE 1146 -#define IDC_COMBO_HD_IMG_FORMAT 1147 -#define IDC_COMBO_HD_BLOCK_SIZE 1148 - -#define IDC_REMOV_DEVICES 1150 /* floppy and cd-rom drives config */ -#define IDC_LIST_FLOPPY_DRIVES 1151 -#define IDC_COMBO_FD_TYPE 1152 -#define IDC_CHECKTURBO 1153 -#define IDC_CHECKBPB 1154 -#define IDC_LIST_CDROM_DRIVES 1155 -#define IDC_COMBO_CD_BUS 1156 -#define IDC_COMBO_CD_ID 1157 -#define IDC_COMBO_CD_LUN 1158 -#define IDC_COMBO_CD_CHANNEL_IDE 1159 -#define IDC_COMBO_CD_TYPE 1160 - -#define IDC_LIST_ZIP_DRIVES 1170 /* other removable devices config */ -#define IDC_COMBO_ZIP_BUS 1171 -#define IDC_COMBO_ZIP_ID 1172 -#define IDC_COMBO_ZIP_LUN 1173 -#define IDC_COMBO_ZIP_CHANNEL_IDE 1174 -#define IDC_CHECK250 1175 -#define IDC_COMBO_CD_SPEED 1176 -#define IDC_LIST_MO_DRIVES 1177 -#define IDC_COMBO_MO_BUS 1178 -#define IDC_COMBO_MO_ID 1179 -#define IDC_COMBO_MO_LUN 1170 -#define IDC_COMBO_MO_CHANNEL_IDE 1181 -#define IDC_COMBO_MO_TYPE 1182 - -#define IDC_CHECK_BUGGER 1190 /* other periph config */ -#define IDC_CHECK_POSTCARD 1191 -#define IDC_COMBO_ISARTC 1192 -#define IDC_CONFIGURE_ISARTC 1193 -#define IDC_COMBO_FDC 1194 -#define IDC_CONFIGURE_FDC 1195 -#define IDC_GROUP_ISAMEM 1196 -#define IDC_COMBO_ISAMEM_1 1197 -#define IDC_COMBO_ISAMEM_2 1198 -#define IDC_COMBO_ISAMEM_3 1199 -#define IDC_COMBO_ISAMEM_4 1200 -#define IDC_CONFIGURE_ISAMEM_1 1201 -#define IDC_CONFIGURE_ISAMEM_2 1202 -#define IDC_CONFIGURE_ISAMEM_3 1203 -#define IDC_CONFIGURE_ISAMEM_4 1204 - -#define IDC_SLIDER_GAIN 1210 /* sound gain dialog */ - -#define IDC_EDIT_FILE_NAME 1220 /* new floppy image dialog */ -#define IDC_COMBO_DISK_SIZE 1221 -#define IDC_COMBO_RPM_MODE 1222 - -#define IDC_COMBO_LANG 1009 /* change language dialog */ -#define IDC_COMBO_ICON 1010 -#define IDC_CHECKBOX_GLOBAL 1300 -#define IDC_BUTTON_DEFAULT 1302 -#define IDC_BUTTON_DEFICON 1304 - -/* For the DeviceConfig code, re-do later. */ -#define IDC_CONFIG_BASE 1300 -#define IDC_CONFIGURE_VID 1300 -#define IDC_CONFIGURE_VID_2 1301 -#define IDC_CONFIGURE_SND1 1302 -#define IDC_CONFIGURE_SND2 1303 -#define IDC_CONFIGURE_SND3 1304 -#define IDC_CONFIGURE_SND4 1305 -#define IDC_CONFIGURE_VOODOO 1306 -#define IDC_CONFIGURE_NET1_TYPE 1310 -#define IDC_CONFIGURE_NET2_TYPE 1311 -#define IDC_CONFIGURE_NET3_TYPE 1312 -#define IDC_CONFIGURE_NET4_TYPE 1313 -#define IDC_CONFIGURE_PCAP1 1314 -#define IDC_CONFIGURE_PCAP2 1315 -#define IDC_CONFIGURE_PCAP3 1316 -#define IDC_CONFIGURE_PCAP4 1317 -#define IDC_CONFIGURE_NET1 1318 -#define IDC_CONFIGURE_NET2 1319 -#define IDC_CONFIGURE_NET3 1320 -#define IDC_CONFIGURE_NET4 1321 -#define IDC_CONFIGURE_MIDI_OUT 1322 -#define IDC_CONFIGURE_MIDI_IN 1323 -#define IDC_CONFIGURE_SERIAL_PASS1 1324 -#define IDC_CONFIGURE_SERIAL_PASS2 1325 -#define IDC_CONFIGURE_SERIAL_PASS3 1326 -#define IDC_CONFIGURE_SERIAL_PASS4 1327 -#define IDC_JOY1 1330 -#define IDC_JOY2 1331 -#define IDC_JOY3 1332 -#define IDC_JOY4 1333 -#define IDC_HDTYPE 1380 -#define IDC_RENDER 1381 -#define IDC_STATUS 1382 - -#define IDC_EDIT_WIDTH 1400 /* specify main window dimensions dialog */ -#define IDC_WIDTHSPIN 1401 -#define IDC_EDIT_HEIGHT 1402 -#define IDC_HEIGHTSPIN 1403 -#define IDC_CHECK_LOCK_SIZE 1404 - -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 -#define IDM_ACTION_KBD_REQ_CAPTURE 40010 -#define IDM_ACTION_RCTRL_IS_LALT 40011 -#define IDM_ACTION_SCREENSHOT 40012 -#define IDM_ACTION_HRESET 40013 -#define IDM_ACTION_RESET_CAD 40014 -#define IDM_ACTION_EXIT 40015 -#define IDM_ACTION_CTRL_ALT_ESC 40016 -#define IDM_ACTION_PAUSE 40017 -#ifdef MTR_ENABLED -# define IDM_ACTION_BEGIN_TRACE 40018 -# define IDM_ACTION_END_TRACE 40019 -# define IDM_ACTION_TRACE 40020 -#endif -#define IDM_CONFIG 40021 -#define IDM_VID_HIDE_STATUS_BAR 40022 -#define IDM_VID_HIDE_TOOLBAR 40023 -#define IDM_UPDATE_ICONS 40030 -#define IDM_SND_GAIN 40031 -#define IDM_VID_MONITORS 40040 -#define IDM_VID_RESIZE 40041 -#define IDM_VID_REMEMBER 40042 -#define IDM_VID_SDL_SW 40050 -#define IDM_VID_SDL_HW 40051 -#define IDM_VID_SDL_OPENGL 40052 -#define IDM_VID_OPENGL_CORE 40053 -#ifdef USE_VNC -# define IDM_VID_VNC 40054 -#endif -#define IDM_VID_SCALE_1X 40055 -#define IDM_VID_SCALE_2X 40056 -#define IDM_VID_SCALE_3X 40057 -#define IDM_VID_SCALE_4X 40058 -#define IDM_VID_SCALE_5X 40059 -#define IDM_VID_SCALE_6X 40060 -#define IDM_VID_SCALE_7X 40061 -#define IDM_VID_SCALE_8X 40062 -#define IDM_VID_SCALE_9X 40063 -#define IDM_VID_SCALE_10X 40064 - -#define IDM_VID_HIDPI 40065 -#define IDM_VID_FULLSCREEN 40066 -#define IDM_VID_FS_FULL 40067 -#define IDM_VID_FS_43 40068 -#define IDM_VID_FS_KEEPRATIO 40069 -#define IDM_VID_FS_INT 40070 -#define IDM_VID_SPECIFY_DIM 40071 -#define IDM_VID_FORCE43 40072 -#define IDM_VID_OVERSCAN 40073 -#define IDM_VID_INVERT 40074 -#define IDM_VID_CGACON 40075 -#define IDM_VID_GRAYCT_601 40076 -#define IDM_VID_GRAYCT_709 40077 -#define IDM_VID_GRAYCT_AVE 40078 -#define IDM_VID_GRAY_RGB 40080 -#define IDM_VID_GRAY_MONO 40081 -#define IDM_VID_GRAY_AMBER 40082 -#define IDM_VID_GRAY_GREEN 40083 -#define IDM_VID_GRAY_WHITE 40084 -#define IDM_VID_FILTER_NEAREST 40085 -#define IDM_VID_FILTER_LINEAR 40086 - -#define IDM_MEDIA 40087 -#define IDM_DOCS 40088 - -#define IDM_DISCORD 40090 - -#define IDM_PREFERENCES 40091 - -#define IDM_VID_GL_FPS_BLITTER 40100 -#define IDM_VID_GL_FPS_25 40101 -#define IDM_VID_GL_FPS_30 40102 -#define IDM_VID_GL_FPS_50 40103 -#define IDM_VID_GL_FPS_60 40104 -#define IDM_VID_GL_FPS_75 40105 -#define IDM_VID_GL_VSYNC 40106 -#define IDM_VID_GL_SHADER 40107 -#define IDM_VID_GL_NOSHADER 40108 - -/* - * We need 7 bits for CDROM (2 bits ID and 5 bits for host drive), - * and 5 bits for Removable Disks (5 bits for ID), so we use an - * 8bit (256 entries) space for these devices. - */ -#define IDM_CASSETTE_IMAGE_NEW 0x1200 -#define IDM_CASSETTE_IMAGE_EXISTING 0x1300 -#define IDM_CASSETTE_IMAGE_EXISTING_WP 0x1400 -#define IDM_CASSETTE_RECORD 0x1500 -#define IDM_CASSETTE_PLAY 0x1600 -#define IDM_CASSETTE_REWIND 0x1700 -#define IDM_CASSETTE_FAST_FORWARD 0x1800 -#define IDM_CASSETTE_EJECT 0x1900 - -#define IDM_CARTRIDGE_IMAGE 0x2200 -#define IDM_CARTRIDGE_EJECT 0x2300 - -#define IDM_FLOPPY_IMAGE_NEW 0x3200 -#define IDM_FLOPPY_IMAGE_EXISTING 0x3300 -#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x3400 -#define IDM_FLOPPY_EXPORT_TO_86F 0x3500 -#define IDM_FLOPPY_EJECT 0x3600 - -#define IDM_CDROM_MUTE 0x4200 -#define IDM_CDROM_EMPTY 0x4300 -#define IDM_CDROM_RELOAD 0x4400 -#define IDM_CDROM_IMAGE 0x4500 -#define IDM_CDROM_DIR 0x4600 -#define IDM_CDROM_HOST_DRIVE 0x4700 - -#define IDM_ZIP_IMAGE_NEW 0x5200 -#define IDM_ZIP_IMAGE_EXISTING 0x5300 -#define IDM_ZIP_IMAGE_EXISTING_WP 0x5400 -#define IDM_ZIP_EJECT 0x5500 -#define IDM_ZIP_RELOAD 0x5600 - -#define IDM_MO_IMAGE_NEW 0x6200 -#define IDM_MO_IMAGE_EXISTING 0x6300 -#define IDM_MO_IMAGE_EXISTING_WP 0x6400 -#define IDM_MO_EJECT 0x6500 -#define IDM_MO_RELOAD 0x6600 - -/* Next default values for new objects */ -#ifdef APSTUDIO_INVOKED -# ifndef APSTUDIO_READONLY_SYMBOLS -# define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 1400 -# define _APS_NEXT_COMMAND_VALUE 55000 -# define _APS_NEXT_CONTROL_VALUE 1800 -# define _APS_NEXT_SYMED_VALUE 200 -# endif -#endif - -#endif /*WIN_RESOURCE_H*/ diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 35f6688ad..5cead7cb0 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -26,50 +26,7 @@ #ifndef UNICODE # define UNICODE #endif -#define BITMAP WINDOWS_BITMAP -#if 0 -# ifdef _WIN32_WINNT -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0501 -# endif -#endif -#include "resource.h" #include -#undef BITMAP - -/* DPI Awareness Context, copied from MinGW-w64 windef.h */ -#ifndef _DPI_AWARENESS_CONTEXTS_ -DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); -# define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT) -1) -# define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT) -2) -# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT) -3) -# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4) -# define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT) -5) -#endif - -#ifndef WM_DPICHANGED_AFTERPARENT -# define WM_DPICHANGED_AFTERPARENT 0x02E3 -#endif - -/* Class names and such. */ -#define CLASS_NAME L"86BoxMainWnd" -#define MENU_NAME L"MainMenu" -#define ACCEL_NAME L"MainAccel" -#define SUB_CLASS_NAME L"86BoxSubWnd" -#define SB_CLASS_NAME L"86BoxStatusBar" -#define SB_MENU_NAME L"StatusBarMenu" -#define FS_CLASS_NAME L"86BoxFullScreen" -#define SDL_CLASS_NAME L"86BoxSDLWnd" -#define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd" - -#define CASSETTE_SUBMENU_NAME L"CassetteSubmenu" -#define CARTRIDGE_SUBMENU_NAME L"CartridgeSubmenu" -#define FLOPPY_SUBMENU_NAME L"FloppySubmenu" -#define CDROM_SUBMENU_NAME L"CdromSubmenu" -#define ZIP_SUBMENU_NAME L"ZIPSubmenu" -#define MO_SUBMENU_NAME L"MOSubmenu" - -#define VID_GL_SUBMENU L"VidGLSubMenu" /* Application-specific window messages. @@ -92,163 +49,4 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); /* The emulator has shut down. */ #define WM_HAS_SHUTDOWN 0x8897 -#ifdef USE_VNC -# define RENDERERS_NUM 5 -#else -# define RENDERERS_NUM 4 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern HINSTANCE hinstance; -extern HWND hwndMain; -extern HWND hwndRender; -extern HWND hwndRender2; -extern HANDLE ghMutex; -extern HICON hIcon[256]; -extern int dpi; -extern RECT oldclip; -extern int sbar_height; -extern int tbar_height; -extern int user_resize; -extern int acp_utf8; - -#if 0 -extern int status_is_open; -#endif - -extern char openfilestring[512]; -extern WCHAR wopenfilestring[512]; - -extern uint8_t filterindex; - -extern void ResizeWindowByClientArea(HWND hwnd, int width, int height); - -/* Emulator start/stop support functions. */ -extern void do_start(void); -extern void do_stop(void); - -/* Internal platform support functions. */ -extern int has_language_changed(uint32_t id); -extern void set_language(uint32_t id); -extern int get_vidpause(void); -extern void show_cursor(int); - -extern void keyboard_getkeymap(void); -extern void keyboard_handle(PRAWINPUT raw); - -extern void win_mouse_init(void); -extern void win_mouse_close(void); -extern void win_mouse_handle(PRAWINPUT raw); - -extern void win_joystick_handle(PRAWINPUT raw); - -extern void win_notify_dlg_open(void); -extern void win_notify_dlg_closed(void); -extern int win_get_dpi(HWND hwnd); -extern int win_get_system_metrics(int i, int dpi); - -extern LPARAM win_get_string(int id); - -extern void win_clear_icon_set(void); -extern void win_system_icon_set(void); -extern void win_load_icon_set(void); -extern void win_get_icons_path(char *path_root); - -extern intptr_t fdd_type_to_icon(int type); - -#ifdef EMU_DEVICE_H -extern uint8_t deviceconfig_open(HWND hwnd, const device_t *device); -extern uint8_t deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst); -#endif -extern uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type); - -extern int getfile(HWND hwnd, char *f, char *fn); -extern int getsfile(HWND hwnd, char *f, char *fn); - -extern void hard_disk_add_open(HWND hwnd, int is_existing); -extern int hard_disk_was_added(void); - -/* Platform UI support functions. */ -extern int ui_init(int nCmdShow); - -/* Functions in win_about.c: */ -extern void AboutDialogCreate(HWND hwnd); - -/* Functions in win_snd_gain.c: */ -extern void SoundGainDialogCreate(HWND hwnd); - -/* Functions in win_new_floppy.c: */ -extern void NewFloppyDialogCreate(HWND hwnd, int id, int part); - -/* Functions in win_specify_dim.c: */ -extern void SpecifyDimensionsDialogCreate(HWND hwnd); - -/* Functions in win_preferences.c: */ -extern void PreferencesDlgCreate(HWND hwnd); - -/* Functions in win_settings.c: */ -#define SETTINGS_PAGE_MACHINE 0 -#define SETTINGS_PAGE_VIDEO 1 -#define SETTINGS_PAGE_INPUT 2 -#define SETTINGS_PAGE_SOUND 3 -#define SETTINGS_PAGE_NETWORK 4 -#define SETTINGS_PAGE_PORTS 5 -#define SETTINGS_PAGE_STORAGE 6 -#define SETTINGS_PAGE_HARD_DISKS 7 -#define SETTINGS_PAGE_FLOPPY_AND_CDROM_DRIVES 8 -#define SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES 9 -#define SETTINGS_PAGE_PERIPHERALS 10 - -extern void win_settings_open(HWND hwnd); -extern void win_settings_open_ex(HWND hwnd, int category); - -/* Functions in win_stbar.c: */ -extern HWND hwndSBAR; -extern void StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst); -extern int MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -/* Functions in win_toolbar.c */ -extern HWND hwndRebar; -extern void ToolBarCreate(HWND hwndParent, HINSTANCE hInst); -extern void ToolBarLoadIcons(void); -extern void ToolBarUpdatePause(int paused); - -/* Functions in win_dialog.c: */ -/* Pass NULL in the title param to use the default title. */ -extern int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save); -extern int file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save); -extern int file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save); -extern int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, char *title, int save); -extern int file_dlg_st(HWND hwnd, int i, char *fn, char *title, int save); - -extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title); - -/* Functions in win_media_menu.c */ -extern void media_menu_init(void); -extern void media_menu_reset(void); -extern int media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -extern HMENU media_menu_get_cassette(void); -extern HMENU media_menu_get_cartridge(int id); -extern HMENU media_menu_get_floppy(int id); -extern HMENU media_menu_get_cdrom(int id); -extern HMENU media_menu_get_zip(int id); -extern HMENU media_menu_get_mo(int id); -extern void media_menu_update_cassette(void); -extern void media_menu_update_cartridge(int id); -extern void media_menu_update_floppy(int id); -extern void media_menu_update_cdrom(int id); -extern void media_menu_update_zip(int id); -extern void media_menu_update_mo(int id); - -/* Functions in win_ui.c */ -extern HMENU menuMain; -extern void ResetAllMenus(void); - -#ifdef __cplusplus -} -#endif - #endif /*PLAT_WIN_H*/ diff --git a/src/include/86box/win_opengl.h b/src/include/86box/win_opengl.h deleted file mode 100644 index d354131ef..000000000 --- a/src/include/86box/win_opengl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - * - * Header file for OpenGL rendering module - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - */ - -#ifndef WIN_OPENGL_H -#define WIN_OPENGL_H - -#define UNICODE -#include - -extern int opengl_init(HWND hwnd); -extern int opengl_pause(void); -extern void opengl_close(void); -extern void opengl_set_fs(int fs); -extern void opengl_resize(int w, int h); -extern void opengl_reload(void); - -#endif /*!WIN_OPENGL_H*/ diff --git a/src/include/86box/win_opengl_glslp.h b/src/include/86box/win_opengl_glslp.h deleted file mode 100644 index 6586cd526..000000000 --- a/src/include/86box/win_opengl_glslp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - * - * Header file for shader file parser. - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - */ - -#ifndef WIN_OPENGL_GLSLP_H -#define WIN_OPENGL_GLSLP_H - -#include - -GLuint load_custom_shaders(const char *path); -GLuint load_default_shaders(void); - -#endif /*!WIN_OPENGL_GLSLP_H*/ diff --git a/src/include/86box/win_sdl.h b/src/include/86box/win_sdl.h deleted file mode 100644 index 69340e8b6..000000000 --- a/src/include/86box/win_sdl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - * - * Definitions for the libSDL2 rendering module. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2019 Fred N. van Kempen. - * Copyright 2018-2019 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WIN_SDL_H -#define WIN_SDL_H - -extern void sdl_close(void); -extern int sdl_inits(HWND h); -extern int sdl_inith(HWND h); -extern int sdl_initho(HWND h); -extern int sdl_pause(void); -extern void sdl_resize(int x, int y); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); - -#endif /*WIN_SDL_H*/ diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h deleted file mode 100644 index 4bb6c71d7..000000000 --- a/src/include_make/86box/version.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Definitions for project version, branding, and external links. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2020 Miran Grca. - */ - -#define _LSTR(s) L ## s -#define LSTR(s) _LSTR(s) - -/* Version info. */ -#define EMU_NAME "86Box" -#define EMU_NAME_W LSTR(EMU_NAME) - -#define EMU_VERSION "4.1.1" -#define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ -#define EMU_VERSION_MAJ 4 -#define EMU_VERSION_MIN 1 -#define EMU_VERSION_PATCH 1 - -#define EMU_BUILD_NUM 0 - -#define EMU_VERSION_FULL EMU_VERSION -#define EMU_VERSION_FULL_W EMU_VERSION_W - -#define COPYRIGHT_YEAR "2024" - -/* Web URL info. */ -#define EMU_SITE "86box.net" -#define EMU_SITE_W LSTR(EMU_SITE) -#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" -#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) -#ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v4.1/" -#else -# define EMU_DOCS_URL "https://86box.readthedocs.io" -#endif -#define EMU_DOCS_URL_W LSTR(EMU_DOCS_URL) From 27e78da4ec9f849b60615c85792d9a5f87ad1737 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Mar 2024 17:10:36 +0100 Subject: [PATCH 268/690] WIP: PAS16. See above, currently very WIP. --- src/include/86box/pit.h | 28 ++- src/include/86box/pit_fast.h | 3 +- src/include/86box/sound.h | 2 - src/pit.c | 117 +++++---- src/pit_fast.c | 67 ++--- src/sound/CMakeLists.txt | 7 +- src/sound/snd_pas16.c | 475 ++++++++++++++++++----------------- src/sound/sound.c | 2 - 8 files changed, 381 insertions(+), 320 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index d288b7e6c..078694633 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -42,6 +42,7 @@ typedef struct ctr_t { int state; int null_count; int do_read_status; + int enable; union { int32_t count; @@ -57,7 +58,7 @@ typedef struct ctr_t { uint32_t l; void (*load_func)(uint8_t new_m, int new_count); - void (*out_func)(int new_out, int old_out); + void (*out_func)(int new_out, int old_out, void *priv); } ctr_t; typedef struct PIT { @@ -68,8 +69,12 @@ typedef struct PIT { ctr_t counters[3]; uint8_t ctrl; + void *dev_priv; + void (*dev_timer)(void *priv); } pit_t; +extern pit_t *ext_pit; + enum { PIT_8253 = 0, PIT_8254 = 1, @@ -87,7 +92,7 @@ typedef struct pit_intf_t { /* Sets if a counter's CLOCK input is from the timer or not - used by PCjr. */ void (*set_using_timer)(void *data, int counter_id, int using_timer); /* Sets a counter's OUT output handler. */ - void (*set_out_func)(void *data, int counter_id, void (*func)(int new_out, int old_out)); + void (*set_out_func)(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); /* Sets a counter's load count handler. */ void (*set_load_func)(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)); void (*ctr_clock)(void *data, int counter_id); @@ -113,20 +118,24 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; /* Sets a counter's CLOCK input. */ -extern void pit_ctr_set_clock(ctr_t *ctr, int clock); +extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); -extern pit_t *pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)); +extern void pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); + +extern void pit_ctr_set_using_timer(void *data, int counter_id, int using_timer); + +extern pit_t *pit_common_init(int type, void (*out0)(int new_out, int old_out, void *priv), void (*out1)(int new_out, int old_out, void *priv)); extern pit_t *pit_ps2_init(int type); extern void pit_reset(pit_t *dev); -extern void pit_irq0_timer_ps2(int new_out, int old_out); +extern void pit_irq0_timer_ps2(int new_out, int old_out, void *priv); -extern void pit_refresh_timer_xt(int new_out, int old_out); -extern void pit_refresh_timer_at(int new_out, int old_out); +extern void pit_refresh_timer_xt(int new_out, int old_out, void *priv); +extern void pit_refresh_timer_at(int new_out, int old_out, void *priv); -extern void pit_speaker_timer(int new_out, int old_out); +extern void pit_speaker_timer(int new_out, int old_out, void *priv); -extern void pit_nmi_timer_ps2(int new_out, int old_out); +extern void pit_nmi_timer_ps2(int new_out, int old_out, void *priv); extern void pit_set_clock(uint32_t clock); extern void pit_handler(int set, uint16_t base, int size, void *priv); @@ -135,6 +144,7 @@ extern uint8_t pit_read_reg(void *priv, uint8_t reg); #ifdef EMU_DEVICE_H extern const device_t i8253_device; +extern const device_t i8253_ext_io_device; extern const device_t i8254_device; extern const device_t i8254_sec_device; extern const device_t i8254_ext_io_device; diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 2485a360c..845105185 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -59,7 +59,8 @@ typedef struct ctrf_t { pc_timer_t timer; void (*load_func)(uint8_t new_m, int new_count); - void (*out_func)(int new_out, int old_out); + void (*out_func)(int new_out, int old_out, void *priv); + void *priv; } ctrf_t; typedef struct pitf_t { diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index b8f9be5b2..0359c0ff8 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -123,10 +123,8 @@ extern const device_t cms_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; -# if defined(DEV_BRANCH) && defined(USE_PAS16) /* Pro Audio Spectrum 16 */ extern const device_t pas16_device; -# endif /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; diff --git a/src/pit.c b/src/pit.c index 6045fd842..4f64d40c1 100644 --- a/src/pit.c +++ b/src/pit.c @@ -94,13 +94,15 @@ pit_log(const char *fmt, ...) #endif static void -ctr_set_out(ctr_t *ctr, int out) +ctr_set_out(ctr_t *ctr, int out, void *priv) { + pit_t *pit = (pit_t *)priv; + if (ctr == NULL) return; if (ctr->out_func != NULL) - ctr->out_func(out, ctr->out); + ctr->out_func(out, ctr->out, pit); ctr->out = out; } @@ -146,8 +148,9 @@ ctr_load_count(ctr_t *ctr) } static void -ctr_tick(ctr_t *ctr) +ctr_tick(ctr_t *ctr, void *priv) { + pit_t *pit = (pit_t *)priv; uint8_t state = ctr->state; if ((state & 0x03) == 0x01) { @@ -155,7 +158,7 @@ ctr_tick(ctr_t *ctr) ctr_load_count(ctr); ctr->state++; if (((ctr->m & 0x07) == 0x01) && (ctr->state == 2)) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } else switch (ctr->m & 0x07) { case 0: /* Interrupt on terminal count */ @@ -165,7 +168,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } } break; @@ -185,7 +188,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } } break; @@ -205,7 +208,7 @@ ctr_tick(ctr_t *ctr) case 3: ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); break; case 2: if (ctr->gate == 0) @@ -214,7 +217,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 2) { ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } } break; @@ -240,7 +243,7 @@ ctr_tick(ctr_t *ctr) if (ctr->count < 0) { ctr_load_count(ctr); ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -259,7 +262,7 @@ ctr_tick(ctr_t *ctr) if (ctr->count < 0) { ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -284,13 +287,13 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } } break; case 3: ctr->state = 0; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); break; default: @@ -316,7 +319,7 @@ ctr_clock(void *data, int counter_id) if (ctr->using_timer) return; - ctr_tick(ctr); + ctr_tick(ctr, pit); } static void @@ -351,7 +354,7 @@ ctr_load(ctr_t *ctr) if (ctr->load_func != NULL) ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); - pit_log("Counter loaded, state = %i, gate = %i\n", ctr->state, ctr->gate); + pclog("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } static __inline void @@ -390,7 +393,7 @@ ctr_latch_count(ctr_t *ctr) break; } - pit_log("latched counter = %04X\n", ctr->rl & 0xffff); + pclog("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); } uint16_t @@ -415,7 +418,7 @@ pit_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, in } void -pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) +pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) return; @@ -448,14 +451,14 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) /* Here we handle the rising edges. */ if (mode & 1) { if (mode != 1) - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); ctr->state = 1; } else if (mode == 2) ctr->state = 3; } else if (old && !gate) { /* Here we handle the lowering edges. */ if (mode & 2) - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } break; @@ -465,8 +468,9 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) } static __inline void -pit_ctr_set_clock_common(ctr_t *ctr, int clock) +pit_ctr_set_clock_common(ctr_t *ctr, int clock, void *priv) { + pit_t *pit = (pit_t *)priv; int old = ctr->clock; ctr->clock = clock; @@ -484,18 +488,18 @@ pit_ctr_set_clock_common(ctr_t *ctr, int clock) ctr->s1_det++; /* Falling edge. */ if (ctr->s1_det >= 2) { ctr->s1_det = 0; - ctr_tick(ctr); + ctr_tick(ctr, pit); } } } else if (old && !ctr->clock) - ctr_tick(ctr); + ctr_tick(ctr, pit); } } void -pit_ctr_set_clock(ctr_t *ctr, int clock) +pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv) { - pit_ctr_set_clock_common(ctr, clock); + pit_ctr_set_clock_common(ctr, clock, priv); } void @@ -516,7 +520,10 @@ pit_timer_over(void *priv) dev->clock ^= 1; for (uint8_t i = 0; i < 3; i++) - pit_ctr_set_clock_common(&dev->counters[i], dev->clock); + pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); + + if (dev->dev_timer != NULL) + dev->dev_timer(dev); timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); } @@ -528,7 +535,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) int t = (addr & 3); ctr_t *ctr; - pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); switch (addr & 3) { case 3: /* control */ @@ -544,7 +552,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_latch_count(&dev->counters[1]); if (val & 8) ctr_latch_count(&dev->counters[2]); - pit_log("PIT %i: Initiated readback command\n", t); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Initiated readback command\n", t); } if (!(val & 0x10)) { if (val & 2) @@ -561,7 +570,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); - pit_log("PIT %i: Initiated latched read, %i bytes latched\n", + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); } else { ctr->ctrl = val; @@ -571,14 +581,16 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->m &= 3; ctr->null_count = 1; ctr->bcd = (ctr->ctrl & 0x01); - ctr_set_out(ctr, !!ctr->m); + ctr_set_out(ctr, !!ctr->m, dev); ctr->state = 0; if (ctr->latched) { - pit_log("PIT %i: Reload while counter is latched\n", t); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Reload while counter is latched\n", t); ctr->rl--; } - pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); } } break; @@ -595,30 +607,31 @@ pit_write(uint16_t addr, uint8_t val, void *priv) case 1: ctr->l = val; if (ctr->m == 0) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 2: ctr->l = (val << 8); if (ctr->m == 0) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 3: case 0x83: if (ctr->wm & 0x80) { ctr->l = (ctr->l & 0x00ff) | (val << 8); - pit_log("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; - pit_log("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) { ctr->state = 0; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); } } - if (ctr->wm & 0x80) ctr->wm &= ~0x80; else @@ -749,13 +762,14 @@ pit_read(uint16_t addr, void *priv) break; } - pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); return ret; } void -pit_irq0_timer_ps2(int new_out, int old_out) +pit_irq0_timer_ps2(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) { picint(1); @@ -770,21 +784,21 @@ pit_irq0_timer_ps2(int new_out, int old_out) } void -pit_refresh_timer_xt(int new_out, int old_out) +pit_refresh_timer_xt(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) dma_channel_read(0); } void -pit_refresh_timer_at(int new_out, int old_out) +pit_refresh_timer_at(int new_out, int old_out, UNUSED(void *priv)) { if (refresh_at_enable && new_out && !old_out) ppi.pb ^= 0x10; } void -pit_speaker_timer(int new_out, UNUSED(int old_out)) +pit_speaker_timer(int new_out, UNUSED(int old_out), UNUSED(void *priv)) { int l; @@ -804,7 +818,7 @@ pit_speaker_timer(int new_out, UNUSED(int old_out)) } void -pit_nmi_timer_ps2(int new_out, UNUSED(int old_out)) +pit_nmi_timer_ps2(int new_out, UNUSED(int old_out), UNUSED(void *priv)) { nmi = new_out; @@ -882,6 +896,9 @@ pit_init(const device_t *info) pit_read, NULL, NULL, pit_write, NULL, NULL, dev); } + dev->dev_priv = NULL; + dev->dev_timer = NULL; + return dev; } @@ -899,6 +916,20 @@ const device_t i8253_device = { .config = NULL }; +const device_t i8253_ext_io_device = { + .name = "Intel 8253 Programmable Interval Timer (External I/O)", + .internal_name = "i8253_ext_io", + .flags = DEVICE_ISA, + .local = PIT_8253 | PIT_EXT_IO, + .init = pit_init, + .close = pit_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t i8254_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254", @@ -956,7 +987,7 @@ const device_t i8254_ps2_device = { }; pit_t * -pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)) +pit_common_init(int type, void (*out0)(int new_out, int old_out, void *priv), void (*out1)(int new_out, int old_out, void *priv)) { void *pit; diff --git a/src/pit_fast.c b/src/pit_fast.c index f9d055375..9c5d622ec 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -66,13 +66,15 @@ pit_log(const char *fmt, ...) #endif static void -pitf_ctr_set_out(ctrf_t *ctr, int out) +pitf_ctr_set_out(ctrf_t *ctr, int out, void *priv) { + pitf_t *pit = (pitf_t *)priv; + if (ctr == NULL) return; if (ctr->out_func != NULL) - ctr->out_func(out, ctr->out); + ctr->out_func(out, ctr->out, pit); ctr->out = out; } @@ -98,7 +100,7 @@ pitf_ctr_get_count(void *data, int counter_id) } static void -pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) +pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) return; @@ -154,8 +156,9 @@ pitf_dump_and_disable_timer(ctrf_t *ctr) } static void -pitf_ctr_load(ctrf_t *ctr) +pitf_ctr_load(ctrf_t *ctr, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; ctr->newcount = 0; @@ -166,7 +169,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = ctr->gate; break; @@ -178,7 +181,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l - 1; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -188,7 +191,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -200,7 +203,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -223,8 +226,9 @@ pitf_ctr_load(ctrf_t *ctr) } static void -pitf_set_gate_no_timer(ctrf_t *ctr, int gate) +pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; if (ctr->disabled) { @@ -245,7 +249,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = 1; } @@ -255,7 +259,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l - 1; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = gate; @@ -265,7 +269,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = gate; @@ -291,12 +295,13 @@ pitf_ctr_set_gate(void *data, int counter_id, int gate) return; } - pitf_set_gate_no_timer(ctr, gate); + pitf_set_gate_no_timer(ctr, gate, pit); } static void -pitf_over(ctrf_t *ctr) +pitf_over(ctrf_t *ctr, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; if (ctr->disabled) { ctr->count += 0xffff; @@ -309,7 +314,7 @@ pitf_over(ctrf_t *ctr) case 0: /*Interrupt on terminal count*/ case 1: /*Hardware retriggerable one-shot*/ if (!ctr->thit) - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) @@ -319,17 +324,17 @@ pitf_over(ctrf_t *ctr) ctr->count += l; if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); break; case 3: /*Square wave mode*/ if (ctr->out) { - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->count += (l >> 1); if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * PITCONST)); } else { - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); @@ -341,8 +346,8 @@ pitf_over(ctrf_t *ctr) break; case 4: /*Software triggered strove*/ if (!ctr->thit) { - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); } if (ctr->newcount) { ctr->newcount = 0; @@ -358,8 +363,8 @@ pitf_over(ctrf_t *ctr) break; case 5: /*Hardware triggered strove*/ if (!ctr->thit) { - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); } ctr->thit = 1; ctr->count += 0xffff; @@ -453,9 +458,9 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) ctr->rereadlatch = 1; ctr->initial = 1; if (!ctr->m) - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, dev); else - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, dev); ctr->disabled = 1; pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); @@ -472,16 +477,16 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) switch (ctr->wm) { case 1: ctr->l = val; - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); break; case 2: ctr->l = (val << 8); - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); break; case 0: ctr->l &= 0xFF; ctr->l |= (val << 8); - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); ctr->wm = 3; break; case 3: @@ -610,7 +615,8 @@ static void pitf_timer_over(void *priv) { ctrf_t *ctr = (ctrf_t *) priv; - pitf_over(ctr); + pit_t *pit = (pit_t *)ctr->priv; + pitf_over(ctr, pit); } static void @@ -627,7 +633,7 @@ pitf_ctr_clock(void *data, int counter_id) ctr->count -= (ctr->m == 3) ? 2 : 1; if (!ctr->count) - pitf_over(ctr); + pitf_over(ctr, pit); } static void @@ -679,6 +685,7 @@ pitf_init(const device_t *info) if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { for (int i = 0; i < 3; i++) { ctrf_t *ctr = &dev->counters[i]; + ctr->priv = dev; timer_add(&ctr->timer, pitf_timer_over, (void *) ctr, 0); } } diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 72f05ff6d..c1bbc811f 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -17,7 +17,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c - snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c + snd_emu8k.c snd_mpu401.c snd_pas16.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c snd_optimc.c) if(OPENAL) @@ -116,11 +116,6 @@ endif() add_subdirectory(ymfm) target_link_libraries(86Box ymfm) -if(PAS16) - target_compile_definitions(snd PRIVATE USE_PAS16) - target_sources(snd PRIVATE snd_pas16.c) -endif() - if(GUSMAX) target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 3ce9b5c4c..32879cd1e 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -12,6 +12,7 @@ #include <86box/dma.h> #include <86box/filters.h> #include <86box/io.h> +#include <86box/midi.h> #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> @@ -132,34 +133,25 @@ typedef struct pas16_t { uint8_t sys_conf_2; uint8_t sys_conf_3; uint8_t sys_conf_4; - - struct { - uint32_t l[3]; - int64_t c[3]; - pc_timer_t timer[3]; - uint8_t m[3]; - uint8_t ctrl; - uint8_t ctrls[2]; - int wp; - int rm[3]; - int wm[3]; - uint16_t rl[3]; - int thit[3]; - int delay[3]; - int rereadlatch[3]; - int64_t enable[3]; - } pit; + uint8_t waitstates; + uint8_t midi_ctrl; + uint8_t midi_stat; + uint8_t midi_data; + uint8_t midi_fifo[16]; fm_drv_t opl; sb_dsp_t dsp; + mpu_t *mpu; int16_t pcm_buffer[2][SOUNDBUFLEN]; int pos; + + int midi_uart_out; + + pit_t *pit; } pas16_t; -static uint8_t pas16_pit_in(uint16_t port, void *priv); -static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; @@ -169,7 +161,8 @@ static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; enum { PAS16_INT_SAMP = 0x04, - PAS16_INT_PCM = 0x08 + PAS16_INT_PCM = 0x08, + PAS16_INT_MIDI = 0x10, }; enum { @@ -204,6 +197,96 @@ pas16_log(const char *fmt, ...) # define pas16_log(fmt, ...) #endif +static void +pas16_update_midi_irqs(pas16_t *pas16) +{ + int irq = 0; + + pas16->irq_stat &= ~PAS16_INT_MIDI; + + if ((pas16->uart_status & 0x18) || (dev->uart_status & 0x04)) { + pas16->irq_stat |= PAS16_INT_MIDI; + irq = 1; + } + + if (irq) + picint(1 << pas16->irq); + else + picintc(1 << pas16->irq); +} + +static void +pas16_update_tx_irq(pas16_t *pas16) +{ + pas16->uart_status &= ~0x18; + + if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x18)) + pas16->uart_status |= 0x18; + + pas16_update_midi_irqs(pas16); +} + +static void +pas16_update_rx_irq(pas16_t *pas16) +{ + pas16->uart_status &= ~0x04; + + if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x04)) + pas16->uart_status |= 0x04; + + pas16_update_midi_irqs(pas16); +} + +static void +pas16_scan_fifo(pas16_t *pas16) +{ + if (pas16->read_fifo_pos != pas16->write_fifo_pos) { + pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; + pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 0x0f; + + es1371_set_rx_irq(pas16, 1); + } else + es1371_set_rx_irq(pas16, 0); +} + +static void +es1371_write_fifo(es1371_t *dev, uint8_t val) +{ + if (dev->write_fifo_pos < 16) { + dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; + dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 0x0f; + } +} + +static void +es1371_reset_fifo(es1371_t *dev) +{ + for (uint8_t i = 0; i < 16; i++) + dev->uart_fifo[i] = 0x00000000; + + dev->read_fifo_pos = dev->write_fifo_pos = 0; + + es1371_set_rx_irq(dev, 0); +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16->uart_status = 0xff; + pas16->uart_ctrl = 0x00; + + for (uint8_t i = 0; i < 16; i++) + pas16->uart_fifo[i] = 0x00; + + pas16_set_tx_irq(pas16, 0); + + pas16_reset_fifo(pas16); + + pas16_update_midi_irqs(pas16); +} + static uint8_t pas16_in(uint16_t port, void *priv) { @@ -230,18 +313,24 @@ pas16_in(uint16_t port, void *priv) break; case 0xb8b: - temp = (pas16->irq_ena & ~0xe0) | 0x20; + temp = pas16->irq_ena & ~0xe0; + temp |= 0x01; break; case 0xf8a: temp = pas16->pcm_ctrl; break; - case 0x1388: - case 0x1389: - case 0x138a: - case 0x138b: - temp = pas16_pit_in(port, pas16); + case 0x1789: + temp = 0; + break; + case 0x178a: + temp = pas16->uart_data; + pas16_set_rx_irq(pas16, 0); + break; + + case 0x1b88: + temp = pas16->uart_status; break; case 0x2789: /*Board revision*/ @@ -249,7 +338,7 @@ pas16_in(uint16_t port, void *priv) break; case 0x7f89: - temp = pas16->enhancedscsi & ~1; + temp = pas16->enhancedscsi & ~0x01; break; case 0x8388: @@ -265,6 +354,10 @@ pas16_in(uint16_t port, void *priv) temp = pas16->sys_conf_4; break; + case 0xbf88: + temp = pas16->waitstates; + break; + case 0xef8b: temp = 0x0c; break; @@ -275,10 +368,10 @@ pas16_in(uint16_t port, void *priv) case 0xf389: temp = pas16->io_conf_2; break; - case 0xf38b: + case 0xf38a: temp = pas16->io_conf_3; break; - case 0xf38c: + case 0xf38b: temp = pas16->io_conf_4; break; @@ -294,7 +387,7 @@ pas16_in(uint16_t port, void *priv) break; case 0xff88: /*Board model*/ - temp = 4; /*PAS16*/ + temp = 0x04; /*PAS16*/ break; case 0xff8b: /*Master mode read*/ temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ @@ -303,7 +396,7 @@ pas16_in(uint16_t port, void *priv) default: break; } - pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); + pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); return temp; } @@ -311,7 +404,8 @@ static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + pit_t *pit = (pit_t *) pas16->pit; + pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); switch ((port - pas16->base) + 0x388) { case 0x388: case 0x389: @@ -348,14 +442,35 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0xf8a: if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ pas16->stereo_lr = 0; + pas16->pcm_ctrl = val; break; - case 0x1388: - case 0x1389: - case 0x138a: - case 0x138b: - pas16_pit_out(port, val, pas16); + case 0x1789: + case 0x178b: + pas16->uart_ctrl = val; + + if ((val & 0x60) == 0x60) { + /* Reset TX */ + pas16_set_tx_irq(pas16, 1); + + /* Software reset */ + pas16_reset_fifo(pas16); + } else { + pas16_set_tx_irq(pas16, 1); + + pas16_update_tx_irq(pas16); + pas16_update_rx_irq(pas16); + } + break; + + case 0x178a: + midi_raw_out_byte(val); + pas16_set_tx_irq(pas16, 1); + break; + + case 0x1b88: + pas16->uart_status = val; break; case 0x7f89: @@ -363,6 +478,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8388: + if ((val & 0x80) && !(pas16->sys_conf_1 & 0x80)) { + pclog("Reset.\n"); + pas16_reset(pas16); + } pas16->sys_conf_1 = val; break; case 0x8389: @@ -375,18 +494,22 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->sys_conf_4 = val; break; + case 0xbf88: + pas16->waitstates = val; + break; + case 0xf388: pas16->io_conf_1 = val; break; case 0xf389: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; - pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); + pclog("pas16_out : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: pas16->io_conf_3 = val; pas16->irq = pas16_irqs[val & 0xf]; - pas16_log("pas16_out : set PAS IRQ %i\n", pas16->irq); + pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); break; case 0xf38b: pas16->io_conf_4 = val; @@ -398,11 +521,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); else sb_dsp_setaddr(&pas16->dsp, 0); + if (pas16->compat & 0x01) + mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); + else + mpu401_change_addr(pas16->mpu, 0); break; case 0xf789: pas16->compat_base = val; if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + if (pas16->compat & 0x01) + mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; case 0xfb8a: @@ -413,7 +542,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; default: - pas16_log("pas16_out : unknown %04X\n", port); + pclog("pas16_out : unknown %04X\n", port); } #if 0 if (cpu_state.pc == 0x80048CF3) { @@ -424,167 +553,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) #endif } + static void -pas16_pit_out(uint16_t port, uint8_t val, void *priv) +pas16_scan_fifo(pas16_t *pas16) { - pas16_t *pas16 = (pas16_t *) priv; - int t; - switch (port & 3) { - case 3: /*CTRL*/ - if ((val & 0xC0) == 0xC0) { - if (!(val & 0x20)) { - if (val & 2) - pas16->pit.rl[0] = timer_get_remaining_u64(&pas16->pit.timer[0]) / PITCONST; - if (val & 4) - pas16->pit.rl[1] = pas16->pit.c[1]; - if (val & 8) - pas16->pit.rl[2] = pas16->pit.c[2]; - } - return; - } - t = val >> 6; - pas16->pit.ctrls[t] = pas16->pit.ctrl = val; - if (t == 3) { - printf("Bad PIT reg select\n"); - return; - } - if (!(pas16->pit.ctrl & 0x30)) { - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] < 0) - pas16->pit.rl[t] = 0; - } - pas16->pit.ctrl |= 0x30; - pas16->pit.rereadlatch[t] = 0; - pas16->pit.rm[t] = 3; - } else { - pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; - pas16->pit.m[t] = (val >> 1) & 7; - if (pas16->pit.m[t] > 5) - pas16->pit.m[t] &= 3; - if (!pas16->pit.rm[t]) { - pas16->pit.rm[t] = 3; - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else - pas16->pit.rl[t] = pas16->pit.c[t]; - } - pas16->pit.rereadlatch[t] = 1; - } - pas16->pit.wp = 0; - pas16->pit.thit[t] = 0; - break; - case 0: - case 1: - case 2: /*Timers*/ - t = port & 3; - switch (pas16->pit.wm[t]) { - case 1: - pas16->pit.l[t] = val; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 2: - pas16->pit.l[t] = val << 8; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 0: - pas16->pit.l[t] &= 0xFF; - pas16->pit.l[t] |= (val << 8); - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.thit[t] = 0; - pas16->pit.wm[t] = 3; - pas16->pit.enable[t] = 1; - break; - case 3: - pas16->pit.l[t] &= 0xFF00; - pas16->pit.l[t] |= val; - pas16->pit.wm[t] = 0; - break; + if (pas16->read_fifo_pos != pas16->write_fifo_pos) { + pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; + pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 7; - default: - break; - } - if (!pas16->pit.l[t]) { - pas16->pit.l[t] |= 0x10000; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - } - break; - - default: - break; - } -} - -static uint8_t -pas16_pit_in(uint16_t port, void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - uint8_t temp = 0xff; - int t = port & 3; - switch (port & 3) { - case 0: - case 1: - case 2: /*Timers*/ - if (pas16->pit.rereadlatch[t]) { - pas16->pit.rereadlatch[t] = 0; - if (!t) { - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - if ((timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST) > 65536) - pas16->pit.rl[t] = 0xFFFF; - } else { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] > 65536) - pas16->pit.rl[t] = 0xFFFF; - } - } - switch (pas16->pit.rm[t]) { - case 0: - temp = pas16->pit.rl[t] >> 8; - pas16->pit.rm[t] = 3; - pas16->pit.rereadlatch[t] = 1; - break; - case 1: - temp = (pas16->pit.rl[t]) & 0xFF; - pas16->pit.rereadlatch[t] = 1; - break; - case 2: - temp = (pas16->pit.rl[t]) >> 8; - pas16->pit.rereadlatch[t] = 1; - break; - case 3: - temp = (pas16->pit.rl[t]) & 0xFF; - if (pas16->pit.m[t] & 0x80) - pas16->pit.m[t] &= 7; - else - pas16->pit.rm[t] = 0; - break; - - default: - break; - } - break; - case 3: /*Control*/ - temp = pas16->pit.ctrl; - break; - - default: - break; - } - return temp; + pas16_set_rx_irq(pas16, 1); + } else + pas16_set_rx_irq(pas16, 0); } static uint8_t @@ -593,30 +572,34 @@ pas16_readdma(pas16_t *pas16) return dma_channel_read(pas16->dma); } + static void pas16_pcm_poll(void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pit_t *pit = (pit_t *)priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; + uint16_t temp = 0x0000; + pas16_update(pas16); - if (pas16->pit.m[0] & 2) { - if (pas16->pit.l[0]) - timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); - else - timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); - } else { - pas16->pit.enable[0] = 0; + if (pit->counters[0].m & 2) { + if (pit->counters[0].l) + timer_advance_u64(&pit->callback_timer, pit->counters[0].l * (PITCONST << 1ULL)); + else { + timer_advance_u64(&pit->callback_timer, 0x10000 * (PITCONST << 1ULL)); + } } pas16->irq_stat |= PAS16_INT_SAMP; if (pas16->irq_ena & PAS16_INT_SAMP) picint(1 << pas16->irq); + else + picintc(1 << pas16->irq); /*Update sample rate counter*/ - if (pas16->pit.enable[1]) { + pas16_log("Enable (t1) = %d.\n", pit->counters[1].enable); + if (pit->counters[1].enable) { if (pas16->pcm_ctrl & PAS16_PCM_ENA) { - uint16_t temp; - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { temp = pas16_readdma(pas16) << 8; temp |= pas16_readdma(pas16); @@ -637,29 +620,42 @@ pas16_pcm_poll(void *priv) } } if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pas16->pit.c[1] -= 2; + pit->counters[1].rl -= 2; else - pas16->pit.c[1]--; - if (pas16->pit.c[1] == 0) { - if (pas16->pit.m[1] & 2) { - if (pas16->pit.l[1]) - pas16->pit.c[1] += pas16->pit.l[1]; + pit->counters[1].rl--; + + pas16_log("RL=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); + if (pit->counters[1].rl == 0xffff) { + if (pit->counters[1].m & 2) { + if (pit->counters[1].l & 0xffff) + pit->counters[1].rl = pit->counters[1].l & 0xffff; else - pas16->pit.c[1] += 0x10000; + pit->counters[1].rl = 0; } else { - pas16->pit.c[1] = -1; - pas16->pit.enable[1] = 0; + pit->counters[1].enable = 0; + pit->counters[1].rl = 0; } + pas16_log("New counter=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); pas16->irq_stat |= PAS16_INT_PCM; if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); + pclog("pas16_pcm_poll : cause IRQ %i %02X, enable timer 1 = %x\n", pas16->irq, 1 << pas16->irq, pit->counters[1].enable); picint(1 << pas16->irq); - } + } else + picintc(1 << pas16->irq); } } } +static void +pas16_pit_timer0(int new_out, int old_out, void *priv) +{ + pit_t *pit = (pit_t *)priv; + pclog("NewOut=%d, OldOut=%d.\n", new_out, old_out); + pit->counters[1].enable = new_out; + pit_ctr_set_clock(&pit->counters[0], new_out, pit); +} + static void pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { @@ -669,8 +665,9 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + pit_handler(0, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); @@ -685,14 +682,15 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); pas16->base = val << 2; - pas16_log("pas16_write_base : PAS16 base now at %04X\n", pas16->base); + pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + pit_handler(1, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); @@ -759,10 +757,22 @@ pas16_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); + pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(pas16->mpu, 0, sizeof(mpu_t)); + mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); + + pas16->pit = device_add(&i8254_ext_io_device); + + pas16->midi_uart_out = 1; io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - - timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); + pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); + pit_ctr_set_using_timer(pas16->pit, 0, 1); + pit_ctr_set_using_timer(pas16->pit, 1, 0); + pit_ctr_set_using_timer(pas16->pit, 2, 0); + pas16->pit->dev_priv = pas16; + pas16->pit->dev_timer = pas16_pcm_poll; sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); @@ -778,10 +788,21 @@ pas16_close(void *priv) free(pas16); } +static const device_config_t pas16_config[] = { + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_AT, .local = 0, .init = pas16_init, .close = pas16_close, @@ -789,5 +810,5 @@ const device_t pas16_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = pas16_config }; diff --git a/src/sound/sound.c b/src/sound/sound.c index 81f70d921..50eb984d6 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -149,9 +149,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, -#if defined(DEV_BRANCH) && defined(USE_PAS16) { &pas16_device }, -#endif { &pssj_isa_device }, { &tndy_device }, { &wss_device }, From 23ba920bbf105718b0b30ad5d7971e4f83b39339 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:53:11 +0500 Subject: [PATCH 269/690] Clean up the plat and ui API Remove functions no longer defined or used on any plat/UI Remove the old non-multi-monitor-aware plat_resize() and rename plat_resize_monitor() to plat_resize() --- src/include/86box/plat.h | 19 +------------------ src/include/86box/ui.h | 6 ------ src/qt/qt_platform.cpp | 17 +++++------------ src/qt/qt_ui.cpp | 12 +++--------- src/unix/unix.c | 16 ++-------------- src/unix/unix_sdl.c | 6 +++--- 6 files changed, 14 insertions(+), 62 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 84f0318c2..32f50c638 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -113,7 +113,6 @@ extern int hide_status_bar; extern int hide_tool_bar; /* System-related functions. */ -extern char *fix_exe_path(char *str); extern FILE *plat_fopen(const char *path, const char *mode); extern FILE *plat_fopen64(const char *path, const char *mode); extern void plat_remove(char *path); @@ -129,29 +128,19 @@ extern void *plat_mmap(size_t size, uint8_t executable); extern void plat_munmap(void *ptr, size_t size); extern uint64_t plat_timer_read(void); extern uint32_t plat_get_ticks(void); -extern uint32_t plat_get_micro_ticks(void); extern void plat_delay_ms(uint32_t count); extern void plat_pause(int p); extern void plat_mouse_capture(int on); extern int plat_vidapi(char *name); extern char *plat_vidapi_name(int api); -extern int plat_setvid(int api); -extern void plat_vidsize(int x, int y); -extern void plat_setfullscreen(int on); -extern void plat_resize_monitor(int x, int y, int monitor_index); +extern void plat_resize(int x, int y, int monitor_index); extern void plat_resize_request(int x, int y, int monitor_index); -extern void plat_resize(int x, int y); -extern void plat_vidapi_enable(int enabled); -extern void plat_vidapi_reload(void); -extern void plat_vid_reload_options(void); extern uint32_t plat_language_code(char *langcode); extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len); extern void plat_get_cpu_string(char *outbuf, uint8_t len); -extern double plat_get_dpi(void); extern void plat_set_thread_name(void *thread, const char *name); /* Resource management. */ -extern void set_language(uint32_t id); extern wchar_t *plat_get_string(int id); /* Emulator start/stop support functions. */ @@ -183,17 +172,11 @@ extern void ioctl_close(uint8_t id); /* Other stuff. */ extern void startblit(void); extern void endblit(void); -extern void take_screenshot(void); /* Conversion between UTF-8 and UTF-16. */ extern size_t mbstoc16s(uint16_t dst[], const char src[], int len); extern size_t c16stombs(char dst[], const uint16_t src[], int len); -#ifdef MTR_ENABLED -extern void init_trace(void); -extern void shutdown_trace(void); -#endif - #ifdef __cplusplus } #endif diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index 9698f896c..c12eb73a0 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -42,9 +42,6 @@ extern "C" { extern int ui_msgbox(int flags, void *message); extern int ui_msgbox_header(int flags, void *header, void *message); -extern int ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3); - -extern void ui_check_menu_item(int id, int checked); /* Status Bar functions. */ #define SB_ICON_WIDTH 24 @@ -60,16 +57,13 @@ extern void ui_check_menu_item(int id, int checked); #define SB_TEXT 0x90 extern wchar_t *ui_window_title(wchar_t *s); -extern void ui_status_update(void); extern void ui_hard_reset_completed(void); extern void ui_init_monitor(int monitor_index); extern void ui_deinit_monitor(int monitor_index); -extern int ui_sb_find_part(int tag); extern void ui_sb_set_ready(int ready); extern void ui_sb_update_panes(void); extern void ui_sb_update_text(void); extern void ui_sb_update_tip(int meaning); -extern void ui_sb_timer_callback(int pane); extern void ui_sb_update_icon(int tag, int active); extern void ui_sb_update_icon_state(int tag, int state); extern void ui_sb_set_text_w(wchar_t *wstr); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 824f71023..da97680fa 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -149,6 +149,11 @@ strnicmp(const char *s1, const char *s2, size_t n) #endif } +void +do_start(void) +{ +} + void do_stop(void) { @@ -425,12 +430,6 @@ plat_power_off(void) QTimer::singleShot(0, (const QWidget *) main_window, &QMainWindow::close); } -void -set_language(uint32_t id) -{ - lang_id = id; -} - extern "C++" { QMap> ProgSettings::lcid_langcode = { { 0x0403, { "ca-ES", "Catalan (Spain)" } }, @@ -741,12 +740,6 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { } -double -plat_get_dpi(void) -{ - return util::screenOfWidget(main_window)->devicePixelRatio(); -} - void plat_set_thread_name(void *thread, const char *name) { diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 47e6b48a2..b544bbde1 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -95,14 +95,14 @@ plat_resize_request(int w, int h, int monitor_index) if (video_fullscreen || is_quit) return; if (vid_resize & 2) { - plat_resize_monitor(fixed_size_x, fixed_size_y, monitor_index); + plat_resize(fixed_size_x, fixed_size_y, monitor_index); } else { - plat_resize_monitor(w, h, monitor_index); + plat_resize(w, h, monitor_index); } } void -plat_resize_monitor(int w, int h, int monitor_index) +plat_resize(int w, int h, int monitor_index) { if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index); @@ -110,12 +110,6 @@ plat_resize_monitor(int w, int h, int monitor_index) main_window->resizeContents(w, h); } -void -plat_setfullscreen(int on) -{ - main_window->setFullscreen(on > 0 ? true : false); -} - void plat_mouse_capture(int on) { diff --git a/src/unix/unix.c b/src/unix/unix.c index 2a9324307..848ed0f22 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -448,12 +448,6 @@ plat_get_ticks(void) return (uint32_t) (plat_get_ticks_common() / 1000); } -uint32_t -plat_get_micro_ticks(void) -{ - return (uint32_t) plat_get_ticks_common(); -} - void plat_remove(char *path) { @@ -578,9 +572,9 @@ main_thread(void *param) /* If needed, handle a screen resize. */ if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); + plat_resize(fixed_size_x, fixed_size_y, 0); else - plat_resize(scrnsz_x, scrnsz_y); + plat_resize(scrnsz_x, scrnsz_y, 0); atomic_store(&doresize_monitors[0], 1); } } @@ -1358,12 +1352,6 @@ plat_vidapi_name(int i) return "default"; } -void -set_language(uint32_t id) -{ - lang_id = id; -} - /* Sets up the program language before initialization. */ uint32_t plat_language_code(char *langcode) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 3ba8c1ae0..c7cc898be 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -424,9 +424,9 @@ sdl_init_common(int flags) sdl_set_fs(video_fullscreen); if (!(video_fullscreen & 1)) { if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); + plat_resize(fixed_size_x, fixed_size_y, 0); else - plat_resize(scrnsz_x, scrnsz_y); + plat_resize(scrnsz_x, scrnsz_y, 0); } if ((vid_resize < 2) && window_remember) { SDL_SetWindowSize(sdl_win, window_w, window_h); @@ -479,7 +479,7 @@ plat_mouse_capture(int on) } void -plat_resize(int w, int h) +plat_resize(int w, int h, UNUSED(int monitor_index)) { SDL_LockMutex(sdl_mutex); resize_w = w; From c5c4dcb2685bf32dcc194938fedaa61c4cb36b1a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:54:03 +0500 Subject: [PATCH 270/690] Remove the unfinished and unused Qt SDL renderer --- src/qt/qt_sdl.c | 708 ------------------------------------------------ src/qt/qt_sdl.h | 72 ----- 2 files changed, 780 deletions(-) delete mode 100644 src/qt/qt_sdl.c delete mode 100644 src/qt/qt_sdl.h diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c deleted file mode 100644 index 15af4d7b6..000000000 --- a/src/qt/qt_sdl.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * 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. - * - * Rendering module for libSDL2 - * - * NOTE: Given all the problems reported with FULLSCREEN use of SDL, - * we will not use that, but, instead, use a new window which - * covers the entire desktop. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2020 Fred N. van Kempen. - * Copyright 2018-2020 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include - -#include -#include -#include -#include -/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ -#undef HAVE_STDARG_H -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/mouse.h> -#include <86box/keyboard.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/video.h> -#include <86box/ui.h> -#include <86box/version.h> - -#include "qt_sdl.h" - -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 - -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static int sdl_w; -static int sdl_h; -static int sdl_fs; -static int sdl_flags = -1; -static int cur_w; -static int cur_h; -static int cur_ww = 0; -static int cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex *sdl_mutex = NULL; - -static const uint16_t sdl_to_xt[0x200] = { - [SDL_SCANCODE_ESCAPE] = 0x01, - [SDL_SCANCODE_1] = 0x02, - [SDL_SCANCODE_2] = 0x03, - [SDL_SCANCODE_3] = 0x04, - [SDL_SCANCODE_4] = 0x05, - [SDL_SCANCODE_5] = 0x06, - [SDL_SCANCODE_6] = 0x07, - [SDL_SCANCODE_7] = 0x08, - [SDL_SCANCODE_8] = 0x09, - [SDL_SCANCODE_9] = 0x0A, - [SDL_SCANCODE_0] = 0x0B, - [SDL_SCANCODE_MINUS] = 0x0C, - [SDL_SCANCODE_EQUALS] = 0x0D, - [SDL_SCANCODE_BACKSPACE] = 0x0E, - [SDL_SCANCODE_TAB] = 0x0F, - [SDL_SCANCODE_Q] = 0x10, - [SDL_SCANCODE_W] = 0x11, - [SDL_SCANCODE_E] = 0x12, - [SDL_SCANCODE_R] = 0x13, - [SDL_SCANCODE_T] = 0x14, - [SDL_SCANCODE_Y] = 0x15, - [SDL_SCANCODE_U] = 0x16, - [SDL_SCANCODE_I] = 0x17, - [SDL_SCANCODE_O] = 0x18, - [SDL_SCANCODE_P] = 0x19, - [SDL_SCANCODE_LEFTBRACKET] = 0x1A, - [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, - [SDL_SCANCODE_RETURN] = 0x1C, - [SDL_SCANCODE_LCTRL] = 0x1D, - [SDL_SCANCODE_A] = 0x1E, - [SDL_SCANCODE_S] = 0x1F, - [SDL_SCANCODE_D] = 0x20, - [SDL_SCANCODE_F] = 0x21, - [SDL_SCANCODE_G] = 0x22, - [SDL_SCANCODE_H] = 0x23, - [SDL_SCANCODE_J] = 0x24, - [SDL_SCANCODE_K] = 0x25, - [SDL_SCANCODE_L] = 0x26, - [SDL_SCANCODE_SEMICOLON] = 0x27, - [SDL_SCANCODE_APOSTROPHE] = 0x28, - [SDL_SCANCODE_GRAVE] = 0x29, - [SDL_SCANCODE_LSHIFT] = 0x2A, - [SDL_SCANCODE_BACKSLASH] = 0x2B, - [SDL_SCANCODE_Z] = 0x2C, - [SDL_SCANCODE_X] = 0x2D, - [SDL_SCANCODE_C] = 0x2E, - [SDL_SCANCODE_V] = 0x2F, - [SDL_SCANCODE_B] = 0x30, - [SDL_SCANCODE_N] = 0x31, - [SDL_SCANCODE_M] = 0x32, - [SDL_SCANCODE_COMMA] = 0x33, - [SDL_SCANCODE_PERIOD] = 0x34, - [SDL_SCANCODE_SLASH] = 0x35, - [SDL_SCANCODE_RSHIFT] = 0x36, - [SDL_SCANCODE_KP_MULTIPLY] = 0x37, - [SDL_SCANCODE_LALT] = 0x38, - [SDL_SCANCODE_SPACE] = 0x39, - [SDL_SCANCODE_CAPSLOCK] = 0x3A, - [SDL_SCANCODE_F1] = 0x3B, - [SDL_SCANCODE_F2] = 0x3C, - [SDL_SCANCODE_F3] = 0x3D, - [SDL_SCANCODE_F4] = 0x3E, - [SDL_SCANCODE_F5] = 0x3F, - [SDL_SCANCODE_F6] = 0x40, - [SDL_SCANCODE_F7] = 0x41, - [SDL_SCANCODE_F8] = 0x42, - [SDL_SCANCODE_F9] = 0x43, - [SDL_SCANCODE_F10] = 0x44, - [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, - [SDL_SCANCODE_SCROLLLOCK] = 0x46, - [SDL_SCANCODE_HOME] = 0x147, - [SDL_SCANCODE_UP] = 0x148, - [SDL_SCANCODE_PAGEUP] = 0x149, - [SDL_SCANCODE_KP_MINUS] = 0x4A, - [SDL_SCANCODE_LEFT] = 0x14B, - [SDL_SCANCODE_KP_5] = 0x4C, - [SDL_SCANCODE_RIGHT] = 0x14D, - [SDL_SCANCODE_KP_PLUS] = 0x4E, - [SDL_SCANCODE_END] = 0x14F, - [SDL_SCANCODE_DOWN] = 0x150, - [SDL_SCANCODE_PAGEDOWN] = 0x151, - [SDL_SCANCODE_INSERT] = 0x152, - [SDL_SCANCODE_DELETE] = 0x153, - [SDL_SCANCODE_F11] = 0x57, - [SDL_SCANCODE_F12] = 0x58, - - [SDL_SCANCODE_KP_ENTER] = 0x11c, - [SDL_SCANCODE_RCTRL] = 0x11d, - [SDL_SCANCODE_KP_DIVIDE] = 0x135, - [SDL_SCANCODE_RALT] = 0x138, - [SDL_SCANCODE_KP_9] = 0x49, - [SDL_SCANCODE_KP_8] = 0x48, - [SDL_SCANCODE_KP_7] = 0x47, - [SDL_SCANCODE_KP_6] = 0x4D, - [SDL_SCANCODE_KP_4] = 0x4B, - [SDL_SCANCODE_KP_3] = 0x51, - [SDL_SCANCODE_KP_2] = 0x50, - [SDL_SCANCODE_KP_1] = 0x4F, - [SDL_SCANCODE_KP_0] = 0x52, - [SDL_SCANCODE_KP_PERIOD] = 0x53, - - [SDL_SCANCODE_LGUI] = 0x15B, - [SDL_SCANCODE_RGUI] = 0x15C, - [SDL_SCANCODE_APPLICATION] = 0x15D, - [SDL_SCANCODE_PRINTSCREEN] = 0x137, - [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, -}; - -// #define ENABLE_SDL_LOG 3 -#ifdef ENABLE_SDL_LOG -int sdl_do_log = ENABLE_SDL_LOG; - -static void -sdl_log(const char *fmt, ...) -{ - va_list ap; - - if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define sdl_log(fmt, ...) -#endif - -static void -sdl_integer_scale(double *d, double *g) -{ - double ratio; - - if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; - } else { - ratio = ceil(*d / *g); - *d = *g / ratio; - } -} - -static void -sdl_stretch(int *w, int *h, int *x, int *y) -{ - double hw; - double gw; - double hh; - double gh; - double dx; - double dy; - double dw; - double dh; - double gsr; - double hsr; - - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; - hsr = hw / hh; - - switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - default: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - } -} - -static void -sdl_blit(int x, int y, int w, int h) -{ - SDL_Rect r_src; - void *pixeldata; - int ret; - int pitch; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { - video_blit_complete(); - return; - } - - SDL_LockMutex(sdl_mutex); - SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - - video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048) * sizeof(uint32_t)); - - if (monitors[m_monitor_index].mon_screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, (2048)); - - SDL_UnlockTexture(sdl_tex); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = 0; - r_src.y = 0; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); - - SDL_RenderPresent(sdl_render); - - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_destroy_window(void) -{ - if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; - } -} - -static void -sdl_destroy_texture(void) -{ - if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; - } - - /* SDL_DestroyRenderer also automatically destroys all associated textures. */ - if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; - } -} - -void -sdl_close(void) -{ - if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); - - /* Unregister our renderer! */ - video_setblit(NULL); - - if (sdl_enabled) - sdl_enabled = 0; - - if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; - } - - sdl_destroy_texture(); - sdl_destroy_window(); - - /* Quit. */ - SDL_Quit(); - sdl_flags = -1; -} - -static void -sdl_select_best_hw_driver(void) -{ - SDL_RendererInfo renderInfo; - - for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (renderInfo.flags & SDL_RENDERER_ACCELERATED) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name); - return; - } - } -} - -static void -sdl_init_texture(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - } else { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - } - - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); - - if (sdl_render == NULL) { - sdl_log("SDL: unable to SDL_CreateRenderer (%s)\n", SDL_GetError()); - } - if (sdl_tex == NULL) { - sdl_log("SDL: unable to SDL_CreateTexture (%s)\n", SDL_GetError()); - } -} - -static void -sdl_reinit_texture(void) -{ - if (sdl_flags == -1) - return; - - sdl_destroy_texture(); - sdl_init_texture(); -} - -void -sdl_set_fs(int fs) -{ - SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - SDL_SetRelativeMouseMode((SDL_bool) mouse_capture); - - sdl_fs = fs; - - if (fs) { - sdl_flags |= RENDERER_FULL_SCREEN; - } else { - sdl_flags &= ~RENDERER_FULL_SCREEN; - } - - sdl_reinit_texture(); -} - -static int -sdl_init_common(void *win, int flags) -{ - wchar_t temp[128]; - SDL_version ver; - - sdl_log("SDL: init (fs=%d)\n", 0); - - /* Get and log the version of the DLL we are using. */ - SDL_GetVersion(&ver); - sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); - - /* Initialize the SDL system. */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return (0); - } - - if (flags & RENDERER_HARDWARE) { - if (flags & RENDERER_OPENGL) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); - else - sdl_select_best_hw_driver(); - } - - /* Get the size of the (current) desktop. */ - SDL_DisplayMode dm; - if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { - sdl_log("SDL: SDL_GetDesktopDisplayMode failed (%s)\n", SDL_GetError()); - return (0); - } - sdl_w = dm.w; - sdl_h = dm.h; - sdl_flags = flags; - - sdl_win = SDL_CreateWindow("86Box renderer", 640, 480, 100, 100, sdl_flags); - if (sdl_win == NULL) { - sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); - } - sdl_init_texture(); - sdl_set_fs(video_fullscreen & 1); - - /* Make sure we get a clean exit. */ - atexit(sdl_close); - - /* Register our renderer! */ - video_setblit(sdl_blit); - - sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); - - return (1); -} - -int -sdl_inits(void *win) -{ - return sdl_init_common(win, 0); -} - -int -sdl_inith(void *win) -{ - return sdl_init_common(win, RENDERER_HARDWARE); -} - -int -sdl_initho(void *win) -{ - return sdl_init_common(win, RENDERER_HARDWARE | RENDERER_OPENGL); -} - -int -sdl_pause(void) -{ - return 0; -} - -void -sdl_resize(int w, int h) -{ - int ww = 0; - int wh = 0; - - if (video_fullscreen & 2) - return; - - if ((w == cur_w) && (h == cur_h)) - return; - - SDL_LockMutex(sdl_mutex); - - ww = w; - wh = h; - - if (sdl_fs) { - // sdl_stretch(&ww, &wh, &wx, &wy); - // MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); - } - - cur_w = w; - cur_h = h; - - cur_ww = ww; - cur_wh = wh; - - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_enable(int enable) -{ - if (sdl_flags == -1) - return; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = !!enable; - - if (enable == 1) { - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - } - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_reload(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); - } -} - -static int mouse_inside = 0; -enum sdl_main_status -sdl_main() -{ - int ret = SdlMainOk; - SDL_Rect r_src; - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - ret = SdlMainQuit; - break; - case SDL_MOUSEWHEEL: - { - if (mouse_capture || video_fullscreen) { - if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { - event.wheel.x *= -1; - event.wheel.y *= -1; - } - mouse_set_z(event.wheel.y); - } - break; - } - case SDL_MOUSEMOTION: - { - if (mouse_capture || video_fullscreen) - mouse_scale(event.motion.xrel, event.motion.yrel); - break; - } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - if (!dopause && (event.button.button == SDL_BUTTON_LEFT) - && !(mouse_capture || video_fullscreen) - && event.button.state == SDL_RELEASED - && mouse_inside) { - plat_mouse_capture(1); - break; - } - if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) { - plat_mouse_capture(0); - break; - } - if (mouse_capture || video_fullscreen) { - int buttonmask = 0; - - switch (event.button.button) { - case SDL_BUTTON_LEFT: - buttonmask = 1; - break; - case SDL_BUTTON_RIGHT: - buttonmask = 2; - break; - case SDL_BUTTON_MIDDLE: - buttonmask = 4; - break; - } - if (event.button.state == SDL_PRESSED) - mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); - else - mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); - } - break; - } - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: - { - sdl_reinit_texture(); - break; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - uint16_t xtkey = 0; - switch (event.key.keysym.scancode) { - default: - xtkey = sdl_to_xt[event.key.keysym.scancode]; - break; - } - keyboard_input(event.key.state == SDL_PRESSED, xtkey); - } - break; - case SDL_WINDOWEVENT: - { - switch (event.window.event) { - case SDL_WINDOWEVENT_ENTER: - mouse_inside = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - mouse_inside = 0; - break; - } - } - } - } - - if (mouse_capture && keyboard_ismsexit()) { - plat_mouse_capture(0); - } - if (video_fullscreen && keyboard_isfsexit()) { - plat_setfullscreen(0); - } - - return ret; -} - -void -sdl_mouse_capture(int on) -{ - SDL_SetRelativeMouseMode((SDL_bool) on); -} diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h deleted file mode 100644 index f9709c857..000000000 --- a/src/qt/qt_sdl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * - * Definitions for the libSDL2 rendering module. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2019 Fred N. van Kempen. - * Copyright 2018-2019 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef WIN_SDL_H -#define WIN_SDL_H - -extern void *sdl_win_handle; -extern void sdl_close(void); -extern int sdl_inits(); -extern int sdl_inith(); -extern int sdl_initho(); -extern int sdl_pause(void); -extern void sdl_resize(int w, int h); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); - -enum sdl_main_status { - SdlMainOk, - SdlMainQuit, -}; - -extern enum sdl_main_status sdl_main(); - -extern void sdl_mouse_capture(int on); - -#endif /*WIN_SDL_H*/ From 9e5ead428cc4eead39c89bd0765fa30de9a331be Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 19 Mar 2024 17:31:46 -0300 Subject: [PATCH 271/690] De-underscore the Aptiva 510 --- src/include/86box/machine.h | 2 +- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/machine_table.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 18abf9ea9..ee18a89b1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,7 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); -extern int machine_at_aptiva_510_init(const machine_t *); +extern int machine_at_aptiva510_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4cfa7447e..0c687bf20 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -722,11 +722,11 @@ machine_at_pc330_6573_common_init(const machine_t *model) } int -machine_at_aptiva_510_init(const machine_t *model) +machine_at_aptiva510_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/aptiva_510/$IMAGES.USF", + ret = bios_load_linear("roms/machines/aptiva510/$IMAGES.USF", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 04cc59043..6683f41f0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7187,10 +7187,10 @@ const machine_t machines[] = { /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", - .internal_name = "aptiva_510", + .internal_name = "aptiva510", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_aptiva_510_init, + .init = machine_at_aptiva510_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From e587cda80d6948adb171df0c2c67d8ddda2c823e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 20:21:47 +0500 Subject: [PATCH 272/690] Translations: Remove a few unused strings --- src/qt/languages/ca-ES.po | 6 ------ 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 | 6 ------ 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 | 6 ------ 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_platform.cpp | 1 - src/unix/unix.c | 2 -- 25 files changed, 141 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index cba27b839..4554bec10 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -760,9 +760,6 @@ 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" @@ -1000,9 +997,6 @@ 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" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 31388ca54..aa8ad5664 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -760,9 +760,6 @@ msgstr "%i čekací stav(y)" msgid "Type" msgstr "Typ" -msgid "Failed to set up PCap" -msgstr "Nastala chyba při inicializaci knihovny PCap" - msgid "No PCap devices found" msgstr "Nebyla nalezena žádná PCap zařízení" @@ -1000,9 +997,6 @@ msgstr "Nebylo možné zapisovat do souboru" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Obraz disku ve formátu HDI nebo HDX s velikostí sektoru jinou než 512 bajtů nejsou podporovány." -msgid "USB is not yet supported" -msgstr "USB zatím není podporováno." - msgid "Disk image file already exists" msgstr "Soubor obrazu disku již existuje" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 86289507c..8a9360b96 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -760,9 +760,6 @@ msgstr "%i Wartezustände" msgid "Type" msgstr "Typ" -msgid "Failed to set up PCap" -msgstr "PCap konnte nicht eingerichtet werden" - msgid "No PCap devices found" msgstr "Keine PCap-Geräte gefunden" @@ -1000,9 +997,6 @@ msgstr "Die Datei konnte nicht beschrieben werden" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." -msgid "USB is not yet supported" -msgstr "USB wird noch nicht unterstützt" - msgid "Disk image file already exists" msgstr "Die Festplattenimagedatei existiert bereits" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index cff4be3ef..e3d007cc4 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -760,9 +760,6 @@ msgstr "%i Wait state(s)" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Failed to set up PCap" - msgid "No PCap devices found" msgstr "No PCap devices found" @@ -1000,9 +997,6 @@ msgstr "Unable to write file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI or HDX images with a sector size other than 512 are not supported." -msgid "USB is not yet supported" -msgstr "USB is not yet supported" - msgid "Disk image file already exists" msgstr "Disk image file already exists" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index f3bca870f..8b2c20ffe 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -760,9 +760,6 @@ msgstr "%i Wait state(s)" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Failed to set up PCap" - msgid "No PCap devices found" msgstr "No PCap devices found" @@ -1000,9 +997,6 @@ msgstr "Unable to write file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI or HDX images with a sector size other than 512 are not supported." -msgid "USB is not yet supported" -msgstr "USB is not yet supported" - msgid "Disk image file already exists" msgstr "Disk image file already exists" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index e41a94947..b88c38b07 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de Espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Incapaz de configurar PCap" - msgid "No PCap devices found" msgstr "No se encontraron dispositivos PCap" @@ -1000,9 +997,6 @@ msgstr "No se pudo escribir el archivo" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "No se soportan las imágenes HDI o HDX con un tamaño de sector diferente a 512." -msgid "USB is not yet supported" -msgstr "No se soporta aún el USB" - msgid "Disk image file already exists" msgstr "La imagen de disco ya existe" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index ddf6a0683..04a745816 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -760,9 +760,6 @@ msgstr "%i odotustilaa" msgid "Type" msgstr "Tyyppi" -msgid "Failed to set up PCap" -msgstr "PCap-asennus epäonnistui" - msgid "No PCap devices found" msgstr "PCap-laitteita ei löytynyt" @@ -1000,9 +997,6 @@ msgstr "Tiedostoon ei voi kirjoittaa" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512" -msgid "USB is not yet supported" -msgstr "USB-tukea ei vielä ole" - msgid "Disk image file already exists" msgstr "Levykuva on jo olemassa" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c443a881d..3abe3e53f 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -760,9 +760,6 @@ msgstr "%i état(s) d'attente" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Impossible d'initialiser PCap" - msgid "No PCap devices found" msgstr "Aucun dispositif PCap trouvé" @@ -1000,9 +997,6 @@ msgstr "Impossible d'écrire le fichier" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." -msgid "USB is not yet supported" -msgstr "USB n'est pas encore pris en charge." - msgid "Disk image file already exists" msgstr "Le fichier de l'image disque existe déjà." diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 28db9e32d..a830644a0 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -760,9 +760,6 @@ msgstr "%i stanje čekanja" msgid "Type" msgstr "Tip" -msgid "Failed to set up PCap" -msgstr "Postavljanje PCap-a nije uspjelo" - msgid "No PCap devices found" msgstr "Nema PCap uređaja" @@ -1000,9 +997,6 @@ msgstr "Nije moguće napisati datoteku" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI ili HDX slike s veličinom sektora koja nije 512 kB nisu podržane." -msgid "USB is not yet supported" -msgstr "USB nije još podržano" - msgid "Disk image file already exists" msgstr "Slika diska već postoji" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 07770c077..a22f6808e 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -760,9 +760,6 @@ msgstr "%i várakozási ciklus(ok)" msgid "Type" msgstr "Típus" -msgid "Failed to set up PCap" -msgstr "Nem sikerült a PCap beállítása" - msgid "No PCap devices found" msgstr "Nem találhatóak PCap eszközök" @@ -1000,9 +997,6 @@ msgstr "A fájl nem írható" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Az 512-től eltérő szektorméretű HDI vagy HDX képek nem támogatottak." -msgid "USB is not yet supported" -msgstr "Az USB még nem támogatott" - msgid "Disk image file already exists" msgstr "A lemezképfájl már létezik" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 39ecd7e89..7ff74c116 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -760,9 +760,6 @@ msgstr "%i stati d'attesa" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Impossibile impostare PCap" - msgid "No PCap devices found" msgstr "Nessun dispositivo PCap trovato" @@ -1000,9 +997,6 @@ msgstr "Impossibile scrivere al file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Le immagini HDI o HDX con settori di dimensioni diverse da 512 non sono supportati." -msgid "USB is not yet supported" -msgstr "USB non è ancora supportato" - msgid "Disk image file already exists" msgstr "Immagine disco già esiste" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 5eb5d23c1..b5aaa82e7 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -760,9 +760,6 @@ msgstr "%iつのウェイト ステート" msgid "Type" msgstr "タイプ" -msgid "Failed to set up PCap" -msgstr "PCapのセットアップに失敗しました" - msgid "No PCap devices found" msgstr "PCapデバイスがありません" @@ -1000,9 +997,6 @@ msgstr "ファイルの書き込みができません" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512以外のセクタサイズを持つHDIまたはHDXイメージはサポートされていません。" -msgid "USB is not yet supported" -msgstr "USBはまだ非対応です" - msgid "Disk image file already exists" msgstr "ディスクイメージファイルが既に存在します" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 2eaf53b2e..59855f460 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -760,9 +760,6 @@ msgstr "%i 대기 상태" msgid "Type" msgstr "형식" -msgid "Failed to set up PCap" -msgstr "PCap 설정에 실패했습니다" - msgid "No PCap devices found" msgstr "PCap 장치가 없습니다" @@ -1000,9 +997,6 @@ msgstr "파일을 저장할 수 없습니다" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512 바이트 이외의 섹터 크기를 가진 HDI 또는 HDX 형식의 이미지를 생성할 수 없습니다" -msgid "USB is not yet supported" -msgstr "USB는 아직 지원하지 않습니다" - msgid "Disk image file already exists" msgstr "디스크 이미지 파일이 이미 존재합니다" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 583774ab4..b3e71ffa0 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -760,9 +760,6 @@ msgstr "%i Stany oczekiwania" msgid "Type" msgstr "Rodzaj" -msgid "Failed to set up PCap" -msgstr "Nie udało się ustawić PCap" - msgid "No PCap devices found" msgstr "Nie znaleziono urządzeń PCap" @@ -1000,9 +997,6 @@ msgstr "Nie można zapisać pliku" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Obrazy HDI lub HDX z rozmiarem sektora innym niż 512 nie są wspierane." -msgid "USB is not yet supported" -msgstr "USB nie jest jeszcze wspierane" - msgid "Disk image file already exists" msgstr "Plik obrazu dysku już istnieje" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 8ee668a1d..b46012101 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Não foi possível configurar o PCap" - msgid "No PCap devices found" msgstr "Nenhum dispositivo PCap encontrado" @@ -1000,9 +997,6 @@ msgstr "Não foi possível escrever o arquivo" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Imagens HDI ou HDX com um tamanho de setor que não seja 512 não são suportadas." -msgid "USB is not yet supported" -msgstr "O USB ainda não é suportado" - msgid "Disk image file already exists" msgstr "Esta imagem existe" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 6ae146eaf..fc892f6dc 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Falha na configuração de PCap" - msgid "No PCap devices found" msgstr "Não foi encontrado um dispositivo PCap" @@ -1000,9 +997,6 @@ msgstr "Não foi possível escrever o ficheiro" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Imagens HDI ou HDX com um tamanho de sector diferente de 512 não são suportadas." -msgid "USB is not yet supported" -msgstr "O barramento USB ainda não tem suporte" - msgid "Disk image file already exists" msgstr "A imagem de disco já existe" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index cbeeafdd5..7ed5d0b5f 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -850,9 +850,6 @@ msgstr "%i WS" msgid "Type" msgstr "Тип" -msgid "Failed to set up PCap" -msgstr "Не удалось настроить PCap" - msgid "No PCap devices found" msgstr "Устройства PCap не найдены" @@ -1090,9 +1087,6 @@ msgstr "Невозможно записать файл" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Образы HDI или HDX с размером сектора, отличным от 512, не поддерживаются." -msgid "USB is not yet supported" -msgstr "USB пока не поддерживается" - msgid "Disk image file already exists" msgstr "Файл образа диска уже существует" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index cdcfcbfe8..8842a5215 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -760,9 +760,6 @@ 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" @@ -1000,9 +997,6 @@ 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" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index d56318aed..ae173ad30 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -760,9 +760,6 @@ msgstr "%i stanj čakanja" msgid "Type" msgstr "Vrsta" -msgid "Failed to set up PCap" -msgstr "Nastavitev PCap ni uspela" - msgid "No PCap devices found" msgstr "Nobena naprava PCap ni bila najdena" @@ -1000,9 +997,6 @@ msgstr "Ne morem pisati v datoteko" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Slike HDI ali HDX, ki nimajo sektorjev velikosti 512 bajtov, niso podprte." -msgid "USB is not yet supported" -msgstr "USB še ni podprt" - msgid "Disk image file already exists" msgstr "Datoteka s sliko diska že obstaja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 1af206659..5c413fb58 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -760,9 +760,6 @@ msgstr "%i Bekleme durumları" msgid "Type" msgstr "Tür" -msgid "Failed to set up PCap" -msgstr "PCap ayarlanamadı" - msgid "No PCap devices found" msgstr "Herhangi bir PCap cihazı bulunamadı" @@ -1000,9 +997,6 @@ msgstr "Dosyanın üzerine yazılamıyor" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." -msgid "USB is not yet supported" -msgstr "USB şu anda desteklenmemektedir" - msgid "Disk image file already exists" msgstr "Disk imaj dosyası zaten var olmakta" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 860116fe8..da48b74c7 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -760,9 +760,6 @@ msgstr "%i WS" msgid "Type" msgstr "Тип" -msgid "Failed to set up PCap" -msgstr "Не вдалося налаштувати PCap" - msgid "No PCap devices found" msgstr "Пристрої PCap не знайдені" @@ -1000,9 +997,6 @@ msgstr "Неможливо записати файл" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." -msgid "USB is not yet supported" -msgstr "USB поки не підтримується" - msgid "Disk image file already exists" msgstr "Файл образу диска вже існує" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index eade3f77e..8a09cf87d 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -760,9 +760,6 @@ msgstr "%i 等待状态 (WS)" msgid "Type" msgstr "类型" -msgid "Failed to set up PCap" -msgstr "设置 PCap 失败" - msgid "No PCap devices found" msgstr "未找到 PCap 设备" @@ -1000,9 +997,6 @@ msgstr "无法写入文件" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" -msgid "USB is not yet supported" -msgstr "尚未支持 USB" - msgid "Disk image file already exists" msgstr "磁盘映像文件已存在" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 0e61363f4..f05e16cd6 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -760,9 +760,6 @@ msgstr "%i 等待狀態 (WS)" msgid "Type" msgstr "類型" -msgid "Failed to set up PCap" -msgstr "設定 PCap 失敗" - msgid "No PCap devices found" msgstr "未找到 PCap 裝置" @@ -1000,9 +997,6 @@ msgstr "無法寫入檔案" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "不支援非 512 位元組磁區大小的 HDI 或 HDX 映像。" -msgid "USB is not yet supported" -msgstr "尚未支援 USB" - msgid "Disk image file already exists" msgstr "磁碟映像檔案已存在" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index da97680fa..04a255ac8 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -602,7 +602,6 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); - translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); diff --git a/src/unix/unix.c b/src/unix/unix.c index 848ed0f22..9cce3c898 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -256,8 +256,6 @@ plat_get_string(int i) return L"Invalid configuration"; case IDS_4099: return L"MFM/RLL or ESDI CD-ROM drives never existed"; - case IDS_2094: - return L"Failed to set up PCap"; case IDS_2095: return L"No PCap devices found"; case IDS_2096: From 8e06b5449fcf7d2fe6db9104be418df2099562ca Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 19 Mar 2024 14:27:19 +0500 Subject: [PATCH 273/690] Overhaul plat_get_string() Now takes constants with human-readable names instead of Win32 string table IDs, language.h is no longer needed ui_msgbox*() no longer accepts string IDs as arguments directly, plat_get_string() must be explicitly called to retrieve the string --- src/86box.c | 20 +-- src/config.c | 8 +- src/disk/hdd.c | 2 +- src/include/86box/language.h | 283 ----------------------------------- src/include/86box/plat.h | 20 ++- src/network/net_plip.c | 1 - src/network/network.c | 2 +- src/printer/prt_ps.c | 3 +- src/qt/qt_harddiskdialog.cpp | 8 +- src/qt/qt_main.cpp | 6 +- src/qt/qt_platform.cpp | 38 +++-- src/qt/qt_ui.cpp | 5 - src/unix/unix.c | 32 ++-- src/video/vid_svga.c | 2 +- 14 files changed, 78 insertions(+), 352 deletions(-) delete mode 100644 src/include/86box/language.h diff --git a/src/86box.c b/src/86box.c index 79ddc7692..88229a820 100644 --- a/src/86box.c +++ b/src/86box.c @@ -954,12 +954,12 @@ pc_init_modules(void) /* Load the ROMs for the selected machine. */ if (!machine_available(machine)) { - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2063), machine_getname()); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_MACHINE), machine_getname()); c = 0; machine = -1; while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); machine = c; config_save(); break; @@ -976,12 +976,12 @@ pc_init_modules(void) if (!video_card_available(gfxcard[0])) { memset(tempc, 0, sizeof(tempc)); device_get_name(video_card_getdevice(gfxcard[0]), 0, tempc); - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2064), tempc); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO), tempc); c = 0; while (video_get_internal_name(c) != NULL) { gfxcard[0] = -1; if (video_card_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); gfxcard[0] = c; config_save(); break; @@ -997,8 +997,8 @@ pc_init_modules(void) if (!video_card_available(gfxcard[1])) { char tempc[512] = { 0 }; device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc); - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2163), tempc); - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); gfxcard[1] = 0; } @@ -1289,17 +1289,17 @@ update_mouse_msg(void) mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", - plat_get_string(IDS_2077)); + plat_get_string(STRING_MOUSE_CAPTURE)); swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", - (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); + (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, - plat_get_string(IDS_2077)); + plat_get_string(STRING_MOUSE_CAPTURE)); swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, - (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); + (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif diff --git a/src/config.c b/src/config.c index 84c570f62..da02a93b0 100644 --- a/src/config.c +++ b/src/config.c @@ -663,9 +663,9 @@ load_network(void) if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC)); else if (network_dev_to_id(p) == -1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC)); strcpy(nc->host_dev_name, "none"); } else strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); @@ -710,9 +710,9 @@ load_network(void) if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC)); else if (network_dev_to_id(p) == -1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC)); strcpy(nc->host_dev_name, "none"); } else strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 3bb15c241..23dd51b92 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -53,7 +53,7 @@ hdd_string_to_bus(char *str, int cdrom) if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { if (cdrom) { no_cdrom: - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4099); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_INVALID_CONFIG), plat_get_string(STRING_NO_ST506_ESDI_CDROM)); return 0; } diff --git a/src/include/86box/language.h b/src/include/86box/language.h deleted file mode 100644 index 3c96e711f..000000000 --- a/src/include/86box/language.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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. - * - * Definitions for the language management module. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2022 Jasmine Iwanek. - */ - -#ifndef LANG_UAGE_H -#define LANG_UAGE_H - -/* String IDs. */ -#define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "Error" -#define IDS_2050 2050 // "Fatal error" -#define IDS_2051 2051 // " - PAUSED" -#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." -#define IDS_2053 2053 // "Speed" -#define IDS_2054 2054 // "ZIP %i (%03i): %ls" -#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2056 2056 // "No usable ROM images found!" -#define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2059 2059 // "(Turbo)" -#define IDS_2060 2060 // "On" -#define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Machine ""%hs"" is not..." -#define IDS_2064 2064 // "Video card ""%hs"" is not..." -#define IDS_2065 2065 // "Machine" -#define IDS_2066 2066 // "Display" -#define IDS_2067 2067 // "Input devices" -#define IDS_2068 2068 // "Sound" -#define IDS_2069 2069 // "Network" -#define IDS_2070 2070 // "Ports (COM & LPT)" -#define IDS_2071 2071 // "Storage controllers" -#define IDS_2072 2072 // "Hard disks" -#define IDS_2073 2073 // "Floppy and CD-ROM drives" -#define IDS_2074 2074 // "Other removable devices" -#define IDS_2075 2075 // "Other peripherals" -#define IDS_2076 2076 // "Surface-based images (*.8.." -#define IDS_2077 2077 // "Click to capture mouse" -#define IDS_2078 2078 // "Press F12-F8 to release mouse" -#define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2081 2081 // "Bus" -#define IDS_BUS IDS_2081 // "Bus" -#define IDS_2082 2082 // "File" -#define IDS_2083 2083 // "C" -#define IDS_2084 2084 // "H" -#define IDS_2085 2085 // "S" -#define IDS_2086 2086 // "MB" -#define IDS_MB IDS_2086 // "MB" -#define IDS_2087 2087 // "Speed" - -#define IDS_2088 2088 // "Check BPB" -#define IDS_BPB IDS_2088 // "Check BPB" - -#define IDS_2089 2089 // "KB" -#define IDS_KB IDS_2089 // "KB" - -#define IDS_2090 2090 // "Could not initialize the video..." - -#define IDS_2091 2091 // "Default" -#define IDS_DEFAULT IDS_2091 // "Default" - -#define IDS_2092 2092 // "%i Wait state(s)" -#define IDS_WS IDS_2092 // "%i Wait state(s)" - -#define IDS_2093 2093 // "Type" -#define IDS_TYPE IDS_2093 // "Type" - -/* TODO */ -#define IDS_2094 2094 // "PCap failed to set up.." -#define IDS_2095 2095 // "No PCap devices found" -#define IDS_2096 2096 // "Invalid PCap device" -#define IDS_2097 2097 // "Standard 2-button joystick(s)" -#define IDS_2098 2098 // "Standard 4-button joystick" -#define IDS_2099 2099 // "Standard 6-button joystick" -#define IDS_2100 2100 // "Standard 8-button joystick" -#define IDS_2101 2101 // "CH Flightstick Pro" -#define IDS_2102 2102 // "Microsoft SideWinder Pad" -#define IDS_2103 2103 // "Thrustmaster Flight Cont.." -#define IDS_2104 2104 // "None" -#define IDS_2105 2105 // "Unable to load keyboard..." -#define IDS_2106 2106 // "Unable to register raw input." -#define IDS_2107 2107 // "%u" -#define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" -#define IDS_2109 2109 // "Floppy %i (%s): %ls" -#define IDS_2110 2110 // "All floppy images (*.0??;*.." -#define IDS_2113 2113 // "Are you sure you want to..." -#define IDS_2114 2114 // "Are you sure you want to..." -#define IDS_2115 2115 // "Unable to initialize Ghostscript..." -#define IDS_2116 2116 // "MO %i (%03i): %ls" -#define IDS_2117 2117 // "MO images (*.IM?)\0*.IM..." -#define IDS_2118 2118 // "Welcome to 86Box!" -#define IDS_2119 2119 // "Internal controller" -#define IDS_2120 2120 // "Exit" -#define IDS_2121 2121 // "No ROMs found" -#define IDS_2122 2122 // "Do you want to save the settings?" -#define IDS_2123 2123 // "This will hard reset the emulated..." -#define IDS_2124 2124 // "Save" -#define IDS_2125 2125 // "About 86Box" -#define IDS_2126 2126 // "86Box v" EMU_VERSION -#define IDS_2127 2127 // "An emulator of old computers..." -#define IDS_2128 2128 // "OK" -#define IDS_2129 2129 // "Hardware not available" -#define IDS_2130 2130 // "Make sure " LIB_NAME_PCAP "..." -#define IDS_2131 2131 // "Invalid configuration" -#define IDS_2133 2133 // LIB_NAME_GS " is required for... -#define IDS_2135 2135 // "Entering fullscreen mode" -#define IDS_2136 2136 // "Don't show this message again" -#define IDS_2137 2137 // "Don't exit" -#define IDS_2138 2138 // "Reset" -#define IDS_2139 2139 // "Don't reset" -#define IDS_2140 2140 // "MO images (*.IM?)\0*.IM?..." -#define IDS_2141 2141 // "CD-ROM images (*.ISO;*.CU.." -#define IDS_2142 2142 // "%hs Device Configuration" -#define IDS_2143 2143 // "Monitor in sleep mode" -#define IDS_2144 2144 // "OpenGL Shaders (*.GLSL)..." -#define IDS_2145 2145 // "OpenGL options" -#define IDS_2146 2146 // "You are loading an unsupported..." -#define IDS_2147 2147 // "CPU type filtering based on..." -#define IDS_2148 2148 // "Continue" -#define IDS_2149 2149 // "Cassette: %s" -#define IDS_2150 2150 // "Cassette images (*.PCM;*.RAW;*..." -#define IDS_2151 2151 // "Cartridge %i: %ls" -#define IDS_2152 2152 // "Cartridge images (*.JRC)\0*.JRC\0..." -#define IDS_2153 2153 // "Error initializing renderer" -#define IDS_2154 2154 // "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -#define IDS_2155 2155 // "Resume execution" -#define IDS_2156 2156 // "Pause execution" -#define IDS_2157 2157 // "Press Ctrl+Alt+Del" -#define IDS_2158 2158 // "Press Ctrl+Alt+Esc" -#define IDS_2159 2159 // "Hard reset" -#define IDS_2160 2160 // "ACPI shutdown" -#define IDS_2161 2161 // "Settings" -#define IDS_2162 2162 // "Early drive" -#define IDS_2163 2163 // "no dynarec" -#define IDS_2164 2164 // "old dynarec" -#define IDS_2165 2165 // "new dynarec" -#ifdef USE_DYNAREC -# ifdef USE_NEW_DYNAREC -# define IDS_DYNAREC IDS_2165 -# else -# define IDS_DYNAREC IDS_2164 -# endif -#else -# define IDS_DYNAREC IDS_2163 -#endif -#define IDS_2166 2166 // "Video card #2 ""%hs"" is not..." -#define IDS_2167 2167 // "Network driver initialization failed" -#define IDS_2168 2168 // "The network configuration will be switched to the null driver" - -#define IDS_4096 4096 // "Hard disk (%s)" -#define IDS_4097 4097 // "%01i:%01i" -#define IDS_4098 4098 // "%i" -#define IDS_4099 4099 // "MFM/RLL or ESDI CD-ROM driv.." -#define IDS_4100 4100 // "Custom..." -#define IDS_4101 4101 // "Custom (large)..." -#define IDS_4102 4102 // "Add New Hard Disk" -#define IDS_4103 4103 // "Add Existing Hard Disk" -#define IDS_4104 4104 // "HDI disk images cannot be..." -#define IDS_4105 4105 // "Disk images cannot be larger..." -#define IDS_4106 4106 // "Hard disk images (*.HDI;*.HD.." -#define IDS_4107 4107 // "Unable to open the file for read" -#define IDS_4108 4108 // "Unable to open the file for write" -#define IDS_4109 4109 // "HDI or HDX image with a sect.." -#define IDS_4110 4110 // "USB is not yet supported" -#define IDS_4111 4111 // "Disk image file already exists" -#define IDS_4112 4112 // "Please specify a valid file name." -#define IDS_4113 4113 // "Remember to partition and fo.." -#define IDS_4114 4114 // "Make sure the file exists and..." -#define IDS_4115 4115 // "Make sure the file is being..." -#define IDS_4116 4116 // "Disk image too large" -#define IDS_4117 4117 // "Remember to partition and format..." -#define IDS_4118 4118 // "The selected file will be..." -#define IDS_4119 4119 // "Unsupported disk image" -#define IDS_4120 4120 // "Overwrite" -#define IDS_4121 4121 // "Don't overwrite" -#define IDS_4122 4122 // "Raw image (.img)" -#define IDS_4123 4123 // "HDI image (.hdi)" -#define IDS_4124 4124 // "HDX image (.hdx)" -#define IDS_4125 4125 // "Fixed-size VHD (.vhd)" -#define IDS_4126 4126 // "Dynamic-size VHD (.vhd)" -#define IDS_4127 4127 // "Differencing VHD (.vhd)" -#define IDS_4128 4128 // "Large blocks (2 MB)" -#define IDS_4129 4129 // "Small blocks (512 KB)" -#define IDS_4130 4130 // "VHD files (*.VHD)\0*.VHD\0All..." -#define IDS_4131 4131 // "Select the parent VHD" -#define IDS_4132 4132 // "This could mean that the parent..." -#define IDS_4133 4133 // "Parent and child disk timestamps..." -#define IDS_4134 4134 // "Could not fix VHD timestamp." -#define IDS_4135 4135 // "%01i:%02i" - -#define IDS_4352 4352 // "MFM/RLL" -#define IDS_4353 4353 // "XT IDE" -#define IDS_4354 4354 // "ESDI" -#define IDS_4355 4355 // "IDE" -#define IDS_4356 4356 // "ATAPI" -#define IDS_4357 4357 // "SCSI" - -#define IDS_4608 4608 // "MFM/RLL (%01i:%01i)" -#define IDS_4609 4609 // "XT IDE (%01i:%01i)" -#define IDS_4610 4610 // "ESDI (%01i:%01i)" -#define IDS_4611 4611 // "IDE (%01i:%01i)" -#define IDS_4612 4612 // "ATAPI (%01i:%01i)" -#define IDS_4613 4613 // "SCSI (%02i:%02i)" - -#define IDS_5120 5120 // "CD-ROM %i (%s): %s" - -#define IDS_5376 5376 // "Disabled" -#define IDS_5377 5377 // -#define IDS_5378 5378 // -#define IDS_5379 5379 // -#define IDS_5380 5380 // -#define IDS_5381 5381 // "ATAPI" -#define IDS_5382 5382 // "SCSI" - -#define IDS_5632 5632 // "Disabled" -#define IDS_5633 5633 // -#define IDS_5634 5634 // -#define IDS_5635 5635 // -#define IDS_5636 5636 // -#define IDS_5637 5637 // "ATAPI (%01i:%01i)" -#define IDS_5638 5638 // "SCSI (%02i:%02i)" - -#define IDS_5888 5888 // "160 kB" -#define IDS_5889 5889 // "180 kB" -#define IDS_5890 5890 // "320 kB" -#define IDS_5891 5891 // "360 kB" -#define IDS_5892 5892 // "640 kB" -#define IDS_5893 5893 // "720 kB" -#define IDS_5894 5894 // "1.2 MB" -#define IDS_5895 5895 // "1.25 MB" -#define IDS_5896 5896 // "1.44 MB" -#define IDS_5897 5897 // "DMF (cluster 1024)" -#define IDS_5898 5898 // "DMF (cluster 2048)" -#define IDS_5899 5899 // "2.88 MB" -#define IDS_5900 5900 // "ZIP 100" -#define IDS_5901 5901 // "ZIP 250" -#define IDS_5902 5902 // "3.5\" 128 MB (ISO 10090)" -#define IDS_5903 5903 // "3.5\" 230 MB (ISO 13963)" -#define IDS_5904 5904 // "3.5\" 540 MB (ISO 15498)" -#define IDS_5905 5905 // "3.5\" 640 MB (ISO 15498)" -#define IDS_5906 5906 // "3.5\" 1.3 GB (GigaMO)" -#define IDS_5907 5907 // "3.5\" 2.3 GB (GigaMO 2)" -#define IDS_5908 5908 // "5.25\" 600 MB" -#define IDS_5909 5909 // "5.25\" 650 MB" -#define IDS_5910 5910 // "5.25\" 1 GB" -#define IDS_5911 5911 // "5.25\" 1.3 GB" - -#define IDS_6144 6144 // "Perfect RPM" -#define IDS_6145 6145 // "1%% below perfect RPM" -#define IDS_6146 6146 // "1.5%% below perfect RPM" -#define IDS_6147 6147 // "2%% below perfect RPM" - -#define IDS_7168 7168 // "(System Default)" - -#define IDS_LANG_ENUS IDS_7168 - -#define STR_NUM_2048 121 -// UNUSED: #define STR_NUM_3072 11 -#define STR_NUM_4096 40 -#define STR_NUM_4352 6 -#define STR_NUM_4608 6 -#define STR_NUM_5120 1 -#define STR_NUM_5376 7 -#define STR_NUM_5632 7 -#define STR_NUM_5888 24 -#define STR_NUM_6144 4 -#define STR_NUM_7168 1 - -#endif /*LANG_UAGE_H*/ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 32f50c638..5b36bab7e 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -30,7 +30,25 @@ #endif /* String ID numbers. */ -#include <86box/language.h> +enum { + STRING_MOUSE_CAPTURE, /* "Click to capture mouse" */ + STRING_MOUSE_RELEASE, /* "Press F8+F12/Ctrl+End to release mouse" */ + STRING_MOUSE_RELEASE_MMB, /* "Press F8+F12/Ctrl+End or middle button to release mouse" */ + STRING_INVALID_CONFIG, /* "Invalid configuration" */ + STRING_NO_ST506_ESDI_CDROM, /* "MFM/RLL or ESDI CD-ROM drives never existed" */ + STRING_NET_ERROR, /* "Failed to initialize network driver" */ + STRING_NET_ERROR_DESC, /* "The network configuration will be switched..." */ + STRING_PCAP_ERROR_NO_DEVICES, /* "No PCap devices found" */ + STRING_PCAP_ERROR_INVALID_DEVICE, /* "Invalid PCap device" */ + STRING_PCAP_ERROR_DESC, /* "Make sure libpcap is installed..." */ + STRING_GHOSTSCRIPT_ERROR_TITLE, /* "Unable to initialize Ghostscript" */ + STRING_GHOSTSCRIPT_ERROR_DESC, /* "gsdll32.dll/gsdll64.dll/libgs is required..." */ + STRING_HW_NOT_AVAILABLE_TITLE, /* "Hardware not available" */ + STRING_HW_NOT_AVAILABLE_MACHINE, /* "Machine \"%hs\" is not available..." */ + STRING_HW_NOT_AVAILABLE_VIDEO, /* "Video card \"%hs\" is not available..." */ + STRING_HW_NOT_AVAILABLE_VIDEO2, /* "Video card #2 \"%hs\" is not available..." */ + STRING_MONITOR_SLEEP /* "Monitor in sleep mode" */ +}; /* The Win32 API uses _wcsicmp. */ #ifdef _WIN32 diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 41e5502a6..8b0bf460c 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -26,7 +26,6 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/language.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> diff --git a/src/network/network.c b/src/network/network.c index fe3bf8489..d0ebe8ef3 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -504,7 +504,7 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin if(net_cards_conf[net_card_current].net_type != NET_TYPE_NONE) { // We're here because of a failure - swprintf(tempmsg, sizeof_w(tempmsg), L"%ls:

%s

%ls", plat_get_string(IDS_2167), net_drv_error, plat_get_string(IDS_2168)); + swprintf(tempmsg, sizeof_w(tempmsg), L"%ls:

%s

%ls", plat_get_string(STRING_NET_ERROR), net_drv_error, plat_get_string(STRING_NET_ERROR_DESC)); ui_msgbox(MBX_ERROR, tempmsg); net_cards_conf[net_card_current].net_type = NET_TYPE_NONE; } diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index c0e3958b2..e6362019f 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -23,7 +23,6 @@ #include #include #include <86box/86box.h> -#include <86box/language.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> @@ -352,7 +351,7 @@ ps_init(void *lpt) } #endif if (ghostscript_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTSCRIPT_ERROR_TITLE), plat_get_string(STRING_GHOSTSCRIPT_ERROR_DESC)); } else { if (gsapi_revision(&rev, sizeof(rev)) == 0) { pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 187bf4ba2..5efd895dc 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -516,8 +516,8 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) fp = _wfopen(wopenfilestring, L"rb"); if (fp != NULL) { fclose(fp); - if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) / * yes * / - return FALSE; + if (settings_msgbox_ex(MBX_QUESTION_YN, L"Disk image file already exists", L"The selected file will be overwritten. Are you sure you want to use it?", L"Overwrite", L"Don't overwrite", NULL) != 0) / * yes * / + return false; } } @@ -525,8 +525,8 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) if (fp == NULL) { hdd_add_file_open_error: fclose(fp); - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; + settings_msgbox_header(MBX_ERROR, (existing & 1) ? L"Make sure the file exists and is readable." : L"Make sure the file is being saved to a writable directory.", (existing & 1) ? L"Unable to read file" : L"Unable to write file"); + return true; } #endif diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index f87f8b6a9..493563c66 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -214,7 +214,11 @@ main(int argc, char *argv[]) #endif if (!pc_init_modules()) { - ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); + QMessageBox fatalbox(QMessageBox::Icon::Critical, QObject::tr("No ROMs found"), + QObject::tr("86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."), + QMessageBox::Ok); + fatalbox.setTextFormat(Qt::TextFormat::RichText); + fatalbox.exec(); return 6; } diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 04a255ac8..079906753 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -597,31 +597,29 @@ void ProgSettings::reloadStrings() { translatedstrings.clear(); - translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); - translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); - translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); - translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); - translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); - translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); - translatedstrings[IDS_2064] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); - translatedstrings[IDS_2163] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); - translatedstrings[IDS_2129] = QCoreApplication::translate("", "Hardware not available").toStdWString(); - translatedstrings[IDS_2143] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); - translatedstrings[IDS_2121] = QCoreApplication::translate("", "No ROMs found").toStdWString(); - translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.").toStdWString(); - translatedstrings[IDS_2167] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); - translatedstrings[IDS_2168] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); + translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); + translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_INVALID_DEVICE] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_TITLE] = QCoreApplication::translate("", "Hardware not available").toStdWString(); + translatedstrings[STRING_MONITOR_SLEEP] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); + translatedstrings[STRING_NET_ERROR] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); + translatedstrings[STRING_NET_ERROR_DESC] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); - auto gsstr = QCoreApplication::translate("", " 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."); + auto gsstr = QCoreApplication::translate("", " 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."); if (gsstr.contains("libgs")) { gsstr.replace("libgs", LIB_NAME_GS); } else gsstr.prepend(LIB_NAME_GS); - translatedstrings[IDS_2133] = gsstr.toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = gsstr.toStdWString(); } wchar_t * diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index b544bbde1..5412a0e4a 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -122,11 +122,6 @@ plat_mouse_capture(int on) int ui_msgbox_header(int flags, void *header, void *message) { - if (header <= (void *) 7168) - header = plat_get_string((uintptr_t) header); - if (message <= (void *) 7168) - message = plat_get_string((uintptr_t) message); - auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); diff --git a/src/unix/unix.c b/src/unix/unix.c index 9cce3c898..3eddc2bbb 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -246,33 +246,33 @@ wchar_t * plat_get_string(int i) { switch (i) { - case IDS_2077: + case STRING_MOUSE_CAPTURE: return L"Click to capture mouse"; - case IDS_2078: + case STRING_MOUSE_RELEASE: return L"Press CTRL-END to release mouse"; - case IDS_2079: + case STRING_MOUSE_RELEASE_MMB: return L"Press CTRL-END or middle button to release mouse"; - case IDS_2131: + case STRING_INVALID_CONFIG: return L"Invalid configuration"; - case IDS_4099: + case STRING_NO_ST506_ESDI_CDROM: return L"MFM/RLL or ESDI CD-ROM drives never existed"; - case IDS_2095: + case STRING_PCAP_ERROR_NO_DEVICES: return L"No PCap devices found"; - case IDS_2096: + case STRING_PCAP_ERROR_INVALID_DEVICE: return L"Invalid PCap device"; - case IDS_2133: + case STRING_GHOSTSCRIPT_ERROR_DESC: return L"libgs 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."; - case IDS_2130: + case STRING_PCAP_ERROR_DESC: return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; - case IDS_2115: + case STRING_GHOSTSCRIPT_ERROR_TITLE: return L"Unable to initialize Ghostscript"; - case IDS_2063: + case STRING_HW_NOT_AVAILABLE_MACHINE: return L"Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine."; - case IDS_2064: + case STRING_HW_NOT_AVAILABLE_VIDEO: return L"Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card."; - case IDS_2129: + case STRING_HW_NOT_AVAILABLE_TITLE: return L"Hardware not available"; - case IDS_2143: + case STRING_MONITOR_SLEEP: return L"Monitor in sleep mode"; } return L""; @@ -638,10 +638,6 @@ ui_msgbox_header(int flags, void *header, void *message) if (!header) header = (void *) ((flags & MBX_ANSI) ? "86Box" : L"86Box"); - if (header <= (void *) 7168) - header = (void *) plat_get_string((uintptr_t) header); - if (message <= (void *) 7168) - message = (void *) plat_get_string((uintptr_t) message); msgbtn.buttonid = 1; msgbtn.text = "OK"; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b20364689..6e32bdc40 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -957,7 +957,7 @@ svga_recalctimings(svga_t *svga) video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; - ui_sb_set_text_w(plat_get_string(IDS_2143)); + ui_sb_set_text_w(plat_get_string(STRING_MONITOR_SLEEP)); } } else if (svga->dpms_ui) { svga->dpms_ui = 0; From ae7d4454cbbd115ad8977cd3ac6e1db908c5d567 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 16:48:09 +0500 Subject: [PATCH 274/690] Move Windows font overrides away from translations Determine which font to use with a dedicated function instead --- src/qt/languages/ca-ES.po | 6 ------ 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 | 6 ------ 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 | 6 ------ 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_main.cpp | 4 +--- src/qt/qt_mainwindow.cpp | 4 +--- src/qt/qt_progsettings.cpp | 19 +++++++++++++++++++ src/qt/qt_progsettings.hpp | 3 +++ 27 files changed, 24 insertions(+), 144 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 4554bec10..0074e4a01 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -625,12 +625,6 @@ msgstr "Dispositiu ISABugger" msgid "POST card" msgstr "Targeta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index aa8ad5664..f02f63e14 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -625,12 +625,6 @@ msgstr "Zařízení ISABugger" msgid "POST card" msgstr "Karta pro kódy POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 8a9360b96..62308e9d8 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -625,12 +625,6 @@ msgstr "ISABugger-Gerät" msgid "POST card" msgstr "POST-Code-Karte" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index e3d007cc4..8fb00f833 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -625,12 +625,6 @@ msgstr "ISABugger device" msgid "POST card" msgstr "POST card" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 8b2c20ffe..147521bb3 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -625,12 +625,6 @@ msgstr "ISABugger device" msgid "POST card" msgstr "POST card" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index b88c38b07..066a31310 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Tarjeta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 04a745816..a81857596 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -625,12 +625,6 @@ msgstr "ISABugger-laite" msgid "POST card" msgstr "POST-kortti" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 3abe3e53f..4e9b94d33 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -625,12 +625,6 @@ msgstr "Dispositif ISABugger" msgid "POST card" msgstr "Carte POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index a830644a0..0255a8280 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -625,12 +625,6 @@ msgstr "Uređaj ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index a22f6808e..e5225dbbb 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -625,12 +625,6 @@ msgstr "ISABugger eszköz" msgid "POST card" msgstr "POST kártya" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 7ff74c116..43ece2315 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Scheda POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index b5aaa82e7..971bbd29f 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -625,12 +625,6 @@ msgstr "ISABuggerデバイス" msgid "POST card" msgstr "POSTカード" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Meiryo UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 59855f460..ea6e196fe 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -625,12 +625,6 @@ msgstr "ISABugger 장치" msgid "POST card" msgstr "POST 카드" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Malgun Gothic" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b3e71ffa0..c6a70d905 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -625,12 +625,6 @@ msgstr "Urządzenie ISABugger" msgid "POST card" msgstr "Karta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index b46012101..45d8a8530 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa de diagnóstico" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index fc892f6dc..156f63926 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 7ed5d0b5f..41cad4eda 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -712,12 +712,6 @@ msgstr "Карта POST" msgid "86Box Unit Tester" msgstr "Модульный Тестер 86Box" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 8842a5215..a6d13b95b 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -625,12 +625,6 @@ 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" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index ae173ad30..93941ffe8 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -625,12 +625,6 @@ msgstr "Naprava ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 5c413fb58..c65f6077c 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -625,12 +625,6 @@ msgstr "ISABugger cihazı" msgid "POST card" msgstr "POST kartı" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index da48b74c7..f7a819a92 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -625,12 +625,6 @@ msgstr "Пристрій ISABugger" msgid "POST card" msgstr "Карта POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 8a09cf87d..5c3fbb54f 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -625,12 +625,6 @@ msgstr "ISABugger 设备" msgid "POST card" msgstr "自检 (POST) 卡" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Microsoft YaHei" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index f05e16cd6..927eb2d85 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -625,12 +625,6 @@ msgstr "ISABugger 裝置" msgid "POST card" msgstr "自檢 (POST) 卡" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Microsoft JhengHei" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 493563c66..a621d1441 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -191,9 +191,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); #ifdef Q_OS_WINDOWS - auto font_name = QObject::tr("FONT_NAME"); - auto font_size = QObject::tr("FONT_SIZE"); - QApplication::setFont(QFont(font_name, font_size.toInt())); + QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f0d2cf431..f4c01b4a2 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1919,9 +1919,7 @@ MainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { - auto font_name = tr("FONT_NAME"); - auto font_size = tr("FONT_SIZE"); - QApplication::setFont(QFont(font_name, font_size.toInt())); + QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); } #endif QWidget::changeEvent(event); diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index cf15e6c04..2d047a787 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -153,6 +153,25 @@ ProgSettings::on_pushButton_released() ui->comboBox->setCurrentIndex(0); } +#ifdef Q_OS_WINDOWS +/* Return the standard font name on Windows, which is overridden per-language + to prevent CJK fonts with embedded bitmaps being chosen as a fallback. */ +QString +ProgSettings::getFontName(uint32_t lcid) +{ + if (lcid == 0x0804) /* zh-CN */ + return "Microsoft YaHei"; + else if (lcid == 0x0404) /* zh-TW */ + return "Microsoft JhengHei"; + else if (lcid == 0x0411) /* ja-JP */ + return "Meiryo UI"; + else if (lcid == 0x0412) /* ko-KR */ + return "Malgun Gothic"; + else + return "Segoe UI"; +} +#endif + void ProgSettings::loadTranslators(QObject *parent) { diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 7565869b0..d41f267df 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -16,6 +16,9 @@ public: ~ProgSettings(); static QString getIconSetPath(); static QIcon loadIcon(QString file); +#ifdef Q_OS_WINDOWS + static QString getFontName(uint32_t lcid); +#endif static void loadTranslators(QObject *parent = nullptr); static void reloadStrings(); class CustomTranslator : public QTranslator { From 3cc0a9176cab43efebcc614df0aee2adfbaa07a3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 16:49:15 +0500 Subject: [PATCH 275/690] Remove unused and unmaintained pcap_if utility --- src/network/pcap_if.c | 296 ------------------------------------------ 1 file changed, 296 deletions(-) delete mode 100644 src/network/pcap_if.c diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c deleted file mode 100644 index 1d3e39221..000000000 --- a/src/network/pcap_if.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * Simple program to show usage of (Win)Pcap. - * - * Based on the "libpcap" examples. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> - -static void *pcap_handle; /* handle to WinPcap DLL */ - -/* Pointers to the real functions. */ -static int (*f_pcap_findalldevs)(pcap_if_t **, char *); -static void (*f_pcap_freealldevs)(pcap_if_t *); -static pcap_t *(*f_pcap_open_live)(const char *, int, int, int, char *); -static int (*f_pcap_next_ex)(pcap_t *, struct pcap_pkthdr **, const unsigned char **); -static void (*f_pcap_close)(pcap_t *); -static dllimp_t pcap_imports[] = { - // clang-format off - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_next_ex", &f_pcap_next_ex }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, - // clang-format on -}; - -typedef struct { - char device[128]; - char description[128]; -} capdev_t; - -/* Retrieve an easy-to-use list of devices. */ -static int -get_devlist(capdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist; - int i = 0; - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf); - return (-1); - } - - for (pcap_if_t *dev = devlist; dev != NULL; dev = dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; - i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return i; -} - -/* Simple HEXDUMP routine for raw data. */ -static void -hex_dump(unsigned char *bufp, int len) -{ - char asci[20]; - unsigned char c; - long addr; - - addr = 0; - while (len-- > 0) { - c = bufp[addr]; - if ((addr % 16) == 0) - printf("%04lx %02x", addr, c); - else - printf(" %02x", c); - asci[addr & 15] = (uint8_t) isprint(c) ? c : '.'; - if ((++addr % 16) == 0) { - asci[16] = '\0'; - printf(" | %s |\n", asci); - } - } - - if (addr % 16) { - while (addr % 16) { - printf(" "); - asci[addr & 15] = ' '; - addr++; - } - asci[16] = '\0'; - printf(" | %s |\n", asci); - } -} - -/* Print a standard Ethernet MAC address. */ -static void -eth_praddr(unsigned char *ptr) -{ - printf("%02x:%02x:%02x:%02x:%02x:%02x", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); -} - -/* Print a standard Ethernet header. */ -static int -eth_prhdr(unsigned char *ptr) -{ - unsigned short type; - - printf("Ethernet "); - eth_praddr(ptr + 6); - printf(" > "); - eth_praddr(ptr); - type = (ptr[12] << 8) | ptr[13]; - printf(" type %04x\n", type); - - return 14; -} - -/* Capture packets from the network, and print them. */ -static int -start_cap(char *dev) -{ - char temp[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr *hdr; - const unsigned char *pkt; - const struct tm *ltime; - time_t now; - pcap_t *pcap; - int rc; - - /* Open the device for reading from it. */ - pcap = f_pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); - if (pcap == NULL) { - fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); - return 2; - } - - printf("Listening on '%s'..\n", dev); - for (;;) { - rc = f_pcap_next_ex(pcap, &hdr, &pkt); - if (rc < 0) - break; - - /* Did we time out? */ - if (rc == 0) - continue; - - /* Convert the timestamp to readable format. */ - now = hdr->ts.tv_sec; - ltime = localtime(&now); - strftime(temp, sizeof(temp), "%H:%M:%S", ltime); - - /* Process and print the packet. */ - printf("\n<< %s,%.6ld len=%u\n", - temp, hdr->ts.tv_usec, hdr->len); - rc = eth_prhdr((unsigned char *) pkt); - hex_dump((unsigned char *) pkt + rc, hdr->len - rc); - } - - /* All done, close up. */ - f_pcap_close(pcap); - - return 0; -} - -/* Show a list of available network interfaces. */ -static void -show_devs(capdev_t *list, int num) -{ - if (num > 0) { - printf("Available network interfaces:\n\n"); - - for (int i = 0; i < num; i++) { - printf(" %d - %s\n", i + 1, list->device); - if (list->description[0] != '\0') - printf(" (%s)\n", list->description); - else - printf(" (No description available)\n"); - list++; - printf("\n"); - } - } else { - printf("No interfaces found!\nMake sure WinPcap is installed.\n"); - } -} - -int -main(int argc, char **argv) -{ - capdev_t interfaces[32]; - int numdev; - int i; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#elif defined __APPLE__ - pcap_handle = dynld_module("libpcap.dylib", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) { -#ifdef _WIN32 - fprintf(stderr, "Unable to load WinPcap DLL !\n"); -#else - fprintf(stderr, "Unable to load libpcap.so !\n"); -#endif - return 1; - } - - /* Get the list. */ - numdev = get_devlist(interfaces); - - if (argc == 1) { - /* No arguments, just show the list. */ - show_devs(interfaces, numdev); - - dynld_close(pcap_handle); - - return numdev; - } - - /* Assume argument to be the interface number to listen on. */ - i = atoi(argv[1]); - if (i < 0 || i > numdev) { - fprintf(stderr, "Invalid interface number %d !\n", i); - - dynld_close(pcap_handle); - - return 1; - } - - /* Looks good, go and listen.. */ - i = start_cap(interfaces[i - 1].device); - - dynld_close(pcap_handle); - - return i; -} From 82e6a7a1293d91267110f0ecda22a3ead00c8ecd Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 17:17:12 +0500 Subject: [PATCH 276/690] Don't recognize no longer used HDD bus types --- src/disk/hdd.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 23dd51b92..7acfc82be 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -50,7 +50,7 @@ hdd_string_to_bus(char *str, int cdrom) if (!strcmp(str, "none")) return HDD_BUS_DISABLED; - if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { + if (!strcmp(str, "mfm")) { if (cdrom) { no_cdrom: ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_INVALID_CONFIG), plat_get_string(STRING_NO_ST506_ESDI_CDROM)); @@ -60,41 +60,22 @@ no_cdrom: return HDD_BUS_MFM; } - /* FIXME: delete 'rll' in a year or so.. --FvK */ - if (!strcmp(str, "esdi") || !strcmp(str, "rll")) { + if (!strcmp(str, "esdi")) { if (cdrom) goto no_cdrom; return HDD_BUS_ESDI; } - if (!strcmp(str, "ide_pio_only")) - return HDD_BUS_IDE; - if (!strcmp(str, "ide")) return HDD_BUS_IDE; - if (!strcmp(str, "atapi_pio_only")) - return HDD_BUS_ATAPI; - if (!strcmp(str, "atapi")) return HDD_BUS_ATAPI; - if (!strcmp(str, "eide")) - return HDD_BUS_IDE; - if (!strcmp(str, "xta")) return HDD_BUS_XTA; - if (!strcmp(str, "atide")) - return HDD_BUS_IDE; - - if (!strcmp(str, "ide_pio_and_dma")) - return HDD_BUS_IDE; - - if (!strcmp(str, "atapi_pio_and_dma")) - return HDD_BUS_ATAPI; - if (!strcmp(str, "scsi")) return HDD_BUS_SCSI; From f02fd4568c461aad97f29623f2780b9d572a0146 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 18:52:51 +0500 Subject: [PATCH 277/690] Simplify dynamic string handling and localization Use Qt `.arg()` instead of substring replacement; Fully remove remnants of SDL renderers from translations; Restore platform-dependent pcap library name in the pcap error message, but use Npcap on Windows instead --- src/qt/languages/ca-ES.po | 47 ++++++++++++---------------------- src/qt/languages/cs-CZ.po | 47 ++++++++++++---------------------- src/qt/languages/de-DE.po | 50 ++++++++++++++----------------------- src/qt/languages/en-GB.po | 47 ++++++++++++---------------------- src/qt/languages/en-US.po | 47 ++++++++++++---------------------- src/qt/languages/es-ES.po | 47 ++++++++++++---------------------- src/qt/languages/fi-FI.po | 47 ++++++++++++---------------------- src/qt/languages/fr-FR.po | 47 ++++++++++++---------------------- src/qt/languages/hr-HR.po | 47 ++++++++++++---------------------- src/qt/languages/hu-HU.po | 47 ++++++++++++---------------------- src/qt/languages/it-IT.po | 47 ++++++++++++---------------------- src/qt/languages/ja-JP.po | 47 ++++++++++++---------------------- src/qt/languages/ko-KR.po | 47 ++++++++++++---------------------- src/qt/languages/pl-PL.po | 47 ++++++++++++---------------------- src/qt/languages/pt-BR.po | 47 ++++++++++++---------------------- src/qt/languages/pt-PT.po | 47 ++++++++++++---------------------- src/qt/languages/ru-RU.po | 47 ++++++++++++---------------------- src/qt/languages/sk-SK.po | 47 ++++++++++++---------------------- src/qt/languages/sl-SI.po | 47 ++++++++++++---------------------- src/qt/languages/tr-TR.po | 47 ++++++++++++---------------------- src/qt/languages/uk-UA.po | 47 ++++++++++++---------------------- src/qt/languages/zh-CN.po | 47 ++++++++++++---------------------- src/qt/languages/zh-TW.po | 47 ++++++++++++---------------------- src/qt/qt_machinestatus.cpp | 12 ++++----- src/qt/qt_platform.cpp | 22 +++++++--------- src/qt/qt_progsettings.hpp | 6 ----- 26 files changed, 386 insertions(+), 738 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 0074e4a01..ff69d11a7 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -40,14 +40,11 @@ msgstr "&Recordar mida i posició" msgid "Re&nderer" msgstr "Re&nderitzador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ 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 %1 to release mouse" +msgstr "Premeu %1 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 "Press %1 or middle button to release mouse" +msgstr "Premeu %1 o el botó central per alliberar el ratolí" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulador d'ordinadors antics\n\nAutors: Miran Grča (OBattler), Richa 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 "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Assegureu-vos que el %1 està instal·lat i que està en una connexió de xarxa compatible amb %1." 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 "%1 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 "%1 é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" @@ -892,8 +877,8 @@ msgstr "No resetejar" msgid "CD-ROM images" msgstr "Imatges de CD-ROM" -msgid "%hs Device Configuration" -msgstr "%hs Configuració de Dispositiu" +msgid "%1 Device Configuration" +msgstr "%1 Configuració de Dispositiu" msgid "Monitor in sleep mode" msgstr "Monitor en mode estalvi" @@ -949,8 +934,8 @@ msgstr "Reinicialització completa" msgid "ACPI shutdown" msgstr "Apagada ACPI" -msgid "Hard disk (%s)" -msgstr "Disc dur (%s)" +msgid "Hard disk (%1)" +msgstr "Disc dur (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index f02f63e14..f89521fdf 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -40,14 +40,11 @@ msgstr "&Pamatovat velikost a pozici" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Jiné příslušenství" msgid "Click to capture mouse" msgstr "Klikněte pro zabraní myši" -msgid "Press F8+F12 to release mouse" -msgstr "Stiskněte F8+F12 pro uvolnění myši" +msgid "Press %1 to release mouse" +msgstr "Stiskněte %1 pro uvolnění myši" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" +msgid "Press %1 or middle button to release mouse" +msgstr "Stiskněte %1 nebo prostřední tlačítko pro uvolnění myši" msgid "Bus" msgstr "Sběrnice" @@ -853,26 +850,14 @@ msgstr "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "Hardware není 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 "Ujistěte se, že je nainstalován libpcap a používáte síťové připojení s ním kompatibilní." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Ujistěte se, že je nainstalován %1 a používáte síťové připojení s ním kompatibilní." msgid "Invalid configuration" msgstr "Neplatná konfigurace" -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 potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." +msgid "%1 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 "%1 je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." msgid "Entering fullscreen mode" msgstr "Vstup do režimu celé obrazovky" @@ -892,8 +877,8 @@ msgstr "Neresetovat" msgid "CD-ROM images" msgstr "Obraz CD-ROM disku" -msgid "%hs Device Configuration" -msgstr "Konfigurace zařízení %hs" +msgid "%1 Device Configuration" +msgstr "Konfigurace zařízení %1" msgid "Monitor in sleep mode" msgstr "Monitor je v režimu spánku" @@ -949,8 +934,8 @@ msgstr "Resetovat" msgid "ACPI shutdown" msgstr "Vypnout skrze rozhraní ACPI" -msgid "Hard disk (%s)" -msgstr "Pevný disk (%s)" +msgid "Hard disk (%1)" +msgstr "Pevný disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 62308e9d8..6c898c25c 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -40,14 +40,11 @@ msgstr "&Größe && Position merken" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0-Kern)" @@ -718,11 +715,14 @@ msgstr "Andere Peripheriegeräte" msgid "Click to capture mouse" msgstr "Zum Einfangen des Mauszeigers bitte klicken" -msgid "Press F8+F12 to release mouse" -msgstr "Bitte F8+F12 zur Mausfreigabe drücken" +msgid "Press %1 to release mouse" +msgstr "Bitte %1 zur Mausfreigabe drücken" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" +msgid "Press %1 or middle button to release mouse" +msgstr "Bitte %1 oder die mittlere Maustaste zur Mausfreigabe drücken" + +msgid "Ctrl+End" +msgstr "Strg+Ende" msgid "Bus" msgstr "Bus" @@ -853,26 +853,14 @@ msgstr "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "Hardware nicht verfügbar" -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 "Bitte stellen Sie sicher, dass libpcap installiert ist und sie eine libpcap-kompatible Netzwerkverbindung nutzen." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Bitte stellen Sie sicher, dass %1 installiert ist und sie eine %1-kompatible Netzwerkverbindung nutzen." msgid "Invalid configuration" msgstr "Ungültige Konfiguration" -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 " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." +msgid "%1 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 "%1 wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." msgid "Entering fullscreen mode" msgstr "Vollbildmodus wird aktiviert" @@ -892,8 +880,8 @@ msgstr "Nicht zurücksetzen" msgid "CD-ROM images" msgstr "CD-ROM-Images" -msgid "%hs Device Configuration" -msgstr "%hs-Gerätekonfiguration" +msgid "%1 Device Configuration" +msgstr "%1-Gerätekonfiguration" msgid "Monitor in sleep mode" msgstr "Monitor im Standbymodus" @@ -949,8 +937,8 @@ msgstr "Hard-Reset" msgid "ACPI shutdown" msgstr "ACPI-basiertes Herunterfahren" -msgid "Hard disk (%s)" -msgstr "Festplatte (%s)" +msgid "Hard disk (%1)" +msgstr "Festplatte (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 8fb00f833..a1ee53f0a 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -40,14 +40,11 @@ msgstr "R&emember size && position" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Other peripherals" msgid "Click to capture mouse" msgstr "Click to capture mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Press F8+F12 to release mouse" +msgid "Press %1 to release mouse" +msgstr "Press %1 to release mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Press F8+F12 or middle button to release mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Press %1 or middle button to release mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Hardware not available" -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 "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." msgid "Invalid configuration" msgstr "Invalid configuration" -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 " 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." +msgid "%1 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 "%1 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." msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -892,8 +877,8 @@ msgstr "Don't reset" msgid "CD-ROM images" msgstr "CD-ROM images" -msgid "%hs Device Configuration" -msgstr "%hs Device Configuration" +msgid "%1 Device Configuration" +msgstr "%1 Device Configuration" msgid "Monitor in sleep mode" msgstr "Monitor in sleep mode" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "ACPI shutdown" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 147521bb3..854ce4bac 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -40,14 +40,11 @@ msgstr "R&emember size && position" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Other peripherals" msgid "Click to capture mouse" msgstr "Click to capture mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Press F8+F12 to release mouse" +msgid "Press %1 to release mouse" +msgstr "Press %1 to release mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Press F8+F12 or middle button to release mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Press %1 or middle button to release mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Hardware not available" -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 "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." msgid "Invalid configuration" msgstr "Invalid configuration" -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 " 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." +msgid "%1 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 "%1 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." msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -892,8 +877,8 @@ msgstr "Don't reset" msgid "CD-ROM images" msgstr "CD-ROM images" -msgid "%hs Device Configuration" -msgstr "%hs Device Configuration" +msgid "%1 Device Configuration" +msgstr "%1 Device Configuration" msgid "Monitor in sleep mode" msgstr "Monitor in sleep mode" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "ACPI shutdown" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 066a31310..f68c6926e 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -40,14 +40,11 @@ msgstr "&Recordar tamaño y posición" msgid "Re&nderer" msgstr "Re&nderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Otros periféricos" msgid "Click to capture mouse" msgstr "Haga click para capturar el ratón" -msgid "Press F8+F12 to release mouse" -msgstr "Pulse F8+F12 para liberar el ratón" +msgid "Press %1 to release mouse" +msgstr "Pulse %1 para liberar el ratón" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pulse F8+F12 o el botón central para liberar el ratón" +msgid "Press %1 or middle button to release mouse" +msgstr "Pulse %1 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Equipo 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 "Asegúrate de que libpcap está instalado y de que estás en una conexión de red compatible con libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Asegúrate de que %1 está instalado y de que estás en una conexión de red compatible con %1." msgid "Invalid configuration" msgstr "Configuración 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 " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." +msgid "%1 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 "%1 es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrando en modo pantalla completa" @@ -892,8 +877,8 @@ msgstr "No reinicializar" msgid "CD-ROM images" msgstr "Imágenes de CD-ROM" -msgid "%hs Device Configuration" -msgstr "%hs Configuración de Dispositivo" +msgid "%1 Device Configuration" +msgstr "%1 Configuración de Dispositivo" msgid "Monitor in sleep mode" msgstr "Monitor en modo ahorro" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Parada ACPI" -msgid "Hard disk (%s)" -msgstr "Disco duro (%s)" +msgid "Hard disk (%1)" +msgstr "Disco duro (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index a81857596..c34639550 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -40,14 +40,11 @@ msgstr "&Muista koko ja sijainti" msgid "Re&nderer" msgstr "&Renderöijä" -msgid "&SDL (Software)" -msgstr "&SDL (ohjelmistopohjainen)" +msgid "&Qt (Software)" +msgstr "&Qt (ohjelmistopohjainen)" -msgid "SDL (&Hardware)" -msgstr "SDL (&laitteistokiihdytetty)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Muut oheislaitteet" msgid "Click to capture mouse" msgstr "Kaappaa hiiri klikkaamalla" -msgid "Press F8+F12 to release mouse" -msgstr "Paina F8+F12 vapauttaaksesi hiiren" +msgid "Press %1 to release mouse" +msgstr "Paina %1 vapauttaaksesi hiiren" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" +msgid "Press %1 or middle button to release mouse" +msgstr "Paina %1 tai keskipainiketta vapauttaaksesi hiiren" msgid "Bus" msgstr "Väylä" @@ -853,26 +850,14 @@ msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Laitteisto ei ole saatavilla" -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 "Varmista, että libpcap on asennettu ja että verkkoyhteytesi on libpcap-yhteensopiva." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Varmista, että %1 on asennettu ja että verkkoyhteytesi on %1-yhteensopiva." msgid "Invalid configuration" msgstr "Virheelliset määritykset" -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 " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." +msgid "%1 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 "%1 vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." msgid "Entering fullscreen mode" msgstr "Siirrytään koko näytön tilaan" @@ -892,8 +877,8 @@ msgstr "Älä käynnistä uudelleen" msgid "CD-ROM images" msgstr "CD-ROM-levykuvat" -msgid "%hs Device Configuration" -msgstr "%hs - Laitteen määritykset" +msgid "%1 Device Configuration" +msgstr "%1 - Laitteen määritykset" msgid "Monitor in sleep mode" msgstr "Näyttö lepotilassa" @@ -949,8 +934,8 @@ msgstr "Kylmä uudelleenkäynnistys" msgid "ACPI shutdown" msgstr "ACPI-sammutus" -msgid "Hard disk (%s)" -msgstr "Kiintolevy (%s)" +msgid "Hard disk (%1)" +msgstr "Kiintolevy (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 4e9b94d33..3fe8faa2e 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -40,14 +40,11 @@ msgstr "S&auvegarder taille && position" msgid "Re&nderer" msgstr "Moteur de &rendu vidéo" -msgid "&SDL (Software)" -msgstr "&SDL (Logiciel)" +msgid "&Qt (Software)" +msgstr "&Qt (Logiciel)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Materiel)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Autres périfériques" msgid "Click to capture mouse" msgstr "Cliquer pour capturer la souris" -msgid "Press F8+F12 to release mouse" -msgstr "Appuyer sur F8+F12 pour libérer la souris" +msgid "Press %1 to release mouse" +msgstr "Appuyer sur %1 pour libérer la souris" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" +msgid "Press %1 or middle button to release mouse" +msgstr "Appuyer sur %1 ou le bouton central pour libérer la souris" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), R msgid "Hardware not available" msgstr "Matériel non 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 "Assurez-vous que libpcap est installé et que vou utilisez une connexion réseau compatible avec libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Assurez-vous que %1 est installé et que vou utilisez une connexion réseau compatible avec %1." msgid "Invalid configuration" msgstr "Configuration non valide" -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 " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." +msgid "%1 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 "%1 est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrer en mode plein écran" @@ -892,8 +877,8 @@ msgstr "Ne pas réinitialiser" msgid "CD-ROM images" msgstr "Images CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuration du dispositif %hs" +msgid "%1 Device Configuration" +msgstr "Configuration du dispositif %1" msgid "Monitor in sleep mode" msgstr "Moniteur en mode veille" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Arrêt ACPI" -msgid "Hard disk (%s)" -msgstr "Disque dur (%s)" +msgid "Hard disk (%1)" +msgstr "Disque dur (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 0255a8280..db8a157cd 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -40,14 +40,11 @@ msgstr "&Zapamtite veličinu i položaj" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Softver)" +msgid "&Qt (Software)" +msgstr "&Qt (Softver)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardver)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 jezgra)" @@ -718,11 +715,11 @@ msgstr "Ostali periferni uređaji" msgid "Click to capture mouse" msgstr "Kliknite da uhvatite miš" -msgid "Press F8+F12 to release mouse" -msgstr "Pritisnite F8+F12 za otpustanje miša" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za otpustanje miša" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ili srednji gumb miša za otpuštanje miša" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867 msgid "Hardware not available" msgstr "Hardver nije dostupan" -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 "Provjerite je li libpcap instaliran i jeste li na mreži, kompadibilnoj s libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Provjerite je li %1 instaliran i jeste li na mreži, kompadibilnoj s %1." msgid "Invalid configuration" msgstr "Nevažeća konfiguracija" -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 potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." +msgid "%1 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 "%1 je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." msgid "Entering fullscreen mode" msgstr "Ulazim u cijelozaslonski način" @@ -892,8 +877,8 @@ msgstr "Ne resetiraj" msgid "CD-ROM images" msgstr "CD-ROM slike" -msgid "%hs Device Configuration" -msgstr "Konfiguracija uređaja %hs " +msgid "%1 Device Configuration" +msgstr "Konfiguracija uređaja %1" msgid "Monitor in sleep mode" msgstr "Ekran u stanju mirovanja" @@ -949,8 +934,8 @@ msgstr "Ponovno pokretanje" msgid "ACPI shutdown" msgstr "ACPI bazirano gašenje" -msgid "Hard disk (%s)" -msgstr "Tvrdi disk (%s)" +msgid "Hard disk (%1)" +msgstr "Tvrdi disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index e5225dbbb..679502f00 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -40,14 +40,11 @@ msgstr "Méret és pozíció &megjegyzése" msgid "Re&nderer" msgstr "&Megjelenítő" -msgid "&SDL (Software)" -msgstr "&SDL (Szoftveres)" +msgid "&Qt (Software)" +msgstr "&Qt (Szoftveres)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardveres)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Egyéb perifériák" msgid "Click to capture mouse" msgstr "Kattintson az egér elfogásához" -msgid "Press F8+F12 to release mouse" -msgstr "Nyomja meg az F8+F12-t az egér elengédéséhez" +msgid "Press %1 to release mouse" +msgstr "Nyomja meg az %1-t az egér elengédéséhez" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" +msgid "Press %1 or middle button to release mouse" +msgstr "Nyomja meg az %1-t vagy a középső gombot az egér elengédéséhez" msgid "Bus" msgstr "Busz" @@ -853,26 +850,14 @@ msgstr "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler) msgid "Hardware not available" msgstr "Hardver nem elérhető" -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 "Győződjön meg hogy a(z) libpcap telepítve van és jelenleg a libpcap-kompatibilis kapcsolatot használja." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Győződjön meg hogy a(z) %1 telepítve van és jelenleg a %1-kompatibilis kapcsolatot használja." msgid "Invalid configuration" msgstr "Érvénytelen konfiguráció" -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 " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." +msgid "%1 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 "%1 szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." msgid "Entering fullscreen mode" msgstr "Teljes képernyős módra váltás" @@ -892,8 +877,8 @@ msgstr "Ne indítsa újra" msgid "CD-ROM images" msgstr "CD-ROM-képek" -msgid "%hs Device Configuration" -msgstr "%hs eszközkonfiguráció" +msgid "%1 Device Configuration" +msgstr "%1 eszközkonfiguráció" msgid "Monitor in sleep mode" msgstr "Képernyő alvó módban" @@ -949,8 +934,8 @@ msgstr "Hardveres újraindítás" msgid "ACPI shutdown" msgstr "ACPI leállítás" -msgid "Hard disk (%s)" -msgstr "Merevlemez (%s)" +msgid "Hard disk (%1)" +msgstr "Merevlemez (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 43ece2315..dfb11fb59 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -40,14 +40,11 @@ msgstr "R&icorda dimensioni e posizione" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Altre periferiche" msgid "Click to capture mouse" msgstr "Fare clic per catturare mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Premi F8+F12 per rilasciare il mouse" +msgid "Press %1 to release mouse" +msgstr "Premi %1 per rilasciare il mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Premi F8+F12 o pulsante centrale per rilasciare il mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Premi %1 o pulsante centrale per rilasciare il mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), Richa msgid "Hardware not available" msgstr "Hardware non disponibile" -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 "Controllare se libpcap è installato e che tu sia connesso ad una connessione libpcap compatibile." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Controllare se %1 è installato e che tu sia connesso ad una connessione %1 compatibile." msgid "Invalid configuration" msgstr "Configurazione invalida" -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 " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" +msgid "%1 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 "%1 è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" msgid "Entering fullscreen mode" msgstr "Entrando nella modalità schermo intero" @@ -892,8 +877,8 @@ msgstr "Non riavviare" msgid "CD-ROM images" msgstr "Immagini CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configurazione del dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configurazione del dispositivo %1" msgid "Monitor in sleep mode" msgstr "Monitor in modalità riposo" @@ -949,8 +934,8 @@ msgstr "Riavvia" msgid "ACPI shutdown" msgstr "Arresto ACPI" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 971bbd29f..c2b0a3d71 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -40,14 +40,11 @@ msgstr "ウィンドウのサイズと位置を保存(&E)" msgid "Re&nderer" msgstr "レンダラー(&N)" -msgid "&SDL (Software)" -msgstr "SDL (ソフトウェア)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (ソフトウェア)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (ハードウェア)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "他の周辺デバイス" msgid "Click to capture mouse" msgstr "左クリックでマウスをキャプチャします" -msgid "Press F8+F12 to release mouse" -msgstr "F8+F12キーでマウスを解放します" +msgid "Press %1 to release mouse" +msgstr "%1キーでマウスを解放します" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "F8+F12キーまたは中クリックでマウスを解放します" +msgid "Press %1 or middle button to release mouse" +msgstr "%1キーまたは中クリックでマウスを解放します" msgid "Bus" msgstr "バス" @@ -853,26 +850,14 @@ msgstr "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBatt msgid "Hardware not available" msgstr "ハードウェアが利用できません" -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 "がインストールされてるか、libpcapに対応したネットワークに接続されてるか確認してください。" +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "がインストールされてるか、%1に対応したネットワークに接続されてるか確認してください。" msgid "Invalid configuration" msgstr "不正な設定です" -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 "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" +msgid "%1 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 "PostScriptファイルをPDFに自動変換するには%1が必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" msgid "Entering fullscreen mode" msgstr "全画面モードを入力" @@ -892,8 +877,8 @@ msgstr "リセットしない" msgid "CD-ROM images" msgstr "CD-ROMイメージ" -msgid "%hs Device Configuration" -msgstr "%hs のデバイス設定" +msgid "%1 Device Configuration" +msgstr "%1 のデバイス設定" msgid "Monitor in sleep mode" msgstr "モニターのスリープモード" @@ -949,8 +934,8 @@ msgstr "ハードリセット" msgid "ACPI shutdown" msgstr "ACPIシャットダウン" -msgid "Hard disk (%s)" -msgstr "ハードディスク (%s)" +msgid "Hard disk (%1)" +msgstr "ハードディスク (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index ea6e196fe..99e74e880 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -40,14 +40,11 @@ msgstr "창 크기와 위치를 기억하기(&E)" msgid "Re&nderer" msgstr "렌더러(&N)" -msgid "&SDL (Software)" -msgstr "SDL (소프트웨어)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (소프트웨어)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (하드웨어)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "기타 주변기기" msgid "Click to capture mouse" msgstr "이 창을 클릭하면 마우스를 사용합니다" -msgid "Press F8+F12 to release mouse" -msgstr "F12+F8키를 누르면 마우스를 해제합니다" +msgid "Press %1 to release mouse" +msgstr "%1키를 누르면 마우스를 해제합니다" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" +msgid "Press %1 or middle button to release mouse" +msgstr "%1키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" msgid "Bus" msgstr "버스" @@ -853,26 +850,14 @@ msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "하드웨어를 이용할 수 없습니다" -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 "이 설치되었는지 libpcap에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "이 설치되었는지 %1에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." msgid "Invalid configuration" msgstr "올바르지 않은 설정입니다" -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 "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." +msgid "%1 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 "%1은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." msgid "Entering fullscreen mode" msgstr "전체 화면으로 전환" @@ -892,8 +877,8 @@ msgstr "재시작 안함" msgid "CD-ROM images" msgstr "CD-ROM 이미지" -msgid "%hs Device Configuration" -msgstr "%hs 장치 설정" +msgid "%1 Device Configuration" +msgstr "%1 장치 설정" msgid "Monitor in sleep mode" msgstr "모니터 절전 모드" @@ -949,8 +934,8 @@ msgstr "재시작" msgid "ACPI shutdown" msgstr "ACPI 종료" -msgid "Hard disk (%s)" -msgstr "하드 디스크 (%s)" +msgid "Hard disk (%1)" +msgstr "하드 디스크 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index c6a70d905..b67946434 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -40,14 +40,11 @@ msgstr "P&amiętaj rozmiar &i pozycję" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Inne urządzenia peryferyjne" msgid "Click to capture mouse" msgstr "Kliknij w celu przechwycenia myszy" -msgid "Press F8+F12 to release mouse" -msgstr "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" +msgid "Press %1 to release mouse" +msgstr "Naciśnij klawisze %1 w celu uwolnienia myszy" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" +msgid "Press %1 or middle button to release mouse" +msgstr "Naciśnij klawisze %1 lub środkowy przycisk w celu uwolnienia myszy" msgid "Bus" msgstr "Magistrala" @@ -853,26 +850,14 @@ msgstr "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Sprzęt niedostępny" -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 "Sprawdź, czy libpcap jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Sprawdź, czy %1 jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z %1." msgid "Invalid configuration" msgstr "Nieprawidłowa konfiguracja" -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 " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." +msgid "%1 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 "%1 jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Przechodzenie do trybu pełnoekranowego" @@ -892,8 +877,8 @@ msgstr "Nie przywracaj" msgid "CD-ROM images" msgstr "Obrazy CD-ROM" -msgid "%hs Device Configuration" -msgstr "Konfiguracja urządzenia %hs" +msgid "%1 Device Configuration" +msgstr "Konfiguracja urządzenia %1" msgid "Monitor in sleep mode" msgstr "Monitor w trybie czuwania" @@ -949,8 +934,8 @@ msgstr "Twardy reset" msgid "ACPI shutdown" msgstr "Wyłączenie ACPI" -msgid "Hard disk (%s)" -msgstr "Dysk twardy (%s)" +msgid "Hard disk (%1)" +msgstr "Dysk twardy (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 45d8a8530..689841312 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -40,14 +40,11 @@ msgstr "&Lembrar tamanho e posição" msgid "Re&nderer" msgstr "&Renderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Núcleo 3.0)" @@ -718,11 +715,11 @@ msgstr "Outros periféricos" msgid "Click to capture mouse" msgstr "Clique para capturar o mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Aperte F8+F12 para liberar o mouse" +msgid "Press %1 to release mouse" +msgstr "Aperte %1 para liberar o mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Aperte F8+F12 ou botão do meio para liberar o mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Aperte %1 ou botão do meio para liberar o mouse" msgid "Bus" msgstr "Barramento" @@ -853,26 +850,14 @@ msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Hardware não disponível" -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 "Certifique-se de que libpcap esteja instalado e que você tenha uma conexão de rede compatível com libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Certifique-se de que %1 esteja instalado e que você tenha uma conexão de rede compatível com %1." msgid "Invalid configuration" msgstr "Configuração 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 " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." +msgid "%1 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 "%1 é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrando no modo de tela cheia" @@ -892,8 +877,8 @@ msgstr "Não reiniciar" msgid "CD-ROM images" msgstr "Imagens de CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuração do dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configuração do dispositivo %1" msgid "Monitor in sleep mode" msgstr "Monitor em modo de suspensão" @@ -949,8 +934,8 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Desligamento por ACPI" -msgid "Hard disk (%s)" -msgstr "Disco rígido (%s)" +msgid "Hard disk (%1)" +msgstr "Disco rígido (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 156f63926..adfc05391 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -40,14 +40,11 @@ msgstr "&Lembrar tamanho e posição" msgid "Re&nderer" msgstr "&Renderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Núcleo 3.0)" @@ -718,11 +715,11 @@ msgstr "Outros dispositivos" msgid "Click to capture mouse" msgstr "Clique para capturar o rato" -msgid "Press F8+F12 to release mouse" -msgstr "Pressione F8+F12 para soltar o rato" +msgid "Press %1 to release mouse" +msgstr "Pressione %1 para soltar o rato" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pressione F8+F12 ou tecla média para soltar o rato" +msgid "Press %1 or middle button to release mouse" +msgstr "Pressione %1 ou tecla média para soltar o rato" msgid "Bus" msgstr "Barramento" @@ -853,26 +850,14 @@ msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Hardware não disponível" -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 "Certifique-se de que a biblioteca libpcap está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Certifique-se de que a biblioteca %1 está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca %1." msgid "Invalid configuration" msgstr "Configuração 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 " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." +msgid "%1 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 "%1 é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "A entrar no modo de ecrã cheio" @@ -892,8 +877,8 @@ msgstr "Não reiniciar" msgid "CD-ROM images" msgstr "Imagens CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuração de dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configuração de dispositivo %1" msgid "Monitor in sleep mode" msgstr "Ecrã em modo de sono" @@ -949,8 +934,8 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Encerramento ACPI" -msgid "Hard disk (%s)" -msgstr "Disco rígido (%s)" +msgid "Hard disk (%1)" +msgstr "Disco rígido (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 41cad4eda..96da04710 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -43,14 +43,11 @@ msgstr "&Запомнить размер и положение" msgid "Re&nderer" msgstr "&Рендеринг" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0)" @@ -808,11 +805,11 @@ msgstr "Другая периферия" msgid "Click to capture mouse" msgstr "Щёлкните мышью для захвата курсора" -msgid "Press F8+F12 to release mouse" -msgstr "Нажмите F8+F12 чтобы освободить курсор" +msgid "Press %1 to release mouse" +msgstr "Нажмите %1, чтобы освободить курсор" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Нажмите %1 или среднюю кнопку мыши, чтобы освободить курсор" msgid "Bus" msgstr "Шина" @@ -943,26 +940,14 @@ msgstr "Эмулятор старых компьютеров\n\nАвторы: Mi msgid "Hardware not available" msgstr "Оборудование недоступно" -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 "Убедитесь, что libpcap установлен и ваше сетевое соединение, совместимо с libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Убедитесь, что %1 установлен и ваше сетевое соединение совместимо с %1." msgid "Invalid configuration" msgstr "Недопустимая конфигурация" -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 " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." +msgid "%1 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 "Для автоматического преобразования файлов PostScript в PDF требуется %1.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Вход в полноэкранный режим" @@ -982,8 +967,8 @@ msgstr "Не перезагружать" msgid "CD-ROM images" msgstr "Образы CD-ROM" -msgid "%hs Device Configuration" -msgstr "Конфигурация устройства %hs" +msgid "%1 Device Configuration" +msgstr "Конфигурация устройства %1" msgid "Monitor in sleep mode" msgstr "Монитор в спящем режиме" @@ -1039,8 +1024,8 @@ msgstr "Холодная перезагрузка" msgid "ACPI shutdown" msgstr "Сигнал завершения ACPI" -msgid "Hard disk (%s)" -msgstr "Жёсткий диск (%s)" +msgid "Hard disk (%1)" +msgstr "Жёсткий диск (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index a6d13b95b..c22445a19 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -40,14 +40,11 @@ msgstr "&Pamätať si veľkosť a polohu" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ 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 %1 to release mouse" +msgstr "Stlačte %1 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 "Press %1 or middle button to release mouse" +msgstr "Stlačte %1 alebo prostredné tlačidlo na uvoľnenie myši" msgid "Bus" msgstr "Zbernica" @@ -853,26 +850,14 @@ msgstr "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), Richa 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 "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Uistite sa, že je nainštalovaný %1 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 "%1 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 "%1 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" @@ -892,8 +877,8 @@ msgstr "Neresetovať" msgid "CD-ROM images" msgstr "Obraz CD-ROM disku" -msgid "%hs Device Configuration" -msgstr "Konfigurácia zariadenia %hs" +msgid "%1 Device Configuration" +msgstr "Konfigurácia zariadenia %1" msgid "Monitor in sleep mode" msgstr "Monitor je v režime spánku" @@ -949,8 +934,8 @@ msgstr "Resetovať" msgid "ACPI shutdown" msgstr "Vypnúť cez rozhranie ACPI" -msgid "Hard disk (%s)" -msgstr "Pevný disk (%s)" +msgid "Hard disk (%1)" +msgstr "Pevný disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 93941ffe8..c32c6c754 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -40,14 +40,11 @@ msgstr "&Zapomni si velikost in položaj" msgid "Re&nderer" msgstr "&Upodabljanje" -msgid "&SDL (Software)" -msgstr "&SDL (programsko)" +msgid "&Qt (Software)" +msgstr "&Qt (programsko)" -msgid "SDL (&Hardware)" -msgstr "SDL (s&trojno)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Jedro 3.0)" @@ -718,11 +715,11 @@ msgstr "Druga periferija" msgid "Click to capture mouse" msgstr "Kliknite za zajem miške" -msgid "Press F8+F12 to release mouse" -msgstr "Pritisnite F8+F12 za izpust miške" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za izpust miške" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pritisnite F8+F12 ali srednji gumb za izpust miške" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ali srednji gumb za izpust miške" msgid "Bus" msgstr "Vodilo" @@ -853,26 +850,14 @@ msgstr "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), Richar msgid "Hardware not available" msgstr "Strojna oprema ni na voljo" -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 "Prepičajte se, da je nameščen libpcap in da ste na omrežni povezavi, združljivi z " +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Prepičajte se, da je nameščen %1 in da ste na omrežni povezavi, združljivi z libpcap." msgid "Invalid configuration" msgstr "Neveljavna konfiguracija" -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 potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." +msgid "%1 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 "%1 je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." msgid "Entering fullscreen mode" msgstr "Preklapljam v celozaslonski način" @@ -892,8 +877,8 @@ msgstr "Ne resetiraj" msgid "CD-ROM images" msgstr "Slike CD-ROM" -msgid "%hs Device Configuration" -msgstr "Konfiguracija naprave %hs" +msgid "%1 Device Configuration" +msgstr "Konfiguracija naprave %1" msgid "Monitor in sleep mode" msgstr "Zaslon v načinu spanja" @@ -949,8 +934,8 @@ msgstr "Ponovni zagon" msgid "ACPI shutdown" msgstr "Zaustavitev ACPI" -msgid "Hard disk (%s)" -msgstr "Trdi disk (%s)" +msgid "Hard disk (%1)" +msgstr "Trdi disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index c65f6077c..a1ce42b38 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -40,14 +40,11 @@ msgstr "&Pencere boyut ve pozisyonunu hatırla" msgid "Re&nderer" msgstr "&İşleyici" -msgid "&SDL (Software)" -msgstr "&SDL (Yazılım)" +msgid "&Qt (Software)" +msgstr "&Qt (Yazılım)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Donanım)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Diğer cihazlar" msgid "Click to capture mouse" msgstr "Farenin yakalanması için tıklayın" -msgid "Press F8+F12 to release mouse" -msgstr "Farenin bırakılması için F8+F12 tuşlarına basın" +msgid "Press %1 to release mouse" +msgstr "Farenin bırakılması için %1 tuşlarına basın" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" +msgid "Press %1 or middle button to release mouse" +msgstr "Farenin bırakılması için %1 veya farenin orta tuşuna basın" msgid "Bus" msgstr "Veri yolu" @@ -853,26 +850,14 @@ msgstr "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), Ri msgid "Hardware not available" msgstr "Donanım mevcut değil" -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 "libpcap kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulunduğunuzdan emin olun." +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "%1 kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulunduğunuzdan emin olun." msgid "Invalid configuration" msgstr "Geçersiz konfigürasyon" -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 " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." +msgid "%1 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 "%1 PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." msgid "Entering fullscreen mode" msgstr "Tam ekran moduna geçiliyor" @@ -892,8 +877,8 @@ msgstr "Yeniden başlatma" msgid "CD-ROM images" msgstr "CD-ROM imajları" -msgid "%hs Device Configuration" -msgstr "%hs Cihaz Konfigürasyonu" +msgid "%1 Device Configuration" +msgstr "%1 Cihaz Konfigürasyonu" msgid "Monitor in sleep mode" msgstr "Monitör uyku modunda" @@ -949,8 +934,8 @@ msgstr "Makineyi yeniden başlat" msgid "ACPI shutdown" msgstr "ACPI kapatma" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index f7a819a92..0dc666c0d 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -40,14 +40,11 @@ msgstr "&Запам'ятати розмір і становище" msgid "Re&nderer" msgstr "&Рендеринг" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0)" @@ -718,11 +715,11 @@ msgstr "Інша периферія" msgid "Click to capture mouse" msgstr "Клацніть мишею для захвату курсора" -msgid "Press F8+F12 to release mouse" -msgstr "Натисніть F8+F12, щоб звільнити курсор" +msgid "Press %1 to release mouse" +msgstr "Натисніть %1, щоб звільнити курсор" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Натисніть %1 або середню кнопку миші, щоб звільнити курсор" msgid "Bus" msgstr "Шина" @@ -853,26 +850,14 @@ msgstr "Емулятор старих комп'ютерів\n\nАвтори: Mir msgid "Hardware not available" msgstr "Обладнання недоступне" -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 "Переконайтесь, що libpcap встановлений і ваше мережеве з'єднання, сумісне з libpcap." +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Переконайтесь, що %1 встановлений і ваше мережеве з'єднання, сумісне з libpcap." msgid "Invalid configuration" msgstr "Неприпустима конфігурація" -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 " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." +msgid "%1 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 "%1 потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Вхід у повноекранний режим" @@ -892,8 +877,8 @@ msgstr "Не перезавантажувати" msgid "CD-ROM images" msgstr "Образи CD-ROM" -msgid "%hs Device Configuration" -msgstr "Конфігурація пристрою %hs" +msgid "%1 Device Configuration" +msgstr "Конфігурація пристрою %1" msgid "Monitor in sleep mode" msgstr "Монітор у сплячому режимі" @@ -949,8 +934,8 @@ msgstr "Холодне перезавантаження" msgid "ACPI shutdown" msgstr "Сигнал завершення ACPI" -msgid "Hard disk (%s)" -msgstr "Жорсткий диск (%s)" +msgid "Hard disk (%1)" +msgstr "Жорсткий диск (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 5c3fbb54f..dea46160e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -40,14 +40,11 @@ msgstr "记住窗口大小和位置(&E)" msgid "Re&nderer" msgstr "渲染器(&N)" -msgid "&SDL (Software)" -msgstr "SDL (软件)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (软件)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (硬件)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "其他外围设备" msgid "Click to capture mouse" msgstr "单击窗口捕捉鼠标" -msgid "Press F8+F12 to release mouse" -msgstr "按下 F8+F12 释放鼠标" +msgid "Press %1 to release mouse" +msgstr "按下 %1 释放鼠标" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "按下 F8+F12 或鼠标中键释放鼠标" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或鼠标中键释放鼠标" msgid "Bus" msgstr "总线" @@ -853,26 +850,14 @@ msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、Richa msgid "Hardware not available" msgstr "硬件不可用" -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 "请确认 libpcap 已安装且使用兼容 libpcap 的网络连接。" +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "请确认 %1 已安装且使用兼容 libpcap 的网络连接。" msgid "Invalid configuration" msgstr "无效配置" -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 " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" +msgid "%1 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 "%1 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" msgid "Entering fullscreen mode" msgstr "正在进入全屏模式" @@ -892,8 +877,8 @@ msgstr "不重置" msgid "CD-ROM images" msgstr "光盘映像" -msgid "%hs Device Configuration" -msgstr "%hs 设备配置" +msgid "%1 Device Configuration" +msgstr "%1 设备配置" msgid "Monitor in sleep mode" msgstr "显示器处在睡眠状态" @@ -949,8 +934,8 @@ msgstr "硬重置" msgid "ACPI shutdown" msgstr "ACPI 关机" -msgid "Hard disk (%s)" -msgstr "硬盘 (%s)" +msgid "Hard disk (%1)" +msgstr "硬盘 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 927eb2d85..9392ce717 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -40,14 +40,11 @@ msgstr "記住視窗大小和位置(&E)" msgid "Re&nderer" msgstr "渲染器(&N)" -msgid "&SDL (Software)" -msgstr "SDL (軟體)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (軟體)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (硬體)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "其他周邊裝置" msgid "Click to capture mouse" msgstr "點擊視窗捕捉滑鼠" -msgid "Press F8+F12 to release mouse" -msgstr "按下 F8+F12 釋放滑鼠" +msgid "Press %1 to release mouse" +msgstr "按下 %1 釋放滑鼠" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "按下 F8+F12 或滑鼠中鍵釋放滑鼠" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或滑鼠中鍵釋放滑鼠" msgid "Bus" msgstr "匯流排" @@ -853,26 +850,14 @@ msgstr "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG msgid "Hardware not available" msgstr "硬體不可用" -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 "請確認 libpcap 已安裝且使用相容 libpcap 的網路連線。" +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "請確認 %1 已安裝且使用相容 libpcap 的網路連線。" msgid "Invalid configuration" msgstr "無效設定" -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 " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" +msgid "%1 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 "%1 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" msgid "Entering fullscreen mode" msgstr "正在進入全螢幕模式" @@ -892,8 +877,8 @@ msgstr "不重設" msgid "CD-ROM images" msgstr "光碟映像" -msgid "%hs Device Configuration" -msgstr "%hs 裝置設定" +msgid "%1 Device Configuration" +msgstr "%1 裝置設定" msgid "Monitor in sleep mode" msgstr "顯示器處在睡眠狀態" @@ -949,8 +934,8 @@ msgstr "硬重設" msgid "ACPI shutdown" msgstr "ACPI 關機" -msgid "Hard disk (%s)" -msgstr "硬碟 (%s)" +msgid "Hard disk (%1)" +msgstr "硬碟 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 59ea960f8..dee487657 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -596,21 +596,21 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_MFM].label = std::make_unique(); d->hdds[HDD_BUS_MFM].setActive(false); d->hdds[HDD_BUS_MFM].refresh(); - d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%s)").replace("%s", "MFM/RLL")); + d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%1)").arg("MFM/RLL")); sbar->addWidget(d->hdds[HDD_BUS_MFM].label.get()); } if ((has_esdi || (hdc_name.left(4) == QStringLiteral("esdi"))) && (c_esdi > 0)) { d->hdds[HDD_BUS_ESDI].label = std::make_unique(); d->hdds[HDD_BUS_ESDI].setActive(false); d->hdds[HDD_BUS_ESDI].refresh(); - d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ESDI")); + d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%1)").arg("ESDI")); sbar->addWidget(d->hdds[HDD_BUS_ESDI].label.get()); } if ((has_xta || (hdc_name.left(3) == QStringLiteral("xta"))) && (c_xta > 0)) { d->hdds[HDD_BUS_XTA].label = std::make_unique(); d->hdds[HDD_BUS_XTA].setActive(false); d->hdds[HDD_BUS_XTA].refresh(); - d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); + d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%1)").arg("XTA")); sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); } if (hasIDE() || (hdc_name.left(5) == QStringLiteral("xtide")) || @@ -620,14 +620,14 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_IDE].label = std::make_unique(); d->hdds[HDD_BUS_IDE].setActive(false); d->hdds[HDD_BUS_IDE].refresh(); - d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); + d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%1)").arg("IDE")); sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); } if (c_atapi > 0) { d->hdds[HDD_BUS_ATAPI].label = std::make_unique(); d->hdds[HDD_BUS_ATAPI].setActive(false); d->hdds[HDD_BUS_ATAPI].refresh(); - d->hdds[HDD_BUS_ATAPI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ATAPI")); + d->hdds[HDD_BUS_ATAPI].label->setToolTip(tr("Hard disk (%1)").arg("ATAPI")); sbar->addWidget(d->hdds[HDD_BUS_ATAPI].label.get()); } } @@ -638,7 +638,7 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); - d->hdds[HDD_BUS_SCSI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "SCSI")); + d->hdds[HDD_BUS_SCSI].label->setToolTip(tr("Hard disk (%1)").arg("SCSI")); sbar->addWidget(d->hdds[HDD_BUS_SCSI].label.get()); } diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 079906753..c7cc76ffe 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,14 +581,16 @@ c16stombs(char dst[], const uint16_t src[], int len) #ifdef _WIN32 # if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) -# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GS "gsdll64.dll" # else -# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_GS "gsdll32.dll" # endif +# define LIB_NAME_PCAP "Npcap" # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" -# define MOUSE_CAPTURE_KEYSEQ "CTRL-END" +# define LIB_NAME_PCAP "libpcap" +# define MOUSE_CAPTURE_KEYSEQ "Ctrl+End" #endif QMap ProgSettings::translatedstrings; @@ -598,14 +600,15 @@ ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press %1 to release mouse").arg(QCoreApplication::translate("", MOUSE_CAPTURE_KEYSEQ)).toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press %1 or middle button to release mouse").arg(QCoreApplication::translate("", MOUSE_CAPTURE_KEYSEQ)).toStdWString(); translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[STRING_PCAP_ERROR_INVALID_DEVICE] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure %1 is installed and that you are on a %1-compatible network connection.").arg(LIB_NAME_PCAP).toStdWString(); translatedstrings[STRING_GHOSTSCRIPT_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = QCoreApplication::translate("", "%1 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.").arg(LIB_NAME_GS).toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); @@ -613,13 +616,6 @@ ProgSettings::reloadStrings() translatedstrings[STRING_MONITOR_SLEEP] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); translatedstrings[STRING_NET_ERROR] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); translatedstrings[STRING_NET_ERROR_DESC] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); - - auto gsstr = QCoreApplication::translate("", " 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."); - if (gsstr.contains("libgs")) { - gsstr.replace("libgs", LIB_NAME_GS); - } else - gsstr.prepend(LIB_NAME_GS); - translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = gsstr.toStdWString(); } wchar_t * diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index d41f267df..642b2002d 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -40,12 +40,6 @@ public: sourceText = "Begin trace\tCtrl+T"; if (strcmp(sourceText, "End trace") == 0) sourceText = "End trace\tCtrl+T"; - if (strcmp(sourceText, "&Qt (Software)") == 0) { - QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n); - finalstr.replace("SDL", "Qt"); - finalstr.replace("(&S)", "(&Q)"); - return finalstr; - } QString finalstr = QTranslator::translate("", sourceText, disambiguation, n); #ifdef Q_OS_MACOS if (finalstr.contains('\t')) From 8a27a77aa1443f42c733f99c71e795bf3c5f7a65 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 18:53:29 +0500 Subject: [PATCH 278/690] Translations: Purge more unused strings --- src/qt/languages/ca-ES.po | 39 --------------------------------------- src/qt/languages/cs-CZ.po | 39 --------------------------------------- src/qt/languages/de-DE.po | 39 --------------------------------------- src/qt/languages/en-GB.po | 39 --------------------------------------- src/qt/languages/en-US.po | 39 --------------------------------------- src/qt/languages/es-ES.po | 39 --------------------------------------- src/qt/languages/fi-FI.po | 39 --------------------------------------- src/qt/languages/fr-FR.po | 39 --------------------------------------- src/qt/languages/hr-HR.po | 39 --------------------------------------- src/qt/languages/hu-HU.po | 39 --------------------------------------- src/qt/languages/it-IT.po | 39 --------------------------------------- src/qt/languages/ja-JP.po | 39 --------------------------------------- src/qt/languages/ko-KR.po | 39 --------------------------------------- src/qt/languages/pl-PL.po | 39 --------------------------------------- src/qt/languages/pt-BR.po | 39 --------------------------------------- src/qt/languages/pt-PT.po | 39 --------------------------------------- src/qt/languages/ru-RU.po | 39 --------------------------------------- src/qt/languages/sk-SK.po | 39 --------------------------------------- src/qt/languages/sl-SI.po | 39 --------------------------------------- src/qt/languages/tr-TR.po | 39 --------------------------------------- src/qt/languages/uk-UA.po | 39 --------------------------------------- src/qt/languages/zh-CN.po | 39 --------------------------------------- src/qt/languages/zh-TW.po | 39 --------------------------------------- 23 files changed, 897 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index ff69d11a7..3cde2ff11 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -586,9 +586,6 @@ msgstr "Comprovar BPB" msgid "CD-ROM drives:" msgstr "Unitats de CD-ROM:" -msgid "Earlier drive" -msgstr "Unitat anterior" - msgid "MO drives:" msgstr "Unitats MO:" @@ -781,15 +778,6 @@ 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)" @@ -937,12 +925,6 @@ msgstr "Apagada ACPI" msgid "Hard disk (%1)" msgstr "Disc dur (%1)" -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" @@ -1048,9 +1030,6 @@ 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" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index f89521fdf..717a4f488 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -586,9 +586,6 @@ msgstr "Kontrola BPB" msgid "CD-ROM drives:" msgstr "Mechaniky CD-ROM:" -msgid "Earlier drive" -msgstr "Časná mechanika" - msgid "MO drives:" msgstr "Magnetooptické mechaniky:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Žadné" -msgid "Unable to load keyboard accelerators." -msgstr "Nebylo možné nahrát klávesnicové zkratky." - -msgid "Unable to register raw input." -msgstr "Nebylo možné zaregistrovat raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Vypnout skrze rozhraní ACPI" msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "CD-ROM mechaniky pro rozhraní MFM/RLL nebo ESDI nikdy neexistovaly" @@ -1048,9 +1030,6 @@ msgstr "Časová razítka nadřazeného a podřazeného disku nesouhlasí" msgid "Could not fix VHD timestamp." msgstr "Nebylo možné opravit časové razítko VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 6c898c25c..c5e5e78aa 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -586,9 +586,6 @@ msgstr "BPB überprüfen" msgid "CD-ROM drives:" msgstr "CD-ROM-Laufwerke:" -msgid "Earlier drive" -msgstr "Früheres Laufwerk" - msgid "MO drives:" msgstr "MO-Laufwerke:" @@ -784,15 +781,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ohne" -msgid "Unable to load keyboard accelerators." -msgstr "Tastaturbeschleuniger konnten nicht geladen werden." - -msgid "Unable to register raw input." -msgstr "Roheingaben konnten nicht registriert werden." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -940,12 +928,6 @@ msgstr "ACPI-basiertes Herunterfahren" msgid "Hard disk (%1)" msgstr "Festplatte (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" @@ -1051,9 +1033,6 @@ msgstr "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" msgid "Could not fix VHD timestamp." msgstr "Der Zeitstempel der VHD konnte nicht korrigiert werden." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1069,24 +1048,6 @@ 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" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index a1ee53f0a..8e22289b8 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -586,9 +586,6 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" -msgid "Earlier drive" -msgstr "Earlier drive" - msgid "MO drives:" msgstr "MO drives:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "None" -msgid "Unable to load keyboard accelerators." -msgstr "Unable to load keyboard accelerators." - -msgid "Unable to register raw input." -msgstr "Unable to register raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI shutdown" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL or ESDI CD-ROM drives never existed" @@ -1048,9 +1030,6 @@ msgstr "Parent and child disk timestamps do not match" msgid "Could not fix VHD timestamp." msgstr "Could not fix VHD timestamp." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 854ce4bac..8298ba0e3 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -586,9 +586,6 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" -msgid "Earlier drive" -msgstr "Earlier drive" - msgid "MO drives:" msgstr "MO drives:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "None" -msgid "Unable to load keyboard accelerators." -msgstr "Unable to load keyboard accelerators." - -msgid "Unable to register raw input." -msgstr "Unable to register raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI shutdown" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL or ESDI CD-ROM drives never existed" @@ -1048,9 +1030,6 @@ msgstr "Parent and child disk timestamps do not match" msgid "Could not fix VHD timestamp." msgstr "Could not fix VHD timestamp." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index f68c6926e..4e2c84d26 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -586,9 +586,6 @@ msgstr "Chequear BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" -msgid "Earlier drive" -msgstr "Unidad anterior" - msgid "MO drives:" msgstr "Unidades MO:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ninguno" -msgid "Unable to load keyboard accelerators." -msgstr "No fué posible cargar aceleradores de teclado." - -msgid "Unable to register raw input." -msgstr "No fué posible registrar entrada directa." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Parada ACPI" msgid "Hard disk (%1)" msgstr "Disco duro (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Nunca existieron unidades de CD-ROM MFM/RLL o ESDI" @@ -1048,9 +1030,6 @@ msgstr "Las marcas de tiempo del padre e hijo no coinciden" msgid "Could not fix VHD timestamp." msgstr "No fué posible corregir la marca de tiempo del VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index c34639550..8935f66b4 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -586,9 +586,6 @@ msgstr "Tarkista BPB" msgid "CD-ROM drives:" msgstr "CD-ROM-asemat:" -msgid "Earlier drive" -msgstr "Aiemmat asemat" - msgid "MO drives:" msgstr "Magneettisoptiset asemat (MO):" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ei mikään" -msgid "Unable to load keyboard accelerators." -msgstr "Näppäinkiihdyttimien lataus epäonnistui" - -msgid "Unable to register raw input." -msgstr "Raakasyötteen rekisteröinti epäonnistui" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u Mt (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI-sammutus" msgid "Hard disk (%1)" msgstr "Kiintolevy (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL- tai ESDI-CD-ROM-asemia ei ole koskaan ollut olemassa" @@ -1048,9 +1030,6 @@ msgstr "Ylä- ja alatason levyjen aikaleimat eivät täsmää" msgid "Could not fix VHD timestamp." msgstr "VHD aikaleimaa ei pystytty korjaamaan." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 3fe8faa2e..c1a0ba18c 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -586,9 +586,6 @@ msgstr "Vérifier BPB" msgid "CD-ROM drives:" msgstr "Lecterus CD-ROM:" -msgid "Earlier drive" -msgstr "Lecteur plus tôt" - msgid "MO drives:" msgstr "Lecteurs magnéto-optiques:" @@ -781,15 +778,6 @@ msgstr "Système de contrôle de vol Thrustmaster" msgid "None" msgstr "Aucun" -msgid "Unable to load keyboard accelerators." -msgstr "Impossible de charger les accélérateurs de clavier." - -msgid "Unable to register raw input." -msgstr "Impossible de charger l'entrée raw." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u Mo (CTS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Arrêt ACPI" msgid "Hard disk (%1)" msgstr "Disque dur (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Les lecteurs de CD-ROM MFM/RLL ou ESDI n'ont jamais existé" @@ -1048,9 +1030,6 @@ msgstr "Les horodatages des disques parent et enfant ne correspondent pas" msgid "Could not fix VHD timestamp." msgstr "Impossible de réparer l'horodatage du VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index db8a157cd..bd87c6b61 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -586,9 +586,6 @@ msgstr "Provjeraj BPB" msgid "CD-ROM drives:" msgstr "CD-ROM pogoni:" -msgid "Earlier drive" -msgstr "Raniji pogon" - msgid "MO drives:" msgstr "MO pogoni:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Bez" -msgid "Unable to load keyboard accelerators." -msgstr "Nije moguće učitati ubrzivače tipkovnice." - -msgid "Unable to register raw input." -msgstr "Nije moguće registrirati neobrađeni unos." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI bazirano gašenje" msgid "Hard disk (%1)" msgstr "Tvrdi disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL ili ESDI CD-ROM pogoni nisu nikada postojali" @@ -1048,9 +1030,6 @@ msgstr "Vremenske ozanke matične i poređenog diska ne odgovaraju." msgid "Could not fix VHD timestamp." msgstr "Ne mogu popraviti vremensku oznaku slike VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 679502f00..7df519ea2 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -586,9 +586,6 @@ msgstr "BPB ellenőrzés" msgid "CD-ROM drives:" msgstr "CD-ROM meghajtók:" -msgid "Earlier drive" -msgstr "Korábbi meghajtó" - msgid "MO drives:" msgstr "MO-meghajtók:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nincs" -msgid "Unable to load keyboard accelerators." -msgstr "Nem lehet betölteni a billentyűzetgyorsítókat." - -msgid "Unable to register raw input." -msgstr "A közvetlen nyers bevitel regisztrálása nem sikerült." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI leállítás" msgid "Hard disk (%1)" msgstr "Merevlemez (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL vagy ESDI CD-ROM meghajtók soha nem léteztek" @@ -1048,9 +1030,6 @@ msgstr "A szülő- és a gyermeklemez időbélyegei nem egyeznek" msgid "Could not fix VHD timestamp." msgstr "Nem sikerült kijavítani a VHD időbélyegét." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index dfb11fb59..97c19bbbf 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -586,9 +586,6 @@ msgstr "Verifica BPB" msgid "CD-ROM drives:" msgstr "Unità CD-ROM:" -msgid "Earlier drive" -msgstr "Unità anteriore" - msgid "MO drives:" msgstr "Unità magneto-ottiche:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nessuno" -msgid "Unable to load keyboard accelerators." -msgstr "Impossibile caricare gli acceleratori da tastiera." - -msgid "Unable to register raw input." -msgstr "Impossibile registrare input raw." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Arresto ACPI" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Le unità CD-ROM MFM/RLL o ESDI non sono mai esistite." @@ -1048,9 +1030,6 @@ msgstr "Le marcature di tempo padre e figlio non corrispondono" msgid "Could not fix VHD timestamp." msgstr "Impossibile aggiustare marcature di tempo VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index c2b0a3d71..7ae841f9d 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -586,9 +586,6 @@ msgstr "BPBチェック" msgid "CD-ROM drives:" msgstr "CD-ROMドライブ:" -msgid "Earlier drive" -msgstr "先のドライブ" - msgid "MO drives:" msgstr "光磁気ドライブ:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster飛行制御システム" msgid "None" msgstr "なし" -msgid "Unable to load keyboard accelerators." -msgstr "キーボードアクセラレータを読み込めません。" - -msgid "Unable to register raw input." -msgstr "生入力が登録できません。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS値: %i、%i、%i)" @@ -937,12 +925,6 @@ msgstr "ACPIシャットダウン" msgid "Hard disk (%1)" msgstr "ハードディスク (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLLやESDI CD-ROMドライブが存在しません" @@ -1048,9 +1030,6 @@ msgstr "親ディスクと子ディスクのタイムス タンプが一致し msgid "Could not fix VHD timestamp." msgstr "VHD のタイムスタンプを修正できません。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 99e74e880..29a6ce8dc 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -586,9 +586,6 @@ msgstr "BPB 확인" msgid "CD-ROM drives:" msgstr "CD-ROM 드라이브:" -msgid "Earlier drive" -msgstr "이전 드라이브" - msgid "MO drives:" msgstr "광자기 드라이브:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "없음" -msgid "Unable to load keyboard accelerators." -msgstr "키보드 가속기를 불러올 수 없습니다." - -msgid "Unable to register raw input." -msgstr "Raw 입력을 등록할 수 없습니다." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 종료" msgid "Hard disk (%1)" msgstr "하드 디스크 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL 또는 ESDI CD-ROM 드라이브가 존재하지 않습니다" @@ -1048,9 +1030,6 @@ msgstr "부모 디스크와 자식 디스크의 타임스탬프가 일치하지 msgid "Could not fix VHD timestamp." msgstr "VHD 타임스탬프를 고칠 수 없습니다" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b67946434..b19bde052 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -586,9 +586,6 @@ msgstr "Sprawdzaj BPB" msgid "CD-ROM drives:" msgstr "Napędy CD-ROM:" -msgid "Earlier drive" -msgstr "Wcześniejszy napęd" - msgid "MO drives:" msgstr "Napędy MO:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Żaden" -msgid "Unable to load keyboard accelerators." -msgstr "Nie można załadować akceleratorów klawiaturowych." - -msgid "Unable to register raw input." -msgstr "Nie można zarejestrować surowych danych wejściowych." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Wyłączenie ACPI" msgid "Hard disk (%1)" msgstr "Dysk twardy (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Napędy CD-ROM MFM/RLL lub ESDI nigdy nie istniały" @@ -1048,9 +1030,6 @@ msgstr "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" msgid "Could not fix VHD timestamp." msgstr "Nie można naprawić sygnatury czasowej VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 689841312..137fd89bf 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -586,9 +586,6 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" -msgid "Earlier drive" -msgstr "Unidade anterior" - msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -781,15 +778,6 @@ msgstr "Sistema de Controle de Voo Thrustmaster" msgid "None" msgstr "Nada" -msgid "Unable to load keyboard accelerators." -msgstr "Não foi possível carregar os aceleradores do teclado." - -msgid "Unable to register raw input." -msgstr "Não foi possível registrar a entrada bruta." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Desligamento por ACPI" msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "As unidades de CD-ROM MFM/RLL ou ESDI nunca existiram" @@ -1048,9 +1030,6 @@ msgstr "A data/hora dos arquivos de pais e filhos não correspondem" msgid "Could not fix VHD timestamp." msgstr "Não foi possível consertar o carimbo de data/hora da VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index adfc05391..9e98b135f 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -586,9 +586,6 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades CD-ROM:" -msgid "Earlier drive" -msgstr "Unidade anterior" - msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nenhum" -msgid "Unable to load keyboard accelerators." -msgstr "Não foi possível inicializar os aceleradores de teclado." - -msgid "Unable to register raw input." -msgstr "Não foi possível registar a entrada bruta." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CCS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Encerramento ACPI" msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" @@ -1048,9 +1030,6 @@ msgstr "Os carimbos de data/hora dos discos pai e filho não correspondem!" msgid "Could not fix VHD timestamp." msgstr "Não foi possível corrigir o carimbo de data/hora do VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 96da04710..e913514f9 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -670,9 +670,6 @@ msgstr "Проверять BPB" msgid "CD-ROM drives:" msgstr "Дисководы CD-ROM:" -msgid "Earlier drive" -msgstr "Предыдущий дисковод" - msgid "MO drives:" msgstr "Магнитооптические дисководы:" @@ -871,15 +868,6 @@ msgstr "Система управления полётом Thrustmaster" msgid "None" msgstr "Нет" -msgid "Unable to load keyboard accelerators." -msgstr "Невозможно загрузить ускорители клавиатуры." - -msgid "Unable to register raw input." -msgstr "Невозможно зарегистрировать необработанный (RAW) ввод." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u МБ (CHS: %i, %i, %i)" @@ -1027,12 +1015,6 @@ msgstr "Сигнал завершения ACPI" msgid "Hard disk (%1)" msgstr "Жёсткий диск (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL или ESDI дисководов CD-ROM никогда не существовало" @@ -1138,9 +1120,6 @@ msgstr "Временные метки родительского и дочерн msgid "Could not fix VHD timestamp." msgstr "Не удалось исправить временную метку VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1156,24 +1135,6 @@ 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" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index c22445a19..95ebba063 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -586,9 +586,6 @@ msgstr "Kontrola BPB" msgid "CD-ROM drives:" msgstr "Mechaniky CD-ROM:" -msgid "Earlier drive" -msgstr "Skorá mechanika" - msgid "MO drives:" msgstr "Magnetooptické mechaniky:" @@ -781,15 +778,6 @@ 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)" @@ -937,12 +925,6 @@ msgstr "Vypnúť cez rozhranie ACPI" msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" -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" @@ -1048,9 +1030,6 @@ 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" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index c32c6c754..b0a7e1a04 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -586,9 +586,6 @@ msgstr "Preverjaj BPB" msgid "CD-ROM drives:" msgstr "Pogoni CD-ROM:" -msgid "Earlier drive" -msgstr "Zgodnejši pogon" - msgid "MO drives:" msgstr "Magnetno-optični pogoni:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Brez" -msgid "Unable to load keyboard accelerators." -msgstr "Ne morem naložiti pospeševalnikov tipkovnice." - -msgid "Unable to register raw input." -msgstr "Ne morem registrirati neobdelanega vnosa." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Zaustavitev ACPI" msgid "Hard disk (%1)" msgstr "Trdi disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL ali ESDI pogoni CD-ROM niso nikoli obstajali" @@ -1048,9 +1030,6 @@ msgstr "Časovna žiga starševske slike diska in slike diska otroka se ne ujema msgid "Could not fix VHD timestamp." msgstr "Ne morem popraviti časovnega žiga slike VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index a1ce42b38..bfe745301 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -586,9 +586,6 @@ msgstr "BPB'yi denetle" msgid "CD-ROM drives:" msgstr "CD-ROM sürücüleri:" -msgid "Earlier drive" -msgstr "Daha erken sürüş" - msgid "MO drives:" msgstr "MO sürücüleri:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Kontrol Sistemi" msgid "None" msgstr "Hiçbiri" -msgid "Unable to load keyboard accelerators." -msgstr "Klavye ivdirgeçleri yüklenemedi." - -msgid "Unable to register raw input." -msgstr "Ham girdi kaydedilemedi." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI kapatma" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" @@ -1048,9 +1030,6 @@ msgstr "Ana ve ek disk zaman damgaları uyuşmuyor" msgid "Could not fix VHD timestamp." msgstr "VHD zaman damgası düzeltilemedi." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 0dc666c0d..c4731a375 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -586,9 +586,6 @@ msgstr "Перевіряти BPB" msgid "CD-ROM drives:" msgstr "Дисководи CD-ROM:" -msgid "Earlier drive" -msgstr "Більш ранній дисковод" - msgid "MO drives:" msgstr "Магнітооптичні дисководи:" @@ -781,15 +778,6 @@ msgstr "Система управління польотом Thrustmaster" msgid "None" msgstr "Ні" -msgid "Unable to load keyboard accelerators." -msgstr "Неможливо завантажити прискорювачі клавіатури." - -msgid "Unable to register raw input." -msgstr "Неможливо зарреєструвати необроблене (RAW) введення." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u МБ (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Сигнал завершення ACPI" msgid "Hard disk (%1)" msgstr "Жорсткий диск (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" @@ -1048,9 +1030,6 @@ msgstr "Тимчасові мітки батьківського та дочір msgid "Could not fix VHD timestamp." msgstr "Не вдалося виправити тимчасову позначку VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index dea46160e..87d291739 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -586,9 +586,6 @@ msgstr "检查 BPB" msgid "CD-ROM drives:" msgstr "光盘驱动器:" -msgid "Earlier drive" -msgstr "早先的驱动器" - msgid "MO drives:" msgstr "磁光盘驱动器:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "无" -msgid "Unable to load keyboard accelerators." -msgstr "无法加载键盘加速器。" - -msgid "Unable to register raw input." -msgstr "无法注册原始输入。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 关机" msgid "Hard disk (%1)" msgstr "硬盘 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" @@ -1048,9 +1030,6 @@ msgstr "父盘与子盘的时间戳不匹配" msgid "Could not fix VHD timestamp." msgstr "无法修复 VHD 时间戳。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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 "光盘 %i (%s): %s" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 9392ce717..2fe3405a3 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -586,9 +586,6 @@ msgstr "檢查 BPB" msgid "CD-ROM drives:" msgstr "光碟機:" -msgid "Earlier drive" -msgstr "早先的光碟機" - msgid "MO drives:" msgstr "磁光碟機:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "無" -msgid "Unable to load keyboard accelerators." -msgstr "無法載入鍵盤加速器。" - -msgid "Unable to register raw input." -msgstr "無法註冊原始輸入。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 關機" msgid "Hard disk (%1)" msgstr "硬碟 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" @@ -1048,9 +1030,6 @@ msgstr "父碟與子碟的時間戳不匹配" msgid "Could not fix VHD timestamp." msgstr "無法修復 VHD 時間戳。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ 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 "光碟 %i (%s): %s" From 3e61092d02a52d69b537c879ab9fe6bc5cc78ab0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:21:52 +0500 Subject: [PATCH 279/690] Translations: Add headers to indicate target lang --- src/qt/languages/ca-ES.po | 8 ++++++++ src/qt/languages/cs-CZ.po | 8 ++++++++ src/qt/languages/de-DE.po | 8 ++++++++ src/qt/languages/en-GB.po | 8 ++++++++ src/qt/languages/en-US.po | 8 ++++++++ src/qt/languages/es-ES.po | 8 ++++++++ src/qt/languages/fi-FI.po | 8 ++++++++ src/qt/languages/fr-FR.po | 8 ++++++++ src/qt/languages/hr-HR.po | 8 ++++++++ src/qt/languages/hu-HU.po | 8 ++++++++ src/qt/languages/it-IT.po | 8 ++++++++ src/qt/languages/ja-JP.po | 8 ++++++++ src/qt/languages/ko-KR.po | 8 ++++++++ src/qt/languages/pl-PL.po | 8 ++++++++ src/qt/languages/pt-BR.po | 8 ++++++++ src/qt/languages/pt-PT.po | 8 ++++++++ src/qt/languages/ru-RU.po | 8 ++++++++ src/qt/languages/sk-SK.po | 8 ++++++++ src/qt/languages/sl-SI.po | 8 ++++++++ src/qt/languages/tr-TR.po | 8 ++++++++ src/qt/languages/uk-UA.po | 8 ++++++++ src/qt/languages/zh-CN.po | 8 ++++++++ src/qt/languages/zh-TW.po | 8 ++++++++ 23 files changed, 184 insertions(+) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 3cde2ff11..94b35a235 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ca_ES\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Acció" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 717a4f488..84debf20b 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: cs_CZ\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Akce" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index c5e5e78aa..70b856aa2 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: de_DE\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Aktionen" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 8e22289b8..a20a1ec36 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: en_GB\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 8298ba0e3..39400ebcc 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: en_US\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 4e2c84d26..21fedd7df 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: es_ES\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Acción" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 8935f66b4..829e9870f 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: fi_FI\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Toiminto" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c1a0ba18c..f7687132f 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: fr_FR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index bd87c6b61..eb69971b8 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: hr_HR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Radnje" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 7df519ea2..ac088e148 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: hu_HU\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Művelet" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 97c19bbbf..0ce1efabb 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: it_IT\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Azione" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 7ae841f9d..c20848be6 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ja_JP\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "操作(&A)" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 29a6ce8dc..afecf78f6 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ko_KR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "동작(&A)" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b19bde052..993e6633a 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pl_PL\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Akcje" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 137fd89bf..642031e9a 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pt_BR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Ação" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 9e98b135f..3aa004e83 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pt_PT\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Ação" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index e913514f9..a4103c3e8 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ru_RU\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Действие" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 95ebba063..8aeb0f082 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: sk_SK\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Podujatia" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index b0a7e1a04..2a4b68e46 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: sl_SI\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Dejanja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index bfe745301..ada5ff87f 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: tr_TR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Komutlar" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index c4731a375..8dca70a85 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: uk_UA\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Дія" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 87d291739..7dd7be6d2 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: zh_CN\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "操作(&A)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 2fe3405a3..8ea4d2290 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: zh_TW\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "動作(&A)" From 18495cb09d96d6420e751ae7ab18f08fd1cd8632 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:36:09 +0500 Subject: [PATCH 280/690] Clean up redundant English "translations" --- src/qt/languages/en-GB.po | 1156 +----------------------------------- src/qt/languages/en-US.po | 1167 ------------------------------------- 2 files changed, 5 insertions(+), 2318 deletions(-) diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index a20a1ec36..fa6d1e2c3 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -6,1169 +6,23 @@ msgstr "" "X-Language: en_GB\n" "X-Source-Language: en_US\n" -msgid "&Action" -msgstr "&Action" - -msgid "&Keyboard requires capture" -msgstr "&Keyboard requires capture" - -msgid "&Right CTRL is left ALT" -msgstr "&Right CTRL is left ALT" - -msgid "&Hard Reset..." -msgstr "&Hard Reset..." - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "&Pause" - -msgid "E&xit..." -msgstr "E&xit..." - -msgid "&View" -msgstr "&View" - -msgid "&Hide status bar" -msgstr "&Hide status bar" - -msgid "Hide &toolbar" -msgstr "Hide &toolbar" - -msgid "&Resizeable window" -msgstr "&Resizeable window" - -msgid "R&emember size && position" -msgstr "R&emember size && position" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (Software)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Specify dimensions..." - -msgid "F&orce 4:3 display ratio" -msgstr "F&orce 4:3 display ratio" - -msgid "&Window scale factor" -msgstr "&Window scale factor" - -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 "Filter method" - -msgid "&Nearest" -msgstr "&Nearest" - -msgid "&Linear" -msgstr "&Linear" - -msgid "Hi&DPI scaling" -msgstr "Hi&DPI scaling" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "&Fullscreen\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "Fullscreen &stretch mode" - -msgid "&Full screen stretch" -msgstr "&Full screen stretch" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "&Square pixels (Keep ratio)" - -msgid "&Integer scale" -msgstr "&Integer scale" - -msgid "4:&3 Integer scale" -msgstr "4:&3 Integer scale" - -msgid "E&GA/(S)VGA settings" -msgstr "E&GA/(S)VGA settings" - -msgid "&Inverted VGA monitor" -msgstr "&Inverted VGA monitor" - -msgid "VGA screen &type" -msgstr "VGA screen &type" - msgid "RGB &Color" msgstr "RGB &Colour" msgid "&RGB Grayscale" msgstr "&RGB Greyscale" -msgid "&Amber monitor" -msgstr "&Amber monitor" - -msgid "&Green monitor" -msgstr "&Green monitor" - -msgid "&White monitor" -msgstr "&White monitor" - -msgid "Grayscale &conversion type" -msgstr "Grayscale &conversion type" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Average" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" - -msgid "Change contrast for &monochrome display" -msgstr "Change contrast for &monochrome display" - -msgid "&Media" -msgstr "&Media" - -msgid "&Tools" -msgstr "&Tools" - -msgid "&Settings..." -msgstr "&Settings..." - -msgid "&Update status bar icons" -msgstr "&Update status bar icons" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Take s&creenshot\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Preferences..." - -msgid "Enable &Discord integration" -msgstr "Enable &Discord integration" - -msgid "Sound &gain..." -msgstr "Sound &gain..." - -msgid "Begin trace\tCtrl+T" -msgstr "Begin trace\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "End trace\tCtrl+T" - -msgid "&Help" -msgstr "&Help" - -msgid "&Documentation..." -msgstr "&Documentation..." - -msgid "&About 86Box..." -msgstr "&About 86Box..." - -msgid "&New image..." -msgstr "&New image..." - -msgid "&Existing image..." -msgstr "&Existing image..." - -msgid "Existing image (&Write-protected)..." -msgstr "Existing image (&Write-protected)..." - -msgid "&Record" -msgstr "&Record" - -msgid "&Play" -msgstr "&Play" - -msgid "&Rewind to the beginning" -msgstr "&Rewind to the beginning" - -msgid "&Fast forward to the end" -msgstr "&Fast forward to the end" - -msgid "E&ject" -msgstr "E&ject" - -msgid "&Image..." -msgstr "&Image..." - -msgid "E&xport to 86F..." -msgstr "E&xport to 86F..." - -msgid "&Mute" -msgstr "&Mute" - -msgid "E&mpty" -msgstr "E&mpty" - -msgid "&Reload previous image" -msgstr "&Reload previous image" - -msgid "&Folder..." -msgstr "&Folder..." - -msgid "Target &framerate" -msgstr "Target &framerate" - -msgid "&Sync with video" -msgstr "&Sync with video" - -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 "&Select shader..." - -msgid "&Remove shader" -msgstr "&Remove shader" - -msgid "Preferences" -msgstr "Preferences" - -msgid "Sound Gain" -msgstr "Sound Gain" - -msgid "New Image" -msgstr "New Image" - -msgid "Settings" -msgstr "Settings" - -msgid "Specify Main Window Dimensions" -msgstr "Specify Main Window Dimensions" - -msgid "OK" -msgstr "OK" - -msgid "Cancel" -msgstr "Cancel" - -msgid "Save these settings as &global defaults" -msgstr "Save these settings as &global defaults" - -msgid "&Default" -msgstr "&Default" - -msgid "Language:" -msgstr "Language:" - -msgid "Icon set:" -msgstr "Icon set:" - -msgid "Gain" -msgstr "Gain" - -msgid "File name:" -msgstr "File name:" - -msgid "Disk size:" -msgstr "Disk size:" - -msgid "RPM mode:" -msgstr "RPM mode:" - -msgid "Progress:" -msgstr "Progress:" - -msgid "Width:" -msgstr "Width:" - -msgid "Height:" -msgstr "Height:" - -msgid "Lock to this size" -msgstr "Lock to this size" - -msgid "Machine type:" -msgstr "Machine type:" - -msgid "Machine:" -msgstr "Machine:" - -msgid "Configure" -msgstr "Configure" - -msgid "CPU type:" -msgstr "CPU type:" - -msgid "Speed:" -msgstr "Speed:" - -msgid "Frequency:" -msgstr "Frequency:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Wait states:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Memory:" - msgid "Time synchronization" -msgstr "Time synchronization" - -msgid "Disabled" -msgstr "Disabled" - -msgid "Enabled (local time)" -msgstr "Enabled (local time)" - -msgid "Enabled (UTC)" -msgstr "Enabled (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Dynamic Recompiler" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" - -msgid "XGA Graphics" -msgstr "XGA Graphics" - -msgid "Mouse:" -msgstr "Mouse:" - -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 "Sound card #1:" - -msgid "Sound card #2:" -msgstr "Sound card #2:" - -msgid "Sound card #3:" -msgstr "Sound card #3:" - -msgid "Sound card #4:" -msgstr "Sound card #4:" - -msgid "MIDI Out Device:" -msgstr "MIDI Out Device:" - -msgid "MIDI In Device:" -msgstr "MIDI In Device:" - -msgid "Standalone MPU-401" -msgstr "Standalone MPU-401" - -msgid "Use FLOAT32 sound" -msgstr "Use FLOAT32 sound" - -msgid "FM synth driver" -msgstr "FM synth driver" - -msgid "Nuked (more accurate)" -msgstr "Nuked (more accurate)" - -msgid "YMFM (faster)" -msgstr "YMFM (faster)" - -msgid "Network type:" -msgstr "Network type:" - -msgid "PCap device:" -msgstr "PCap device:" - -msgid "Network adapter:" -msgstr "Network adapter:" - -msgid "COM1 Device:" -msgstr "COM1 Device:" - -msgid "COM2 Device:" -msgstr "COM2 Device:" - -msgid "COM3 Device:" -msgstr "COM3 Device:" - -msgid "COM4 Device:" -msgstr "COM4 Device:" - -msgid "LPT1 Device:" -msgstr "LPT1 Device:" - -msgid "LPT2 Device:" -msgstr "LPT2 Device:" - -msgid "LPT3 Device:" -msgstr "LPT3 Device:" - -msgid "LPT4 Device:" -msgstr "LPT4 Device:" - -msgid "Serial port 1" -msgstr "Serial port 1" - -msgid "Serial port 2" -msgstr "Serial port 2" - -msgid "Serial port 3" -msgstr "Serial port 3" - -msgid "Serial port 4" -msgstr "Serial port 4" - -msgid "Parallel port 1" -msgstr "Parallel port 1" - -msgid "Parallel port 2" -msgstr "Parallel port 2" - -msgid "Parallel port 3" -msgstr "Parallel port 3" - -msgid "Parallel port 4" -msgstr "Parallel port 4" - -msgid "HD Controller:" -msgstr "HD Controller:" - -msgid "FD Controller:" -msgstr "FD Controller:" - -msgid "Tertiary IDE Controller" -msgstr "Tertiary IDE Controller" - -msgid "Quaternary IDE Controller" -msgstr "Quaternary IDE Controller" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Controller 1:" - -msgid "Controller 2:" -msgstr "Controller 2:" - -msgid "Controller 3:" -msgstr "Controller 3:" - -msgid "Controller 4:" -msgstr "Controller 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Hard disks:" - -msgid "&New..." -msgstr "&New..." - -msgid "&Existing..." -msgstr "&Existing..." - -msgid "&Remove" -msgstr "&Remove" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Channel:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "&Specify..." - -msgid "Sectors:" -msgstr "Sectors:" - -msgid "Heads:" -msgstr "Heads:" - -msgid "Cylinders:" -msgstr "Cylinders:" - -msgid "Size (MB):" -msgstr "Size (MB):" - -msgid "Type:" -msgstr "Type:" - -msgid "Image Format:" -msgstr "Image Format:" - -msgid "Block Size:" -msgstr "Block Size:" - -msgid "Floppy drives:" -msgstr "Floppy drives:" - -msgid "Turbo timings" -msgstr "Turbo timings" - -msgid "Check BPB" -msgstr "Check BPB" - -msgid "CD-ROM drives:" -msgstr "CD-ROM drives:" - -msgid "MO drives:" -msgstr "MO drives:" - -msgid "ZIP drives:" -msgstr "ZIP drives:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "ISA Memory Expansion" - -msgid "Card 1:" -msgstr "Card 1:" - -msgid "Card 2:" -msgstr "Card 2:" - -msgid "Card 3:" -msgstr "Card 3:" - -msgid "Card 4:" -msgstr "Card 4:" - -msgid "ISABugger device" -msgstr "ISABugger device" - -msgid "POST card" -msgstr "POST card" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Error" - -msgid "Fatal error" -msgstr "Fatal error" - -msgid " - PAUSED" -msgstr " - PAUSED" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Press Ctrl+Alt+PgDn to return to windowed mode." - -msgid "Speed" -msgstr "Speed" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "ZIP images" - -msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." - -msgid "(empty)" -msgstr "(empty)" - -msgid "All files" -msgstr "All files" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "On" - -msgid "Off" -msgstr "Off" - -msgid "All images" -msgstr "All images" - -msgid "Basic sector images" -msgstr "Basic sector images" - -msgid "Surface images" -msgstr "Surface images" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - -msgid "Machine" -msgstr "Machine" - -msgid "Display" -msgstr "Display" - -msgid "Input devices" -msgstr "Input devices" - -msgid "Sound" -msgstr "Sound" - -msgid "Network" -msgstr "Network" - -msgid "Ports (COM & LPT)" -msgstr "Ports (COM & LPT)" - -msgid "Storage controllers" -msgstr "Storage controllers" - -msgid "Hard disks" -msgstr "Hard disks" - -msgid "Floppy & CD-ROM drives" -msgstr "Floppy & CD-ROM drives" - -msgid "Other removable devices" -msgstr "Other removable devices" - -msgid "Other peripherals" -msgstr "Other peripherals" - -msgid "Click to capture mouse" -msgstr "Click to capture mouse" - -msgid "Press %1 to release mouse" -msgstr "Press %1 to release mouse" - -msgid "Press %1 or middle button to release mouse" -msgstr "Press %1 or middle button to release mouse" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" +msgstr "Time synchronisation" msgid "Could not initialize the video renderer." -msgstr "Could not initialize the video renderer." - -msgid "Default" -msgstr "Default" - -msgid "%i Wait state(s)" -msgstr "%i Wait state(s)" - -msgid "Type" -msgstr "Type" - -msgid "No PCap devices found" -msgstr "No PCap devices found" - -msgid "Invalid PCap device" -msgstr "Invalid PCap device" - -msgid "Standard 2-button joystick(s)" -msgstr "Standard 2-button joystick(s)" - -msgid "Standard 4-button joystick" -msgstr "Standard 4-button joystick" - -msgid "Standard 6-button joystick" -msgstr "Standard 6-button joystick" - -msgid "Standard 8-button joystick" -msgstr "Standard 8-button 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 "None" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Floppy %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Advanced sector images" - -msgid "Flux images" -msgstr "Flux images" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Are you sure you want to hard reset the emulated machine?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Are you sure you want to exit 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Unable to initialize Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "MO images" - -msgid "Welcome to 86Box!" -msgstr "Welcome to 86Box!" - -msgid "Internal controller" -msgstr "Internal controller" - -msgid "Exit" -msgstr "Exit" - -msgid "No ROMs found" -msgstr "No ROMs found" - -msgid "Do you want to save the settings?" -msgstr "Do you want to save the settings?" - -msgid "This will hard reset the emulated machine." -msgstr "This will hard reset the emulated machine." - -msgid "Save" -msgstr "Save" - -msgid "About 86Box" -msgstr "About 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - -msgid "Hardware not available" -msgstr "Hardware not available" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." - -msgid "Invalid configuration" -msgstr "Invalid configuration" - -msgid "%1 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 "%1 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." - -msgid "Entering fullscreen mode" -msgstr "Entering fullscreen mode" - -msgid "Don't show this message again" -msgstr "Don't show this message again" - -msgid "Don't exit" -msgstr "Don't exit" - -msgid "Reset" -msgstr "Reset" - -msgid "Don't reset" -msgstr "Don't reset" - -msgid "CD-ROM images" -msgstr "CD-ROM images" - -msgid "%1 Device Configuration" -msgstr "%1 Device Configuration" - -msgid "Monitor in sleep mode" -msgstr "Monitor in sleep mode" - -msgid "OpenGL Shaders" -msgstr "OpenGL Shaders" - -msgid "OpenGL options" -msgstr "OpenGL options" - -msgid "You are loading an unsupported configuration" -msgstr "You are loading an unsupported configuration" - -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 "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." - -msgid "Continue" -msgstr "Continue" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Cassette images" - -msgid "Cartridge %i: %ls" -msgstr "Cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Cartridge images" +msgstr "Could not initialise the video renderer." msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Error initialising renderer" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - -msgid "Resume execution" -msgstr "Resume execution" - -msgid "Pause execution" -msgstr "Pause execution" - -msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Hard reset" - -msgid "ACPI shutdown" -msgstr "ACPI shutdown" - -msgid "Hard disk (%1)" -msgstr "Hard disk (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL or ESDI CD-ROM drives never existed" - -msgid "Custom..." -msgstr "Custom..." - -msgid "Custom (large)..." -msgstr "Custom (large)..." - -msgid "Add New Hard Disk" -msgstr "Add New Hard Disk" - -msgid "Add Existing Hard Disk" -msgstr "Add Existing Hard Disk" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk images cannot be larger than 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Disk images cannot be larger than 127 GB." - -msgid "Hard disk images" -msgstr "Hard disk images" - -msgid "Unable to read file" -msgstr "Unable to read file" - -msgid "Unable to write file" -msgstr "Unable to write file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI or HDX images with a sector size other than 512 are not supported." - -msgid "Disk image file already exists" -msgstr "Disk image file already exists" - -msgid "Please specify a valid file name." -msgstr "Please specify a valid file name." - -msgid "Disk image created" -msgstr "Disk image created" - -msgid "Make sure the file exists and is readable." -msgstr "Make sure the file exists and is readable." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Make sure the file is being saved to a writable directory." - -msgid "Disk image too large" -msgstr "Disk image too large" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Remember to partition and format the newly-created drive." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "The selected file will be overwritten. Are you sure you want to use it?" - -msgid "Unsupported disk image" -msgstr "Unsupported disk image" - -msgid "Overwrite" -msgstr "Overwrite" - -msgid "Don't overwrite" -msgstr "Don't overwrite" - -msgid "Raw image (.img)" -msgstr "Raw image (.img)" - -msgid "HDI image (.hdi)" -msgstr "HDI image (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "HDX image (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Fixed-size VHD (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Dynamic-size VHD (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Large blocks (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Small blocks (512 KB)" - -msgid "VHD files" -msgstr "VHD files" - -msgid "Select the parent VHD" -msgstr "Select the parent VHD" - -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 "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?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Parent and child disk timestamps do not match" - -msgid "Could not fix VHD timestamp." -msgstr "Could not fix VHD timestamp." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -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 "Perfect RPM" - -msgid "1% below perfect RPM" -msgstr "1% below perfect RPM" - -msgid "1.5% below perfect RPM" -msgstr "1.5% below perfect RPM" - -msgid "2% below perfect RPM" -msgstr "2% below perfect RPM" - -msgid "(System Default)" -msgstr "(System Default)" - -msgid "Failed to initialize network driver" -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:" - -msgid "Auto" -msgstr "Auto" - -msgid "Slow" -msgstr "Slow" - -msgid "Fast" -msgstr "Fast" - -msgid "&Auto-pause on focus loss" -msgstr "&Auto-pause on focus loss" - -msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" +msgstr "OpenGL (3.0 Core) renderer could not be initialised. Use another renderer." msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behaviour will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 39400ebcc..e78536c66 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -5,1170 +5,3 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Language: en_US\n" "X-Source-Language: en_US\n" - -msgid "&Action" -msgstr "&Action" - -msgid "&Keyboard requires capture" -msgstr "&Keyboard requires capture" - -msgid "&Right CTRL is left ALT" -msgstr "&Right CTRL is left ALT" - -msgid "&Hard Reset..." -msgstr "&Hard Reset..." - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "&Pause" - -msgid "E&xit..." -msgstr "E&xit..." - -msgid "&View" -msgstr "&View" - -msgid "&Hide status bar" -msgstr "&Hide status bar" - -msgid "Hide &toolbar" -msgstr "Hide &toolbar" - -msgid "&Resizeable window" -msgstr "&Resizeable window" - -msgid "R&emember size && position" -msgstr "R&emember size && position" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (Software)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Specify dimensions..." - -msgid "F&orce 4:3 display ratio" -msgstr "F&orce 4:3 display ratio" - -msgid "&Window scale factor" -msgstr "&Window scale factor" - -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 "Filter method" - -msgid "&Nearest" -msgstr "&Nearest" - -msgid "&Linear" -msgstr "&Linear" - -msgid "Hi&DPI scaling" -msgstr "Hi&DPI scaling" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "&Fullscreen\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "Fullscreen &stretch mode" - -msgid "&Full screen stretch" -msgstr "&Full screen stretch" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "&Square pixels (Keep ratio)" - -msgid "&Integer scale" -msgstr "&Integer scale" - -msgid "4:&3 Integer scale" -msgstr "4:&3 Integer scale" - -msgid "E&GA/(S)VGA settings" -msgstr "E&GA/(S)VGA settings" - -msgid "&Inverted VGA monitor" -msgstr "&Inverted VGA monitor" - -msgid "VGA screen &type" -msgstr "VGA screen &type" - -msgid "RGB &Color" -msgstr "RGB &Color" - -msgid "&RGB Grayscale" -msgstr "&RGB Grayscale" - -msgid "&Amber monitor" -msgstr "&Amber monitor" - -msgid "&Green monitor" -msgstr "&Green monitor" - -msgid "&White monitor" -msgstr "&White monitor" - -msgid "Grayscale &conversion type" -msgstr "Grayscale &conversion type" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Average" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" - -msgid "Change contrast for &monochrome display" -msgstr "Change contrast for &monochrome display" - -msgid "&Media" -msgstr "&Media" - -msgid "&Tools" -msgstr "&Tools" - -msgid "&Settings..." -msgstr "&Settings..." - -msgid "&Update status bar icons" -msgstr "&Update status bar icons" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Take s&creenshot\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Preferences..." - -msgid "Enable &Discord integration" -msgstr "Enable &Discord integration" - -msgid "Sound &gain..." -msgstr "Sound &gain..." - -msgid "Begin trace\tCtrl+T" -msgstr "Begin trace\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "End trace\tCtrl+T" - -msgid "&Help" -msgstr "&Help" - -msgid "&Documentation..." -msgstr "&Documentation..." - -msgid "&About 86Box..." -msgstr "&About 86Box..." - -msgid "&New image..." -msgstr "&New image..." - -msgid "&Existing image..." -msgstr "&Existing image..." - -msgid "Existing image (&Write-protected)..." -msgstr "Existing image (&Write-protected)..." - -msgid "&Record" -msgstr "&Record" - -msgid "&Play" -msgstr "&Play" - -msgid "&Rewind to the beginning" -msgstr "&Rewind to the beginning" - -msgid "&Fast forward to the end" -msgstr "&Fast forward to the end" - -msgid "E&ject" -msgstr "E&ject" - -msgid "&Image..." -msgstr "&Image..." - -msgid "E&xport to 86F..." -msgstr "E&xport to 86F..." - -msgid "&Mute" -msgstr "&Mute" - -msgid "E&mpty" -msgstr "E&mpty" - -msgid "&Reload previous image" -msgstr "&Reload previous image" - -msgid "&Folder..." -msgstr "&Folder..." - -msgid "Target &framerate" -msgstr "Target &framerate" - -msgid "&Sync with video" -msgstr "&Sync with video" - -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 "&Select shader..." - -msgid "&Remove shader" -msgstr "&Remove shader" - -msgid "Preferences" -msgstr "Preferences" - -msgid "Sound Gain" -msgstr "Sound Gain" - -msgid "New Image" -msgstr "New Image" - -msgid "Settings" -msgstr "Settings" - -msgid "Specify Main Window Dimensions" -msgstr "Specify Main Window Dimensions" - -msgid "OK" -msgstr "OK" - -msgid "Cancel" -msgstr "Cancel" - -msgid "Save these settings as &global defaults" -msgstr "Save these settings as &global defaults" - -msgid "&Default" -msgstr "&Default" - -msgid "Language:" -msgstr "Language:" - -msgid "Icon set:" -msgstr "Icon set:" - -msgid "Gain" -msgstr "Gain" - -msgid "File name:" -msgstr "File name:" - -msgid "Disk size:" -msgstr "Disk size:" - -msgid "RPM mode:" -msgstr "RPM mode:" - -msgid "Progress:" -msgstr "Progress:" - -msgid "Width:" -msgstr "Width:" - -msgid "Height:" -msgstr "Height:" - -msgid "Lock to this size" -msgstr "Lock to this size" - -msgid "Machine type:" -msgstr "Machine type:" - -msgid "Machine:" -msgstr "Machine:" - -msgid "Configure" -msgstr "Configure" - -msgid "CPU type:" -msgstr "CPU type:" - -msgid "Speed:" -msgstr "Speed:" - -msgid "Frequency:" -msgstr "Frequency:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Wait states:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Memory:" - -msgid "Time synchronization" -msgstr "Time synchronization" - -msgid "Disabled" -msgstr "Disabled" - -msgid "Enabled (local time)" -msgstr "Enabled (local time)" - -msgid "Enabled (UTC)" -msgstr "Enabled (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Dynamic Recompiler" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" - -msgid "XGA Graphics" -msgstr "XGA Graphics" - -msgid "Mouse:" -msgstr "Mouse:" - -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 "Sound card #1:" - -msgid "Sound card #2:" -msgstr "Sound card #2:" - -msgid "Sound card #3:" -msgstr "Sound card #3:" - -msgid "Sound card #4:" -msgstr "Sound card #4:" - -msgid "MIDI Out Device:" -msgstr "MIDI Out Device:" - -msgid "MIDI In Device:" -msgstr "MIDI In Device:" - -msgid "Standalone MPU-401" -msgstr "Standalone MPU-401" - -msgid "Use FLOAT32 sound" -msgstr "Use FLOAT32 sound" - -msgid "FM synth driver" -msgstr "FM synth driver" - -msgid "Nuked (more accurate)" -msgstr "Nuked (more accurate)" - -msgid "YMFM (faster)" -msgstr "YMFM (faster)" - -msgid "Network type:" -msgstr "Network type:" - -msgid "PCap device:" -msgstr "PCap device:" - -msgid "Network adapter:" -msgstr "Network adapter:" - -msgid "COM1 Device:" -msgstr "COM1 Device:" - -msgid "COM2 Device:" -msgstr "COM2 Device:" - -msgid "COM3 Device:" -msgstr "COM3 Device:" - -msgid "COM4 Device:" -msgstr "COM4 Device:" - -msgid "LPT1 Device:" -msgstr "LPT1 Device:" - -msgid "LPT2 Device:" -msgstr "LPT2 Device:" - -msgid "LPT3 Device:" -msgstr "LPT3 Device:" - -msgid "LPT4 Device:" -msgstr "LPT4 Device:" - -msgid "Serial port 1" -msgstr "Serial port 1" - -msgid "Serial port 2" -msgstr "Serial port 2" - -msgid "Serial port 3" -msgstr "Serial port 3" - -msgid "Serial port 4" -msgstr "Serial port 4" - -msgid "Parallel port 1" -msgstr "Parallel port 1" - -msgid "Parallel port 2" -msgstr "Parallel port 2" - -msgid "Parallel port 3" -msgstr "Parallel port 3" - -msgid "Parallel port 4" -msgstr "Parallel port 4" - -msgid "HD Controller:" -msgstr "HD Controller:" - -msgid "FD Controller:" -msgstr "FD Controller:" - -msgid "Tertiary IDE Controller" -msgstr "Tertiary IDE Controller" - -msgid "Quaternary IDE Controller" -msgstr "Quaternary IDE Controller" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Controller 1:" - -msgid "Controller 2:" -msgstr "Controller 2:" - -msgid "Controller 3:" -msgstr "Controller 3:" - -msgid "Controller 4:" -msgstr "Controller 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Hard disks:" - -msgid "&New..." -msgstr "&New..." - -msgid "&Existing..." -msgstr "&Existing..." - -msgid "&Remove" -msgstr "&Remove" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Channel:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "&Specify..." - -msgid "Sectors:" -msgstr "Sectors:" - -msgid "Heads:" -msgstr "Heads:" - -msgid "Cylinders:" -msgstr "Cylinders:" - -msgid "Size (MB):" -msgstr "Size (MB):" - -msgid "Type:" -msgstr "Type:" - -msgid "Image Format:" -msgstr "Image Format:" - -msgid "Block Size:" -msgstr "Block Size:" - -msgid "Floppy drives:" -msgstr "Floppy drives:" - -msgid "Turbo timings" -msgstr "Turbo timings" - -msgid "Check BPB" -msgstr "Check BPB" - -msgid "CD-ROM drives:" -msgstr "CD-ROM drives:" - -msgid "MO drives:" -msgstr "MO drives:" - -msgid "ZIP drives:" -msgstr "ZIP drives:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "ISA Memory Expansion" - -msgid "Card 1:" -msgstr "Card 1:" - -msgid "Card 2:" -msgstr "Card 2:" - -msgid "Card 3:" -msgstr "Card 3:" - -msgid "Card 4:" -msgstr "Card 4:" - -msgid "ISABugger device" -msgstr "ISABugger device" - -msgid "POST card" -msgstr "POST card" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Error" - -msgid "Fatal error" -msgstr "Fatal error" - -msgid " - PAUSED" -msgstr " - PAUSED" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Press Ctrl+Alt+PgDn to return to windowed mode." - -msgid "Speed" -msgstr "Speed" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "ZIP images" - -msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." - -msgid "(empty)" -msgstr "(empty)" - -msgid "All files" -msgstr "All files" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "On" - -msgid "Off" -msgstr "Off" - -msgid "All images" -msgstr "All images" - -msgid "Basic sector images" -msgstr "Basic sector images" - -msgid "Surface images" -msgstr "Surface images" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - -msgid "Machine" -msgstr "Machine" - -msgid "Display" -msgstr "Display" - -msgid "Input devices" -msgstr "Input devices" - -msgid "Sound" -msgstr "Sound" - -msgid "Network" -msgstr "Network" - -msgid "Ports (COM & LPT)" -msgstr "Ports (COM & LPT)" - -msgid "Storage controllers" -msgstr "Storage controllers" - -msgid "Hard disks" -msgstr "Hard disks" - -msgid "Floppy & CD-ROM drives" -msgstr "Floppy & CD-ROM drives" - -msgid "Other removable devices" -msgstr "Other removable devices" - -msgid "Other peripherals" -msgstr "Other peripherals" - -msgid "Click to capture mouse" -msgstr "Click to capture mouse" - -msgid "Press %1 to release mouse" -msgstr "Press %1 to release mouse" - -msgid "Press %1 or middle button to release mouse" -msgstr "Press %1 or middle button to release mouse" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" - -msgid "Could not initialize the video renderer." -msgstr "Could not initialize the video renderer." - -msgid "Default" -msgstr "Default" - -msgid "%i Wait state(s)" -msgstr "%i Wait state(s)" - -msgid "Type" -msgstr "Type" - -msgid "No PCap devices found" -msgstr "No PCap devices found" - -msgid "Invalid PCap device" -msgstr "Invalid PCap device" - -msgid "Standard 2-button joystick(s)" -msgstr "Standard 2-button joystick(s)" - -msgid "Standard 4-button joystick" -msgstr "Standard 4-button joystick" - -msgid "Standard 6-button joystick" -msgstr "Standard 6-button joystick" - -msgid "Standard 8-button joystick" -msgstr "Standard 8-button 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 "None" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Floppy %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Advanced sector images" - -msgid "Flux images" -msgstr "Flux images" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Are you sure you want to hard reset the emulated machine?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Are you sure you want to exit 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Unable to initialize Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "MO images" - -msgid "Welcome to 86Box!" -msgstr "Welcome to 86Box!" - -msgid "Internal controller" -msgstr "Internal controller" - -msgid "Exit" -msgstr "Exit" - -msgid "No ROMs found" -msgstr "No ROMs found" - -msgid "Do you want to save the settings?" -msgstr "Do you want to save the settings?" - -msgid "This will hard reset the emulated machine." -msgstr "This will hard reset the emulated machine." - -msgid "Save" -msgstr "Save" - -msgid "About 86Box" -msgstr "About 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - -msgid "Hardware not available" -msgstr "Hardware not available" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." - -msgid "Invalid configuration" -msgstr "Invalid configuration" - -msgid "%1 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 "%1 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." - -msgid "Entering fullscreen mode" -msgstr "Entering fullscreen mode" - -msgid "Don't show this message again" -msgstr "Don't show this message again" - -msgid "Don't exit" -msgstr "Don't exit" - -msgid "Reset" -msgstr "Reset" - -msgid "Don't reset" -msgstr "Don't reset" - -msgid "CD-ROM images" -msgstr "CD-ROM images" - -msgid "%1 Device Configuration" -msgstr "%1 Device Configuration" - -msgid "Monitor in sleep mode" -msgstr "Monitor in sleep mode" - -msgid "OpenGL Shaders" -msgstr "OpenGL Shaders" - -msgid "OpenGL options" -msgstr "OpenGL options" - -msgid "You are loading an unsupported configuration" -msgstr "You are loading an unsupported configuration" - -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 "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." - -msgid "Continue" -msgstr "Continue" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Cassette images" - -msgid "Cartridge %i: %ls" -msgstr "Cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Cartridge images" - -msgid "Error initializing renderer" -msgstr "Error initializing renderer" - -msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - -msgid "Resume execution" -msgstr "Resume execution" - -msgid "Pause execution" -msgstr "Pause execution" - -msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Hard reset" - -msgid "ACPI shutdown" -msgstr "ACPI shutdown" - -msgid "Hard disk (%1)" -msgstr "Hard disk (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL or ESDI CD-ROM drives never existed" - -msgid "Custom..." -msgstr "Custom..." - -msgid "Custom (large)..." -msgstr "Custom (large)..." - -msgid "Add New Hard Disk" -msgstr "Add New Hard Disk" - -msgid "Add Existing Hard Disk" -msgstr "Add Existing Hard Disk" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk images cannot be larger than 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Disk images cannot be larger than 127 GB." - -msgid "Hard disk images" -msgstr "Hard disk images" - -msgid "Unable to read file" -msgstr "Unable to read file" - -msgid "Unable to write file" -msgstr "Unable to write file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI or HDX images with a sector size other than 512 are not supported." - -msgid "Disk image file already exists" -msgstr "Disk image file already exists" - -msgid "Please specify a valid file name." -msgstr "Please specify a valid file name." - -msgid "Disk image created" -msgstr "Disk image created" - -msgid "Make sure the file exists and is readable." -msgstr "Make sure the file exists and is readable." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Make sure the file is being saved to a writable directory." - -msgid "Disk image too large" -msgstr "Disk image too large" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Remember to partition and format the newly-created drive." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "The selected file will be overwritten. Are you sure you want to use it?" - -msgid "Unsupported disk image" -msgstr "Unsupported disk image" - -msgid "Overwrite" -msgstr "Overwrite" - -msgid "Don't overwrite" -msgstr "Don't overwrite" - -msgid "Raw image (.img)" -msgstr "Raw image (.img)" - -msgid "HDI image (.hdi)" -msgstr "HDI image (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "HDX image (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Fixed-size VHD (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Dynamic-size VHD (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Large blocks (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Small blocks (512 KB)" - -msgid "VHD files" -msgstr "VHD files" - -msgid "Select the parent VHD" -msgstr "Select the parent VHD" - -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 "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?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Parent and child disk timestamps do not match" - -msgid "Could not fix VHD timestamp." -msgstr "Could not fix VHD timestamp." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -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 "Perfect RPM" - -msgid "1% below perfect RPM" -msgstr "1% below perfect RPM" - -msgid "1.5% below perfect RPM" -msgstr "1.5% below perfect RPM" - -msgid "2% below perfect RPM" -msgstr "2% below perfect RPM" - -msgid "(System Default)" -msgstr "(System Default)" - -msgid "Failed to initialize network driver" -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:" - -msgid "Auto" -msgstr "Auto" - -msgid "Slow" -msgstr "Slow" - -msgid "Fast" -msgstr "Fast" - -msgid "&Auto-pause on focus loss" -msgstr "&Auto-pause on focus loss" - -msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" - -msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." From 9354c6a6eff5e6f323f9c91a45a78dc8a80fe45f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:41:31 +0500 Subject: [PATCH 281/690] Qt: Fix CD-ROM menu not updating after ejecting a CD from the guest --- src/qt/CMakeLists.txt | 1 - src/qt/qt_cdrom.c | 54 ----------------------------------------- src/qt/qt_mediamenu.cpp | 23 ++++++++++++++++++ src/qt/qt_mediamenu.hpp | 1 + 4 files changed, 24 insertions(+), 55 deletions(-) delete mode 100644 src/qt/qt_cdrom.c diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index e189ec569..422989a44 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -61,7 +61,6 @@ add_library(plat STATIC add_library(ui STATIC qt_ui.cpp - qt_cdrom.c qt_mainwindow.cpp qt_mainwindow.hpp diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c deleted file mode 100644 index 1facae486..000000000 --- a/src/qt/qt_cdrom.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * - * Handle the platform-side of CDROM/ZIP/MO drives. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - */ - -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/hdd.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/scsi_disk.h> -#include <86box/plat.h> -#include <86box/ui.h> - -void -plat_cdrom_ui_update(uint8_t id, uint8_t reload) -{ - cdrom_t *drv = &cdrom[id]; - - if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } - - // media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); -} diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 541e31190..2365fb728 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -521,6 +521,23 @@ MediaMenu::cdromReload(int index, int slot) ui_sb_update_tip(SB_CDROM | index); } +void +MediaMenu::cdromUpdateUi(int i) +{ + cdrom_t *drv = &cdrom[i]; + + if (drv->host_drive == 0) { + mhm.addImageToHistory(i, ui::MediaType::Optical, drv->prev_image_path, QString()); + ui_sb_update_icon_state(SB_CDROM | i, 1); + } else { + mhm.addImageToHistory(i, ui::MediaType::Optical, drv->prev_image_path, drv->image_path); + ui_sb_update_icon_state(SB_CDROM | i, 0); + } + + cdromUpdateMenu(i); + ui_sb_update_tip(SB_CDROM | i); +} + void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { @@ -892,6 +909,12 @@ MediaMenu::getMediaOpenDirectory() // callbacks from 86box C code extern "C" { +void +plat_cdrom_ui_update(uint8_t id, uint8_t reload) +{ + MediaMenu::ptr->cdromUpdateUi(id); +} + void zip_eject(uint8_t id) { diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 57fd8dfc2..03d046847 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -45,6 +45,7 @@ public: void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); + void cdromUpdateUi(int i); void updateImageHistory(int index, int slot, ui::MediaType type); void clearImageHistory(); void cdromUpdateMenu(int i); From 4052ae2e32dad231fdcd6e806c155d5c222df901 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 21:25:14 +0500 Subject: [PATCH 282/690] Use a signal instead --- src/qt/qt_mediamenu.cpp | 3 ++- src/qt/qt_mediamenu.hpp | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 2365fb728..7f7d120b8 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -61,6 +61,7 @@ MediaMenu::MediaMenu(QWidget *parent) : QObject(parent) { parentWidget = parent; + connect(this, &MediaMenu::onCdromUpdateUi, this, &MediaMenu::cdromUpdateUi, Qt::QueuedConnection); } void @@ -912,7 +913,7 @@ extern "C" { void plat_cdrom_ui_update(uint8_t id, uint8_t reload) { - MediaMenu::ptr->cdromUpdateUi(id); + emit MediaMenu::ptr->onCdromUpdateUi(id); } void diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 03d046847..7835077b3 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -10,7 +10,7 @@ extern "C" { } class QMenu; -class MediaMenu : QObject { +class MediaMenu : public QObject { Q_OBJECT public: MediaMenu(QWidget *parent); @@ -45,7 +45,6 @@ public: void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); - void cdromUpdateUi(int i); void updateImageHistory(int index, int slot, ui::MediaType type); void clearImageHistory(); void cdromUpdateMenu(int i); @@ -68,6 +67,12 @@ public: void nicDisconnect(int i); void nicUpdateMenu(int i); +public slots: + void cdromUpdateUi(int i); + +signals: + void onCdromUpdateUi(int i); + private: QWidget *parentWidget = nullptr; From df231b0d873d6fd9fab83d0e7b869f65e46e409b Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 22:26:10 +0500 Subject: [PATCH 283/690] Implement the rest of _eject/_mount functions Implement the rest of media eject/mount functions declared in plat.h, intended for future use --- src/qt/qt_mediamenu.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 7f7d120b8..af6d40e79 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -909,6 +909,47 @@ MediaMenu::getMediaOpenDirectory() // callbacks from 86box C code extern "C" { +void +cassette_mount(char *fn, uint8_t wp) +{ + MediaMenu::ptr->cassetteMount(QString(fn), wp); +} + +void +cassette_eject(void) +{ + MediaMenu::ptr->cassetteEject(); +} + +void +cartridge_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->cartridgeMount(id, QString(fn)); +} + +void +cartridge_eject(uint8_t id) +{ + MediaMenu::ptr->cartridgeEject(id); +} + +void +floppy_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->floppyMount(id, QString(fn), wp); +} + +void +floppy_eject(uint8_t id) +{ + MediaMenu::ptr->floppyEject(id); +} + +void +cdrom_mount(uint8_t id, char *fn) +{ + MediaMenu::ptr->cdromMount(id, QString(fn)); +} void plat_cdrom_ui_update(uint8_t id, uint8_t reload) @@ -922,6 +963,12 @@ zip_eject(uint8_t id) MediaMenu::ptr->zipEject(id); } +void +zip_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->zipMount(id, QString(fn), wp); +} + void zip_reload(uint8_t id) { @@ -934,6 +981,12 @@ mo_eject(uint8_t id) MediaMenu::ptr->moEject(id); } +void +mo_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->moMount(id, QString(fn), wp); +} + void mo_reload(uint8_t id) { From 53fbe7343e7795507891345d2bf531b11067ccb3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 22:30:11 +0500 Subject: [PATCH 284/690] Check for pcap DLL in Npcap's installation directory on Windows --- src/network/net_pcap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index e1747580b..16caaec7e 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -365,7 +365,13 @@ net_pcap_prepare(netdev_t *list) /* Try loading the DLL. */ #ifdef _WIN32 + /* Add the Npcap directory to the DLL search path. */ + char npcap_dir[512]; + GetSystemDirectoryA(npcap_dir, 480); + strcat(npcap_dir, "\\Npcap"); + SetDllDirectoryA(npcap_dir); libpcap_handle = dynld_module("wpcap.dll", pcap_imports); + SetDllDirectoryA(NULL); /* reset the DLL search path */ #elif defined __APPLE__ libpcap_handle = dynld_module("libpcap.dylib", pcap_imports); #else From 0660f08a40732c34ef299cc8f48d25a348417553 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Mar 2024 22:21:31 +0100 Subject: [PATCH 285/690] PB450 fixes. --- src/machine/m_at_386dx_486.c | 25 +++++++++++++------------ src/machine/machine_table.c | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4cfa7447e..9e527e8c3 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -671,25 +671,26 @@ machine_at_pb450_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + device_add(&ide_vlb_2ch_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 5, 4, 3, 2); - pci_register_slot(0x12, PCI_CARD_NORMAL, 9, 8, 7, 6); - - device_add(&opti895_device); - device_add(&opti822_device); - device_add(&keyboard_ps2_intel_ami_pci_device); - device_add(&fdc37c661_ide_device); - device_add(&ide_opti611_vlb_sec_device); - device_add(&ide_vlb_2ch_device); - device_add(&intel_flash_bxt_device); - device_add(&phoenix_486_jumper_pci_device); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); if (gfxcard[0] == VID_INTERNAL) device_add(&gd5428_vlb_onboard_device); + device_add(&opti602_device); + device_add(&opti895_device); + device_add(&opti822_device); + device_add(&keyboard_ps2_ami_device); + device_add(&fdc37c661_ide_device); + device_add(&ide_opti611_vlb_sec_device); + device_add(&intel_flash_bxt_device); + device_add(&phoenix_486_jumper_pci_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 04cc59043..9a7161c7f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6438,7 +6438,7 @@ const machine_t machines[] = { .max = 65536, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, From 3e27bdb86ac9404870abfd577d357119aaa02c98 Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Wed, 20 Mar 2024 23:35:03 +0200 Subject: [PATCH 286/690] Fix broken translation for ZIP drives --- src/qt/qt_settingsotherremovable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index f8b29dac5..36918ad99 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -140,8 +140,8 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) model = new QStandardItemModel(0, 2, this); ui->tableViewZIP->setModel(model); - model->setHeaderData(0, Qt::Horizontal, "Bus"); - model->setHeaderData(1, Qt::Horizontal, "Type"); + model->setHeaderData(0, Qt::Horizontal, tr("Bus")); + model->setHeaderData(1, Qt::Horizontal, tr("Type")); model->insertRows(0, ZIP_NUM); for (int i = 0; i < ZIP_NUM; i++) { auto idx = model->index(i, 0); From 53503cb843e83cc2e5edaa0f24c43ab1065ecadd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Mar 2024 00:47:17 +0100 Subject: [PATCH 287/690] ALi M1217: No on-chip IDE controller. --- src/chipset/ali6117.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index c7ada4bc6..cc2e465a2 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -471,7 +471,8 @@ ali6117_init(const device_t *info) dev->local = info->local; - device_add(&ide_isa_device); + if (!(dev->local & 0x08)) + device_add(&ide_isa_device); ali6117_setup(dev); From 2fd511cc585568a5eb02daf16ee980db93e67dec Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 21:31:16 +0600 Subject: [PATCH 288/690] Add ESFMu for ESFM emulation --- src/cpu/cpu.h | 7 + src/sound/CMakeLists.txt | 2 +- src/sound/esfmu/esfm.c | 2316 ++++++++++++++++++++++++++++++ src/sound/esfmu/esfm.h | 289 ++++ src/sound/esfmu/esfm_registers.c | 999 +++++++++++++ src/sound/snd_opl_esfm.c | 223 +++ 6 files changed, 3835 insertions(+), 1 deletion(-) create mode 100644 src/sound/esfmu/esfm.c create mode 100644 src/sound/esfmu/esfm.h create mode 100644 src/sound/esfmu/esfm_registers.c create mode 100644 src/sound/snd_opl_esfm.c diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 16a9eba10..f2e1242df 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,7 +21,14 @@ #ifndef EMU_CPU_H #define EMU_CPU_H +#ifndef NO_SOFTFLOAT_INCLUDE #include "softfloat/softfloat.h" +#else +typedef struct floatx80 { // leave alignment to compiler + uint64_t exp; + uint16_t fraction; +} floatx80; +#endif enum { FPU_NONE, diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 72f05ff6d..9b2cc1416 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c new file mode 100644 index 000000000..7409603fe --- /dev/null +++ b/src/sound/esfmu/esfm.c @@ -0,0 +1,2316 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - akumanatt + * For helping out with code optimization. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include +#include + +/* + * Log-scale quarter sine table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Extract sine table from ESFM die scans... does ESFM even use a sine + * table? Patent documents give a hint to a possible method of generating sine + * waves using some sort of boolean logic wizardry (lol) + * Optimization: All 8 waveforms are calculated and unfolded from the actual + * data in OPL3's ROM. Negative entries are marked by 0x8000. + */ +static const uint16_t logsinrom[1024*8] = { + // wave 0 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x8859, 0x86c3, 0x8607, 0x858b, 0x852e, 0x84e4, 0x84a6, 0x8471, + 0x8443, 0x841a, 0x83f5, 0x83d3, 0x83b5, 0x8398, 0x837e, 0x8365, + 0x834e, 0x8339, 0x8324, 0x8311, 0x82ff, 0x82ed, 0x82dc, 0x82cd, + 0x82bd, 0x82af, 0x82a0, 0x8293, 0x8286, 0x8279, 0x826d, 0x8261, + 0x8256, 0x824b, 0x8240, 0x8236, 0x822c, 0x8222, 0x8218, 0x820f, + 0x8206, 0x81fd, 0x81f5, 0x81ec, 0x81e4, 0x81dc, 0x81d4, 0x81cd, + 0x81c5, 0x81be, 0x81b7, 0x81b0, 0x81a9, 0x81a2, 0x819b, 0x8195, + 0x818f, 0x8188, 0x8182, 0x817c, 0x8177, 0x8171, 0x816b, 0x8166, + 0x8160, 0x815b, 0x8155, 0x8150, 0x814b, 0x8146, 0x8141, 0x813c, + 0x8137, 0x8133, 0x812e, 0x8129, 0x8125, 0x8121, 0x811c, 0x8118, + 0x8114, 0x810f, 0x810b, 0x8107, 0x8103, 0x80ff, 0x80fb, 0x80f8, + 0x80f4, 0x80f0, 0x80ec, 0x80e9, 0x80e5, 0x80e2, 0x80de, 0x80db, + 0x80d7, 0x80d4, 0x80d1, 0x80cd, 0x80ca, 0x80c7, 0x80c4, 0x80c1, + 0x80be, 0x80bb, 0x80b8, 0x80b5, 0x80b2, 0x80af, 0x80ac, 0x80a9, + 0x80a7, 0x80a4, 0x80a1, 0x809f, 0x809c, 0x8099, 0x8097, 0x8094, + 0x8092, 0x808f, 0x808d, 0x808a, 0x8088, 0x8086, 0x8083, 0x8081, + 0x807f, 0x807d, 0x807a, 0x8078, 0x8076, 0x8074, 0x8072, 0x8070, + 0x806e, 0x806c, 0x806a, 0x8068, 0x8066, 0x8064, 0x8062, 0x8060, + 0x805e, 0x805c, 0x805b, 0x8059, 0x8057, 0x8055, 0x8053, 0x8052, + 0x8050, 0x804e, 0x804d, 0x804b, 0x804a, 0x8048, 0x8046, 0x8045, + 0x8043, 0x8042, 0x8040, 0x803f, 0x803e, 0x803c, 0x803b, 0x8039, + 0x8038, 0x8037, 0x8035, 0x8034, 0x8033, 0x8031, 0x8030, 0x802f, + 0x802e, 0x802d, 0x802b, 0x802a, 0x8029, 0x8028, 0x8027, 0x8026, + 0x8025, 0x8024, 0x8023, 0x8022, 0x8021, 0x8020, 0x801f, 0x801e, + 0x801d, 0x801c, 0x801b, 0x801a, 0x8019, 0x8018, 0x8017, 0x8017, + 0x8016, 0x8015, 0x8014, 0x8014, 0x8013, 0x8012, 0x8011, 0x8011, + 0x8010, 0x800f, 0x800f, 0x800e, 0x800d, 0x800d, 0x800c, 0x800c, + 0x800b, 0x800a, 0x800a, 0x8009, 0x8009, 0x8008, 0x8008, 0x8007, + 0x8007, 0x8007, 0x8006, 0x8006, 0x8005, 0x8005, 0x8005, 0x8004, + 0x8004, 0x8004, 0x8003, 0x8003, 0x8003, 0x8002, 0x8002, 0x8002, + 0x8002, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8002, + 0x8002, 0x8002, 0x8002, 0x8003, 0x8003, 0x8003, 0x8004, 0x8004, + 0x8004, 0x8005, 0x8005, 0x8005, 0x8006, 0x8006, 0x8007, 0x8007, + 0x8007, 0x8008, 0x8008, 0x8009, 0x8009, 0x800a, 0x800a, 0x800b, + 0x800c, 0x800c, 0x800d, 0x800d, 0x800e, 0x800f, 0x800f, 0x8010, + 0x8011, 0x8011, 0x8012, 0x8013, 0x8014, 0x8014, 0x8015, 0x8016, + 0x8017, 0x8017, 0x8018, 0x8019, 0x801a, 0x801b, 0x801c, 0x801d, + 0x801e, 0x801f, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, + 0x8026, 0x8027, 0x8028, 0x8029, 0x802a, 0x802b, 0x802d, 0x802e, + 0x802f, 0x8030, 0x8031, 0x8033, 0x8034, 0x8035, 0x8037, 0x8038, + 0x8039, 0x803b, 0x803c, 0x803e, 0x803f, 0x8040, 0x8042, 0x8043, + 0x8045, 0x8046, 0x8048, 0x804a, 0x804b, 0x804d, 0x804e, 0x8050, + 0x8052, 0x8053, 0x8055, 0x8057, 0x8059, 0x805b, 0x805c, 0x805e, + 0x8060, 0x8062, 0x8064, 0x8066, 0x8068, 0x806a, 0x806c, 0x806e, + 0x8070, 0x8072, 0x8074, 0x8076, 0x8078, 0x807a, 0x807d, 0x807f, + 0x8081, 0x8083, 0x8086, 0x8088, 0x808a, 0x808d, 0x808f, 0x8092, + 0x8094, 0x8097, 0x8099, 0x809c, 0x809f, 0x80a1, 0x80a4, 0x80a7, + 0x80a9, 0x80ac, 0x80af, 0x80b2, 0x80b5, 0x80b8, 0x80bb, 0x80be, + 0x80c1, 0x80c4, 0x80c7, 0x80ca, 0x80cd, 0x80d1, 0x80d4, 0x80d7, + 0x80db, 0x80de, 0x80e2, 0x80e5, 0x80e9, 0x80ec, 0x80f0, 0x80f4, + 0x80f8, 0x80fb, 0x80ff, 0x8103, 0x8107, 0x810b, 0x810f, 0x8114, + 0x8118, 0x811c, 0x8121, 0x8125, 0x8129, 0x812e, 0x8133, 0x8137, + 0x813c, 0x8141, 0x8146, 0x814b, 0x8150, 0x8155, 0x815b, 0x8160, + 0x8166, 0x816b, 0x8171, 0x8177, 0x817c, 0x8182, 0x8188, 0x818f, + 0x8195, 0x819b, 0x81a2, 0x81a9, 0x81b0, 0x81b7, 0x81be, 0x81c5, + 0x81cd, 0x81d4, 0x81dc, 0x81e4, 0x81ec, 0x81f5, 0x81fd, 0x8206, + 0x820f, 0x8218, 0x8222, 0x822c, 0x8236, 0x8240, 0x824b, 0x8256, + 0x8261, 0x826d, 0x8279, 0x8286, 0x8293, 0x82a0, 0x82af, 0x82bd, + 0x82cd, 0x82dc, 0x82ed, 0x82ff, 0x8311, 0x8324, 0x8339, 0x834e, + 0x8365, 0x837e, 0x8398, 0x83b5, 0x83d3, 0x83f5, 0x841a, 0x8443, + 0x8471, 0x84a6, 0x84e4, 0x852e, 0x858b, 0x8607, 0x86c3, 0x8859, + // wave 1 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 2 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + // wave 3 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 4 + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x8859, 0x8607, 0x852e, 0x84a6, 0x8443, 0x83f5, 0x83b5, 0x837e, + 0x834e, 0x8324, 0x82ff, 0x82dc, 0x82bd, 0x82a0, 0x8286, 0x826d, + 0x8256, 0x8240, 0x822c, 0x8218, 0x8206, 0x81f5, 0x81e4, 0x81d4, + 0x81c5, 0x81b7, 0x81a9, 0x819b, 0x818f, 0x8182, 0x8177, 0x816b, + 0x8160, 0x8155, 0x814b, 0x8141, 0x8137, 0x812e, 0x8125, 0x811c, + 0x8114, 0x810b, 0x8103, 0x80fb, 0x80f4, 0x80ec, 0x80e5, 0x80de, + 0x80d7, 0x80d1, 0x80ca, 0x80c4, 0x80be, 0x80b8, 0x80b2, 0x80ac, + 0x80a7, 0x80a1, 0x809c, 0x8097, 0x8092, 0x808d, 0x8088, 0x8083, + 0x807f, 0x807a, 0x8076, 0x8072, 0x806e, 0x806a, 0x8066, 0x8062, + 0x805e, 0x805b, 0x8057, 0x8053, 0x8050, 0x804d, 0x804a, 0x8046, + 0x8043, 0x8040, 0x803e, 0x803b, 0x8038, 0x8035, 0x8033, 0x8030, + 0x802e, 0x802b, 0x8029, 0x8027, 0x8025, 0x8023, 0x8021, 0x801f, + 0x801d, 0x801b, 0x8019, 0x8017, 0x8016, 0x8014, 0x8013, 0x8011, + 0x8010, 0x800f, 0x800d, 0x800c, 0x800b, 0x800a, 0x8009, 0x8008, + 0x8007, 0x8006, 0x8005, 0x8005, 0x8004, 0x8003, 0x8003, 0x8002, + 0x8002, 0x8001, 0x8001, 0x8001, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8002, + 0x8002, 0x8003, 0x8003, 0x8004, 0x8005, 0x8005, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800b, 0x800c, 0x800d, 0x800f, 0x8010, + 0x8011, 0x8013, 0x8014, 0x8016, 0x8017, 0x8019, 0x801b, 0x801d, + 0x801f, 0x8021, 0x8023, 0x8025, 0x8027, 0x8029, 0x802b, 0x802e, + 0x8030, 0x8033, 0x8035, 0x8038, 0x803b, 0x803e, 0x8040, 0x8043, + 0x8046, 0x804a, 0x804d, 0x8050, 0x8053, 0x8057, 0x805b, 0x805e, + 0x8062, 0x8066, 0x806a, 0x806e, 0x8072, 0x8076, 0x807a, 0x807f, + 0x8083, 0x8088, 0x808d, 0x8092, 0x8097, 0x809c, 0x80a1, 0x80a7, + 0x80ac, 0x80b2, 0x80b8, 0x80be, 0x80c4, 0x80ca, 0x80d1, 0x80d7, + 0x80de, 0x80e5, 0x80ec, 0x80f4, 0x80fb, 0x8103, 0x810b, 0x8114, + 0x811c, 0x8125, 0x812e, 0x8137, 0x8141, 0x814b, 0x8155, 0x8160, + 0x816b, 0x8177, 0x8182, 0x818f, 0x819b, 0x81a9, 0x81b7, 0x81c5, + 0x81d4, 0x81e4, 0x81f5, 0x8206, 0x8218, 0x822c, 0x8240, 0x8256, + 0x826d, 0x8286, 0x82a0, 0x82bd, 0x82dc, 0x82ff, 0x8324, 0x834e, + 0x837e, 0x83b5, 0x83f5, 0x8443, 0x84a6, 0x852e, 0x8607, 0x8859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 5 + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 6 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + // wave 7 + 0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038, + 0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078, + 0x0080, 0x0088, 0x0090, 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x00b8, + 0x00c0, 0x00c8, 0x00d0, 0x00d8, 0x00e0, 0x00e8, 0x00f0, 0x00f8, + 0x0100, 0x0108, 0x0110, 0x0118, 0x0120, 0x0128, 0x0130, 0x0138, + 0x0140, 0x0148, 0x0150, 0x0158, 0x0160, 0x0168, 0x0170, 0x0178, + 0x0180, 0x0188, 0x0190, 0x0198, 0x01a0, 0x01a8, 0x01b0, 0x01b8, + 0x01c0, 0x01c8, 0x01d0, 0x01d8, 0x01e0, 0x01e8, 0x01f0, 0x01f8, + 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, 0x0238, + 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, + 0x0280, 0x0288, 0x0290, 0x0298, 0x02a0, 0x02a8, 0x02b0, 0x02b8, + 0x02c0, 0x02c8, 0x02d0, 0x02d8, 0x02e0, 0x02e8, 0x02f0, 0x02f8, + 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338, + 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378, + 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8, + 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8, + 0x0400, 0x0408, 0x0410, 0x0418, 0x0420, 0x0428, 0x0430, 0x0438, + 0x0440, 0x0448, 0x0450, 0x0458, 0x0460, 0x0468, 0x0470, 0x0478, + 0x0480, 0x0488, 0x0490, 0x0498, 0x04a0, 0x04a8, 0x04b0, 0x04b8, + 0x04c0, 0x04c8, 0x04d0, 0x04d8, 0x04e0, 0x04e8, 0x04f0, 0x04f8, + 0x0500, 0x0508, 0x0510, 0x0518, 0x0520, 0x0528, 0x0530, 0x0538, + 0x0540, 0x0548, 0x0550, 0x0558, 0x0560, 0x0568, 0x0570, 0x0578, + 0x0580, 0x0588, 0x0590, 0x0598, 0x05a0, 0x05a8, 0x05b0, 0x05b8, + 0x05c0, 0x05c8, 0x05d0, 0x05d8, 0x05e0, 0x05e8, 0x05f0, 0x05f8, + 0x0600, 0x0608, 0x0610, 0x0618, 0x0620, 0x0628, 0x0630, 0x0638, + 0x0640, 0x0648, 0x0650, 0x0658, 0x0660, 0x0668, 0x0670, 0x0678, + 0x0680, 0x0688, 0x0690, 0x0698, 0x06a0, 0x06a8, 0x06b0, 0x06b8, + 0x06c0, 0x06c8, 0x06d0, 0x06d8, 0x06e0, 0x06e8, 0x06f0, 0x06f8, + 0x0700, 0x0708, 0x0710, 0x0718, 0x0720, 0x0728, 0x0730, 0x0738, + 0x0740, 0x0748, 0x0750, 0x0758, 0x0760, 0x0768, 0x0770, 0x0778, + 0x0780, 0x0788, 0x0790, 0x0798, 0x07a0, 0x07a8, 0x07b0, 0x07b8, + 0x07c0, 0x07c8, 0x07d0, 0x07d8, 0x07e0, 0x07e8, 0x07f0, 0x07f8, + 0x0800, 0x0808, 0x0810, 0x0818, 0x0820, 0x0828, 0x0830, 0x0838, + 0x0840, 0x0848, 0x0850, 0x0858, 0x0860, 0x0868, 0x0870, 0x0878, + 0x0880, 0x0888, 0x0890, 0x0898, 0x08a0, 0x08a8, 0x08b0, 0x08b8, + 0x08c0, 0x08c8, 0x08d0, 0x08d8, 0x08e0, 0x08e8, 0x08f0, 0x08f8, + 0x0900, 0x0908, 0x0910, 0x0918, 0x0920, 0x0928, 0x0930, 0x0938, + 0x0940, 0x0948, 0x0950, 0x0958, 0x0960, 0x0968, 0x0970, 0x0978, + 0x0980, 0x0988, 0x0990, 0x0998, 0x09a0, 0x09a8, 0x09b0, 0x09b8, + 0x09c0, 0x09c8, 0x09d0, 0x09d8, 0x09e0, 0x09e8, 0x09f0, 0x09f8, + 0x0a00, 0x0a08, 0x0a10, 0x0a18, 0x0a20, 0x0a28, 0x0a30, 0x0a38, + 0x0a40, 0x0a48, 0x0a50, 0x0a58, 0x0a60, 0x0a68, 0x0a70, 0x0a78, + 0x0a80, 0x0a88, 0x0a90, 0x0a98, 0x0aa0, 0x0aa8, 0x0ab0, 0x0ab8, + 0x0ac0, 0x0ac8, 0x0ad0, 0x0ad8, 0x0ae0, 0x0ae8, 0x0af0, 0x0af8, + 0x0b00, 0x0b08, 0x0b10, 0x0b18, 0x0b20, 0x0b28, 0x0b30, 0x0b38, + 0x0b40, 0x0b48, 0x0b50, 0x0b58, 0x0b60, 0x0b68, 0x0b70, 0x0b78, + 0x0b80, 0x0b88, 0x0b90, 0x0b98, 0x0ba0, 0x0ba8, 0x0bb0, 0x0bb8, + 0x0bc0, 0x0bc8, 0x0bd0, 0x0bd8, 0x0be0, 0x0be8, 0x0bf0, 0x0bf8, + 0x0c00, 0x0c08, 0x0c10, 0x0c18, 0x0c20, 0x0c28, 0x0c30, 0x0c38, + 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68, 0x0c70, 0x0c78, + 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0, 0x0cb8, + 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8, + 0x0d00, 0x0d08, 0x0d10, 0x0d18, 0x0d20, 0x0d28, 0x0d30, 0x0d38, + 0x0d40, 0x0d48, 0x0d50, 0x0d58, 0x0d60, 0x0d68, 0x0d70, 0x0d78, + 0x0d80, 0x0d88, 0x0d90, 0x0d98, 0x0da0, 0x0da8, 0x0db0, 0x0db8, + 0x0dc0, 0x0dc8, 0x0dd0, 0x0dd8, 0x0de0, 0x0de8, 0x0df0, 0x0df8, + 0x0e00, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38, + 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78, + 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8, + 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8, + 0x0f00, 0x0f08, 0x0f10, 0x0f18, 0x0f20, 0x0f28, 0x0f30, 0x0f38, + 0x0f40, 0x0f48, 0x0f50, 0x0f58, 0x0f60, 0x0f68, 0x0f70, 0x0f78, + 0x0f80, 0x0f88, 0x0f90, 0x0f98, 0x0fa0, 0x0fa8, 0x0fb0, 0x0fb8, + 0x0fc0, 0x0fc8, 0x0fd0, 0x0fd8, 0x0fe0, 0x0fe8, 0x0ff0, 0x0ff8, + 0x8ff8, 0x8ff0, 0x8fe8, 0x8fe0, 0x8fd8, 0x8fd0, 0x8fc8, 0x8fc0, + 0x8fb8, 0x8fb0, 0x8fa8, 0x8fa0, 0x8f98, 0x8f90, 0x8f88, 0x8f80, + 0x8f78, 0x8f70, 0x8f68, 0x8f60, 0x8f58, 0x8f50, 0x8f48, 0x8f40, + 0x8f38, 0x8f30, 0x8f28, 0x8f20, 0x8f18, 0x8f10, 0x8f08, 0x8f00, + 0x8ef8, 0x8ef0, 0x8ee8, 0x8ee0, 0x8ed8, 0x8ed0, 0x8ec8, 0x8ec0, + 0x8eb8, 0x8eb0, 0x8ea8, 0x8ea0, 0x8e98, 0x8e90, 0x8e88, 0x8e80, + 0x8e78, 0x8e70, 0x8e68, 0x8e60, 0x8e58, 0x8e50, 0x8e48, 0x8e40, + 0x8e38, 0x8e30, 0x8e28, 0x8e20, 0x8e18, 0x8e10, 0x8e08, 0x8e00, + 0x8df8, 0x8df0, 0x8de8, 0x8de0, 0x8dd8, 0x8dd0, 0x8dc8, 0x8dc0, + 0x8db8, 0x8db0, 0x8da8, 0x8da0, 0x8d98, 0x8d90, 0x8d88, 0x8d80, + 0x8d78, 0x8d70, 0x8d68, 0x8d60, 0x8d58, 0x8d50, 0x8d48, 0x8d40, + 0x8d38, 0x8d30, 0x8d28, 0x8d20, 0x8d18, 0x8d10, 0x8d08, 0x8d00, + 0x8cf8, 0x8cf0, 0x8ce8, 0x8ce0, 0x8cd8, 0x8cd0, 0x8cc8, 0x8cc0, + 0x8cb8, 0x8cb0, 0x8ca8, 0x8ca0, 0x8c98, 0x8c90, 0x8c88, 0x8c80, + 0x8c78, 0x8c70, 0x8c68, 0x8c60, 0x8c58, 0x8c50, 0x8c48, 0x8c40, + 0x8c38, 0x8c30, 0x8c28, 0x8c20, 0x8c18, 0x8c10, 0x8c08, 0x8c00, + 0x8bf8, 0x8bf0, 0x8be8, 0x8be0, 0x8bd8, 0x8bd0, 0x8bc8, 0x8bc0, + 0x8bb8, 0x8bb0, 0x8ba8, 0x8ba0, 0x8b98, 0x8b90, 0x8b88, 0x8b80, + 0x8b78, 0x8b70, 0x8b68, 0x8b60, 0x8b58, 0x8b50, 0x8b48, 0x8b40, + 0x8b38, 0x8b30, 0x8b28, 0x8b20, 0x8b18, 0x8b10, 0x8b08, 0x8b00, + 0x8af8, 0x8af0, 0x8ae8, 0x8ae0, 0x8ad8, 0x8ad0, 0x8ac8, 0x8ac0, + 0x8ab8, 0x8ab0, 0x8aa8, 0x8aa0, 0x8a98, 0x8a90, 0x8a88, 0x8a80, + 0x8a78, 0x8a70, 0x8a68, 0x8a60, 0x8a58, 0x8a50, 0x8a48, 0x8a40, + 0x8a38, 0x8a30, 0x8a28, 0x8a20, 0x8a18, 0x8a10, 0x8a08, 0x8a00, + 0x89f8, 0x89f0, 0x89e8, 0x89e0, 0x89d8, 0x89d0, 0x89c8, 0x89c0, + 0x89b8, 0x89b0, 0x89a8, 0x89a0, 0x8998, 0x8990, 0x8988, 0x8980, + 0x8978, 0x8970, 0x8968, 0x8960, 0x8958, 0x8950, 0x8948, 0x8940, + 0x8938, 0x8930, 0x8928, 0x8920, 0x8918, 0x8910, 0x8908, 0x8900, + 0x88f8, 0x88f0, 0x88e8, 0x88e0, 0x88d8, 0x88d0, 0x88c8, 0x88c0, + 0x88b8, 0x88b0, 0x88a8, 0x88a0, 0x8898, 0x8890, 0x8888, 0x8880, + 0x8878, 0x8870, 0x8868, 0x8860, 0x8858, 0x8850, 0x8848, 0x8840, + 0x8838, 0x8830, 0x8828, 0x8820, 0x8818, 0x8810, 0x8808, 0x8800, + 0x87f8, 0x87f0, 0x87e8, 0x87e0, 0x87d8, 0x87d0, 0x87c8, 0x87c0, + 0x87b8, 0x87b0, 0x87a8, 0x87a0, 0x8798, 0x8790, 0x8788, 0x8780, + 0x8778, 0x8770, 0x8768, 0x8760, 0x8758, 0x8750, 0x8748, 0x8740, + 0x8738, 0x8730, 0x8728, 0x8720, 0x8718, 0x8710, 0x8708, 0x8700, + 0x86f8, 0x86f0, 0x86e8, 0x86e0, 0x86d8, 0x86d0, 0x86c8, 0x86c0, + 0x86b8, 0x86b0, 0x86a8, 0x86a0, 0x8698, 0x8690, 0x8688, 0x8680, + 0x8678, 0x8670, 0x8668, 0x8660, 0x8658, 0x8650, 0x8648, 0x8640, + 0x8638, 0x8630, 0x8628, 0x8620, 0x8618, 0x8610, 0x8608, 0x8600, + 0x85f8, 0x85f0, 0x85e8, 0x85e0, 0x85d8, 0x85d0, 0x85c8, 0x85c0, + 0x85b8, 0x85b0, 0x85a8, 0x85a0, 0x8598, 0x8590, 0x8588, 0x8580, + 0x8578, 0x8570, 0x8568, 0x8560, 0x8558, 0x8550, 0x8548, 0x8540, + 0x8538, 0x8530, 0x8528, 0x8520, 0x8518, 0x8510, 0x8508, 0x8500, + 0x84f8, 0x84f0, 0x84e8, 0x84e0, 0x84d8, 0x84d0, 0x84c8, 0x84c0, + 0x84b8, 0x84b0, 0x84a8, 0x84a0, 0x8498, 0x8490, 0x8488, 0x8480, + 0x8478, 0x8470, 0x8468, 0x8460, 0x8458, 0x8450, 0x8448, 0x8440, + 0x8438, 0x8430, 0x8428, 0x8420, 0x8418, 0x8410, 0x8408, 0x8400, + 0x83f8, 0x83f0, 0x83e8, 0x83e0, 0x83d8, 0x83d0, 0x83c8, 0x83c0, + 0x83b8, 0x83b0, 0x83a8, 0x83a0, 0x8398, 0x8390, 0x8388, 0x8380, + 0x8378, 0x8370, 0x8368, 0x8360, 0x8358, 0x8350, 0x8348, 0x8340, + 0x8338, 0x8330, 0x8328, 0x8320, 0x8318, 0x8310, 0x8308, 0x8300, + 0x82f8, 0x82f0, 0x82e8, 0x82e0, 0x82d8, 0x82d0, 0x82c8, 0x82c0, + 0x82b8, 0x82b0, 0x82a8, 0x82a0, 0x8298, 0x8290, 0x8288, 0x8280, + 0x8278, 0x8270, 0x8268, 0x8260, 0x8258, 0x8250, 0x8248, 0x8240, + 0x8238, 0x8230, 0x8228, 0x8220, 0x8218, 0x8210, 0x8208, 0x8200, + 0x81f8, 0x81f0, 0x81e8, 0x81e0, 0x81d8, 0x81d0, 0x81c8, 0x81c0, + 0x81b8, 0x81b0, 0x81a8, 0x81a0, 0x8198, 0x8190, 0x8188, 0x8180, + 0x8178, 0x8170, 0x8168, 0x8160, 0x8158, 0x8150, 0x8148, 0x8140, + 0x8138, 0x8130, 0x8128, 0x8120, 0x8118, 0x8110, 0x8108, 0x8100, + 0x80f8, 0x80f0, 0x80e8, 0x80e0, 0x80d8, 0x80d0, 0x80c8, 0x80c0, + 0x80b8, 0x80b0, 0x80a8, 0x80a0, 0x8098, 0x8090, 0x8088, 0x8080, + 0x8078, 0x8070, 0x8068, 0x8060, 0x8058, 0x8050, 0x8048, 0x8040, + 0x8038, 0x8030, 0x8028, 0x8020, 0x8018, 0x8010, 0x8008, 0x8000, +}; + +/* + * Inverse exponent table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Verify if ESFM uses an exponent table or if it possibly uses another + * method to skirt around Yamaha's patents? + * Optimization: All entries are shifted left by one from the actual data in + * OPL3's ROM. + */ +static const uint16_t exprom[256] = { + 0xff4, 0xfea, 0xfde, 0xfd4, 0xfc8, 0xfbe, 0xfb4, 0xfa8, + 0xf9e, 0xf92, 0xf88, 0xf7e, 0xf72, 0xf68, 0xf5c, 0xf52, + 0xf48, 0xf3e, 0xf32, 0xf28, 0xf1e, 0xf14, 0xf08, 0xefe, + 0xef4, 0xeea, 0xee0, 0xed4, 0xeca, 0xec0, 0xeb6, 0xeac, + 0xea2, 0xe98, 0xe8e, 0xe84, 0xe7a, 0xe70, 0xe66, 0xe5c, + 0xe52, 0xe48, 0xe3e, 0xe34, 0xe2a, 0xe20, 0xe16, 0xe0c, + 0xe04, 0xdfa, 0xdf0, 0xde6, 0xddc, 0xdd2, 0xdca, 0xdc0, + 0xdb6, 0xdac, 0xda4, 0xd9a, 0xd90, 0xd88, 0xd7e, 0xd74, + 0xd6a, 0xd62, 0xd58, 0xd50, 0xd46, 0xd3c, 0xd34, 0xd2a, + 0xd22, 0xd18, 0xd10, 0xd06, 0xcfe, 0xcf4, 0xcec, 0xce2, + 0xcda, 0xcd0, 0xcc8, 0xcbe, 0xcb6, 0xcae, 0xca4, 0xc9c, + 0xc92, 0xc8a, 0xc82, 0xc78, 0xc70, 0xc68, 0xc60, 0xc56, + 0xc4e, 0xc46, 0xc3c, 0xc34, 0xc2c, 0xc24, 0xc1c, 0xc12, + 0xc0a, 0xc02, 0xbfa, 0xbf2, 0xbea, 0xbe0, 0xbd8, 0xbd0, + 0xbc8, 0xbc0, 0xbb8, 0xbb0, 0xba8, 0xba0, 0xb98, 0xb90, + 0xb88, 0xb80, 0xb78, 0xb70, 0xb68, 0xb60, 0xb58, 0xb50, + 0xb48, 0xb40, 0xb38, 0xb32, 0xb2a, 0xb22, 0xb1a, 0xb12, + 0xb0a, 0xb02, 0xafc, 0xaf4, 0xaec, 0xae4, 0xade, 0xad6, + 0xace, 0xac6, 0xac0, 0xab8, 0xab0, 0xaa8, 0xaa2, 0xa9a, + 0xa92, 0xa8c, 0xa84, 0xa7c, 0xa76, 0xa6e, 0xa68, 0xa60, + 0xa58, 0xa52, 0xa4a, 0xa44, 0xa3c, 0xa36, 0xa2e, 0xa28, + 0xa20, 0xa18, 0xa12, 0xa0c, 0xa04, 0x9fe, 0x9f6, 0x9f0, + 0x9e8, 0x9e2, 0x9da, 0x9d4, 0x9ce, 0x9c6, 0x9c0, 0x9b8, + 0x9b2, 0x9ac, 0x9a4, 0x99e, 0x998, 0x990, 0x98a, 0x984, + 0x97c, 0x976, 0x970, 0x96a, 0x962, 0x95c, 0x956, 0x950, + 0x948, 0x942, 0x93c, 0x936, 0x930, 0x928, 0x922, 0x91c, + 0x916, 0x910, 0x90a, 0x904, 0x8fc, 0x8f6, 0x8f0, 0x8ea, + 0x8e4, 0x8de, 0x8d8, 0x8d2, 0x8cc, 0x8c6, 0x8c0, 0x8ba, + 0x8b4, 0x8ae, 0x8a8, 0x8a2, 0x89c, 0x896, 0x890, 0x88a, + 0x884, 0x87e, 0x878, 0x872, 0x86c, 0x866, 0x860, 0x85a, + 0x854, 0x850, 0x84a, 0x844, 0x83e, 0x838, 0x832, 0x82c, + 0x828, 0x822, 0x81c, 0x816, 0x810, 0x80c, 0x806, 0x800 +}; + +/* + * Frequency multiplier table multiplied by 2; taken straight from Nuked OPL3 + * source code. + */ +static const uint8_t mt[16] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 +}; + +/* + * This is used during the envelope generation to apply KSL to the envelope by + * determining how much to shift right the keyscale attenuation value before + * adding it to the envelope level. + */ +static const uint8_t kslshift[4] = { + 8, 1, 2, 0 +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * Envelope generator dither table, taken straight from Nuked OPL3 source code. + */ +static const uint8_t eg_incstep[4][4] = { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 0, 1, 0 }, + { 1, 1, 1, 0 } +}; + +/* ------------------------------------------------------------------------- */ +static inline int13 +ESFM_envelope_wavegen(uint3 waveform, int16 phase, uint10 envelope) +{ + int13 out; + uint16 lookup = logsinrom[((uint16)waveform << 10) | (phase & 0x3ff)]; + uint16 level = (lookup & 0x1fff) + (envelope << 3); + if (level > 0x1fff) + { + level = 0x1fff; + } + out = exprom[level & 0xff] >> (level >> 8); + if (lookup & 0x8000) + { + out = -out; + } + return out; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_envelope_calc(esfm_slot *slot) +{ + uint8 nonzero; + uint8 rate; + uint5 rate_hi; + uint2 rate_lo; + uint4 reg_rate = 0; + uint4 ks; + uint8 eg_shift, shift; + bool eg_off; + uint9 eg_rout; + int16 eg_inc; + bool reset = 0; + bool key_on; + bool key_on_signal; + + key_on = *slot->in.key_on; + if (!slot->chip->native_mode) + { + int pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + key_on = *pair_primary->slots[0].in.key_on; + } + } + else if ((slot->channel->channel_idx == 7 || slot->channel->channel_idx == 8) + && slot->slot_idx == 1) + { + key_on = slot->channel->key_on_2; + } + } + + slot->in.eg_output = slot->in.eg_position + (slot->t_level << 2) + + (slot->in.eg_ksl_offset >> kslshift[slot->ksl]); + if (slot->tremolo_en) + { + uint8 tremolo; + if (slot->chip->native_mode) + { + tremolo = slot->channel->chip->tremolo >> ((!slot->tremolo_deep << 1) + 2); + } + else + { + tremolo = slot->channel->chip->tremolo >> ((!slot->chip->emu_tremolo_deep << 1) + 2); + } + slot->in.eg_output += tremolo; + } + + if (slot->in.eg_delay_run && slot->in.eg_delay_counter < 32768) + { + slot->in.eg_delay_counter++; + } + + // triggers on key-on edge + if (key_on && !slot->in.key_on_gate) + { + slot->in.eg_delay_run = 1; + slot->in.eg_delay_counter = 0; + slot->in.eg_delay_transitioned_01 = 0; + slot->in.eg_delay_transitioned_01_gate = 0; + slot->in.eg_delay_transitioned_10 = 0; + slot->in.eg_delay_transitioned_10_gate = 0; + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } + } + else if (!key_on) + { + slot->in.eg_delay_run = 0; + } + + // TODO: is this really how the chip behaves? Can it only transition the envelope delay once? Am I implementing this in a sane way? I feel like this is a roundabout hack. + if ((slot->in.eg_delay_transitioned_10 && !slot->in.eg_delay_transitioned_10_gate) || + (slot->in.eg_delay_transitioned_01 && !slot->in.eg_delay_transitioned_01_gate) + ) + { + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } + if (slot->in.eg_delay_transitioned_10) + { + slot->in.eg_delay_transitioned_10_gate = 1; + } + if (slot->in.eg_delay_transitioned_01) + { + slot->in.eg_delay_transitioned_01_gate = 1; + } + } + + if (key_on && ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode)) + { + key_on_signal = 1; + } else { + key_on_signal = 0; + } + + if (key_on && slot->in.eg_state == EG_RELEASE) + { + + if ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode) + { + reset = 1; + reg_rate = slot->attack_rate; + } + else + { + reg_rate = slot->release_rate; + } + } + else + { + switch (slot->in.eg_state) + { + case EG_ATTACK: + reg_rate = slot->attack_rate; + break; + case EG_DECAY: + reg_rate = slot->decay_rate; + break; + case EG_SUSTAIN: + if (!slot->env_sustaining) + { + reg_rate = slot->release_rate; + } + break; + case EG_RELEASE: + reg_rate = slot->release_rate; + break; + } + } + slot->in.key_on_gate = key_on; + slot->in.phase_reset = reset; + ks = slot->in.keyscale >> ((!slot->ksr) << 1); + nonzero = (reg_rate != 0); + rate = ks + (reg_rate << 2); + rate_hi = rate >> 2; + rate_lo = rate & 0x03; + if (rate_hi & 0x10) + { + rate_hi = 0x0f; + } + eg_shift = rate_hi + slot->chip->eg_clocks; + shift = 0; + if (nonzero) + { + if (rate_hi < 12) + { + if (slot->chip->eg_tick) + { + switch (eg_shift) + { + case 12: + shift = 1; + break; + case 13: + shift = (rate_lo >> 1) & 0x01; + break; + case 14: + shift = rate_lo & 0x01; + break; + default: + break; + } + } + } + else + { + shift = (rate_hi & 0x03) + + eg_incstep[rate_lo][slot->chip->global_timer & 0x03]; + if (shift & 0x04) + { + shift = 0x03; + } + if (!shift) + { + shift = slot->chip->eg_tick; + } + } + } + eg_rout = slot->in.eg_position; + eg_inc = 0; + eg_off = 0; + /* Instant attack */ + if (reset && rate_hi == 0x0f) + { + eg_rout = 0x00; + } + /* Envelope off */ + if ((slot->in.eg_position & 0x1f8) == 0x1f8) + { + eg_off = 1; + } + if (slot->in.eg_state != EG_ATTACK && !reset && eg_off) + { + eg_rout = 0x1ff; + } + switch (slot->in.eg_state) + { + case EG_ATTACK: + if (slot->in.eg_position == 0) + { + slot->in.eg_state = EG_DECAY; + } + else if (key_on_signal && shift > 0 && rate_hi != 0x0f) + { + eg_inc = ~slot->in.eg_position >> (4 - shift); + } + break; + case EG_DECAY: + if ((slot->in.eg_position >> 4) == slot->sustain_lvl) + { + slot->in.eg_state = EG_SUSTAIN; + } + else if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + case EG_SUSTAIN: + case EG_RELEASE: + if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + } + slot->in.eg_position = (eg_rout + eg_inc) & 0x1ff; + /* Key off */ + if (reset) + { + slot->in.eg_state = EG_ATTACK; + } + if (!key_on_signal) + { + slot->in.eg_state = EG_RELEASE; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate(esfm_slot *slot) +{ + esfm_chip *chip; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + + chip = slot->chip; + f_num = slot->f_num; + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !slot->vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << slot->block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + if (slot->slot_idx == 3 && slot->rhy_noise) + { + esfm_slot *prev_slot = &slot->channel->slots[2]; + + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + + chip->rm_tc_bit3 = (prev_slot->in.phase_out >> 3) & 1; + chip->rm_tc_bit5 = (prev_slot->in.phase_out >> 5) & 1; + + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + + switch(slot->rhy_noise) + { + case 1: + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + break; + case 2: + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + break; + case 3: + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + break; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate_emu(esfm_slot *slot) +{ + esfm_chip *chip; + uint3 block; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + int pair_primary_idx; + + chip = slot->chip; + block = slot->channel->slots[0].block; + f_num = slot->channel->slots[0].f_num; + + pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + block = pair_primary->slots[0].block; + f_num = pair_primary->slots[0].f_num; + } + } + + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !chip->emu_vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + // HH + if (slot->channel->channel_idx == 7 && slot->slot_idx == 0) + { + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + } + // TC + if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + chip->rm_tc_bit3 = (phase >> 3) & 1; + chip->rm_tc_bit5 = (phase >> 5) & 1; + } + if (chip->emu_rhy_mode_flags & 0x20) + { + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + if (slot->channel->channel_idx == 7) + { + if (slot->slot_idx == 0) { + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + } + else if (slot->slot_idx == 1) + { + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + } + } + else if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/** + * TODO: Figure out what's ACTUALLY going on inside the real chip! + * This is not accurate at all, but it's the closest I was able to get with + * empirical testing (and it's closer than nothing). + */ +/* ------------------------------------------------------------------------- */ +static int16 +ESFM_slot3_noise3_mod_input_calc(esfm_slot *slot) +{ + esfm_channel *channel = slot->channel; + int16 phase; + int13 output_buf = *channel->slots[1].in.mod_input; + int i; + + // Go through previous slots' partial results and recalculate outputs + // (we skip slot 0 because its calculation happens at the end, not at the beginning) + for (i = 1; i < 3; i++) + { + // double the pitch + phase = channel->slots[i].in.phase_acc >> 8; + if (channel->slots[i].mod_in_level) + { + phase += output_buf >> (7 - channel->slots[i].mod_in_level); + } + output_buf = ESFM_envelope_wavegen(channel->slots[2].waveform, phase, channel->slots[i].in.eg_output); + } + + return output_buf >> (8 - slot->mod_in_level); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate(esfm_slot *slot) +{ + int16 phase = slot->in.phase_out; + if (slot->mod_in_level) + { + if (slot->slot_idx == 3 && slot->rhy_noise == 3) + { + phase += ESFM_slot3_noise3_mod_input_calc(slot); + } + else + { + phase += *slot->in.mod_input >> (7 - slot->mod_in_level); + } + } + slot->in.output = ESFM_envelope_wavegen(slot->waveform, phase, slot->in.eg_output); + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + slot->channel->output[0] += output_value & slot->out_enable[0]; + slot->channel->output[1] += output_value & slot->out_enable[1]; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate_emu(esfm_slot *slot) +{ + const esfm_chip *chip = slot->chip; + uint3 waveform = slot->waveform & (chip->emu_newmode != 0 ? 0x07 : 0x03); + bool rhythm_slot_double_volume = (slot->chip->emu_rhy_mode_flags & 0x20) != 0 + && slot->channel->channel_idx >= 6 && slot->channel->channel_idx < 9; + int16 phase = slot->in.phase_out; + int14 output_value; + + phase += *slot->in.mod_input & slot->in.emu_mod_enable; + slot->in.output = ESFM_envelope_wavegen(waveform, phase, slot->in.eg_output); + output_value = (slot->in.output & slot->in.emu_output_enable) << rhythm_slot_double_volume; + if (chip->emu_newmode) + { + slot->channel->output[0] += output_value & slot->channel->slots[0].out_enable[0]; + slot->channel->output[1] += output_value & slot->channel->slots[0].out_enable[1]; + } + else + { + slot->channel->output[0] += output_value; + slot->channel->output[1] += output_value; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_feedback(esfm_chip *chip) +{ + int channel_idx; + + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_slot *slot = &chip->channels[channel_idx].slots[0]; + uint32 basefreq, phase_offset; + uint3 block; + uint10 f_num; + int32_t wave_out, wave_last; + int32_t phase_feedback; + uint32_t iter_counter; + uint3 waveform; + uint3 mod_in_shift; + uint32_t phase, phase_acc; + uint10 eg_output; + + if (slot->mod_in_level && (chip->native_mode || (slot->in.mod_input == &slot->in.feedback_buf))) + { + if (chip->native_mode) + { + waveform = slot->waveform; + } + else + { + waveform = slot->waveform & (0x03 | (0x02 << (chip->emu_newmode != 0))); + } + f_num = slot->f_num; + block = slot->block; + basefreq = (f_num << block) >> 1; + phase_offset = (basefreq * mt[slot->mult]) >> 1; + mod_in_shift = 7 - slot->mod_in_level; + phase_acc = (uint32_t)(slot->in.phase_acc - phase_offset * 28); + eg_output = slot->in.eg_output; + + // ASM optimizaions! +#if defined(__GNUC__) && defined(__x86_64__) + asm ( + "movzbq %[wave], %%r8 \n\t" + "shll $11, %%r8d \n\t" + "leaq %[sinrom], %%rax \n\t" + "addq %%rax, %%r8 \n\t" + "leaq %[exprom], %%r9 \n\t" + "movzwl %[eg_out], %%r10d \n\t" + "shll $3, %%r10d \n\t" + "xorl %%r11d, %%r11d \n\t" + "movl %%r11d, %[out] \n\t" + "movl $29, %%edx \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "movl %[out], %[p_fb] \n\t" + "addl %%r11d, %[p_fb] \n\t" + "sarl $2, %[p_fb] \n\t" + // wave_last = wave_out + "movl %[out], %%r11d \n\t" + // phase = phase_feedback >> mod_in_shift; + "movl %[p_fb], %%eax \n\t" + "movb %[mod_in], %%cl \n\t" + "sarl %%cl, %%eax \n\t" + // phase += phase_acc >> 9; + "movl %[p_acc], %%ebx \n\t" + "sarl $9, %%ebx \n\t" + "addl %%ebx, %%eax \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "andq $0x3ff, %%rax \n\t" + "movzwl (%%r8, %%rax, 2), %%ebx \n\t" + "movl %%ebx, %%eax \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "movl $0x1fff, %%ecx \n\t" + "andl %%ecx, %%eax \n\t" + "addl %%r10d, %%eax \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmpl %%ecx, %%eax \n\t" + "cmoval %%ecx, %%eax \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "movb %%ah, %%cl \n\t" + "movzbl %%al, %%eax \n\t" + "movzwl (%%r9, %%rax, 2), %[out] \n\t" + "shrl %%cl, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "movl %[out], %%ecx \n\t" + "negl %%ecx \n\t" + "testw %%bx, %%bx \n\t" + "cmovsl %%ecx, %[out] \n\t" + // phase_acc += phase_offset + "addl %[p_off], %[p_acc] \n\t" + // loop + "decl %%edx \n\t" + "jne 1b \n\t" + : [p_fb] "=&r" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out) + : [p_off] "r" (phase_offset), + [mod_in] "r" (mod_in_shift), + [wave] "g" (waveform), + [eg_out] "g" (eg_output), + [sinrom] "m" (logsinrom), + [exprom] "m" (exprom) + : "cc", "ax", "bx", "cx", "dx", "r8", "r9", "r10", "r11" + ); +#elif defined(__GNUC__) && defined(__i386__) + asm ( + "movzbl %b[wave], %%eax \n\t" + "shll $11, %%eax \n\t" + "leal %[sinrom], %%edi \n\t" + "addl %%eax, %%edi \n\t" + "shlw $3, %[eg_out] \n\t" + "xorl %[out], %[out] \n\t" + "movl %[out], %[last] \n\t" + "movl $29, %[i] \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "movl %[out], %%eax \n\t" + "addl %[last], %%eax \n\t" + "sarl $2, %%eax \n\t" + "movl %%eax, %[p_fb] \n\t" + // wave_last = wave_out + "movl %[out], %[last] \n\t" + // phase = phase_feedback >> mod_in_shift; + "movb %[mod_in], %%cl \n\t" + "sarl %%cl, %%eax \n\t" + // phase += phase_acc >> 9; + "movl %[p_acc], %%ebx \n\t" + "shrl $9, %%ebx \n\t" + "addl %%ebx, %%eax \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "andl $0x3ff, %%eax \n\t" + "movzwl (%%edi, %%eax, 2), %%ebx \n\t" + "movl %%ebx, %%eax \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "movl $0x1fff, %%ecx \n\t" + "andl %%ecx, %%eax \n\t" + "addw %[eg_out], %%ax \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmpl %%ecx, %%eax \n\t" + "cmoval %%ecx, %%eax \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "movb %%ah, %%cl \n\t" + "movzbl %%al, %%eax \n\t" + "leal %[exprom], %[out] \n\t" + "movzwl (%[out], %%eax, 2), %[out] \n\t" + "shrl %%cl, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "movl %[out], %%ecx \n\t" + "negl %%ecx \n\t" + "testw %%bx, %%bx \n\t" + "cmovsl %%ecx, %[out] \n\t" + // phase_acc += phase_offset + "addl %[p_off], %[p_acc] \n\t" + // loop + "decl %[i] \n\t" + "jne 1b \n\t" + : [p_fb] "=&m" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out), + [last] "=&m" (wave_last), + [eg_out] "+m" (eg_output) + : [p_off] "m" (phase_offset), + [mod_in] "m" (mod_in_shift), + [wave] "m" (waveform), + [sinrom] "m" (logsinrom), + [exprom] "m" (exprom), + [i] "m" (iter_counter) + : "cc", "ax", "bx", "cx", "di" + ); +#elif defined(__GNUC__) && defined(__arm__) + asm ( + "movs r3, #0 \n\t" + "movs %[out], #0 \n\t" + "ldr r8, =0x1fff \n\t" + "movs r2, #29 \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "adds %[p_fb], %[out], r3 \n\t" + "asrs %[p_fb], %[p_fb], #2 \n\t" + // wave_last = wave_out + "mov r3, %[out] \n\t" + // phase = phase_feedback >> mod_in_shift; + "asr r0, %[p_fb], %[mod_in] \n\t" + // phase += phase_acc >> 9; + "add r0, r0, %[p_acc], asr #9 \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "lsls r0, r0, #22 \n\t" + "lsrs r0, r0, #21 \n\t" + "ldrsh r1, [%[sinrom], r0] \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "and r0, r8, r1 \n\t" + "add r0, r0, %[eg_out], lsl #3 \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmp r0, r8 \n\t" + "it hi \n\t" + "movhi r0, r8 \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "lsrs %[out], r0, #8 \n\t" + "ands r0, r0, #255 \n\t" + "lsls r0, r0, #1 \n\t" + "ldrh r0, [%[exprom], r0] \n\t" + "lsr %[out], r0, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "tst r1, r1 \n\t" + "it mi \n\t" + "negmi %[out], %[out] \n\t" + // phase_acc += phase_offset + "adds %[p_acc], %[p_acc], %[p_off]\n\t" + // loop + "subs r2, r2, #1 \n\t" + "bne 1b \n\t" + : [p_fb] "=&r" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out) + : [p_off] "r" (phase_offset), + [mod_in] "r" (mod_in_shift), + [eg_out] "r" (eg_output), + [sinrom] "r" (logsinrom + waveform * 1024), + [exprom] "r" (exprom) + : "cc", "r0", "r1", "r2", "r3", "r8" + ); +#else + wave_out = 0; + wave_last = 0; + for (iter_counter = 0; iter_counter < 29; iter_counter++) + { + phase_feedback = (wave_out + wave_last) >> 2; + wave_last = wave_out; + phase = phase_feedback >> mod_in_shift; + phase += phase_acc >> 9; + wave_out = ESFM_envelope_wavegen(waveform, phase, eg_output); + phase_acc += phase_offset; + } +#endif + + // TODO: Figure out - is this how the ESFM chip does it, like the + // patent literally says? (it's really hacky...) + // slot->in.output = wave_out; + + // This would be the more canonical way to do it, reusing the rest of + // the synthesis pipeline to finish the calculation: + if (chip->native_mode) + { + slot->in.feedback_buf = phase_feedback; + } + else + { + slot->in.feedback_buf = phase_feedback >> (7 - slot->mod_in_level); + } + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate(slot); + if(slot_idx > 0) + { + ESFM_slot_generate(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel_emu(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 2; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate_emu(slot); + if(slot_idx > 0) + { + ESFM_slot_generate_emu(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware +} + +/* ------------------------------------------------------------------------- */ +static int16_t +ESFM_clip_sample(int32 sample) +{ + // TODO: Supposedly, the real ESFM chip actually overflows rather than + // clipping. Verify that. + if (sample > 32767) + { + sample = 32767; + } + else if (sample < -32768) + { + sample = -32768; + } + return (int16_t)sample; +} + +#define TIMER1_CONST (0.2517482517482517) +#define TIMER2_CONST (0.06293706293706293) +/* ------------------------------------------------------------------------- */ +static void +ESFM_update_timers(esfm_chip *chip) +{ + int i; + // Tremolo + if ((chip->global_timer & 0x3f) == 0x3f) + { + chip->tremolo_pos = (chip->tremolo_pos + 1) % 210; + if (chip->tremolo_pos < 105) + { + chip->tremolo = chip->tremolo_pos; + } + else + { + chip->tremolo = (210 - chip->tremolo_pos); + } + } + + // Vibrato + if ((chip->global_timer & 0x3ff) == 0x3ff) + { + chip->vibrato_pos = (chip->vibrato_pos + 1) & 0x07; + } + + chip->global_timer = (chip->global_timer + 1) & 0x3ff; + + // Envelope generator dither clocks + chip->eg_clocks = 0; + if (chip->eg_timer) + { + uint8 shift = 0; + while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) + { + shift++; + } + + if (shift <= 12) + { + chip->eg_clocks = shift + 1; + } + } + + if (chip->eg_tick || chip->eg_timer_overflow) + { + if (chip->eg_timer == (1llu << 36) - 1) + { + chip->eg_timer = 0; + chip->eg_timer_overflow = 1; + } + else + { + chip->eg_timer++; + chip->eg_timer_overflow = 0; + } + } + + for (i = 0; i < 2; i++) + { + if (chip->timer_enable[i]) + { + chip->timer_accumulator[i] += i == 0 ? TIMER1_CONST : TIMER2_CONST; + if (chip->timer_accumulator[i] > 1.0) + { + chip->timer_accumulator[i] -= 1.0; + chip->timer_counter[i]++; + if (chip->timer_counter[i] == 0) + { + if (chip->timer_mask[i] == 0) + { + chip->timer_overflow[i] = true; + } + chip->timer_counter[i] = chip->timer_reload[i]; + } + } + } + } + + chip->eg_tick ^= 1; +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +/* ------------------------------------------------------------------------- */ +int +ESFM_reg_write_chan_idx(esfm_chip *chip, uint16_t reg) +{ + int which_reg = -1; + if (chip->native_mode) + { + bool is_key_on_reg = reg >= KEY_ON_REGS_START && reg < (KEY_ON_REGS_START + 20); + if (is_key_on_reg) + { + which_reg = reg - KEY_ON_REGS_START; + } + } + else + { + uint8_t reg_low = reg & 0xff; + bool high = reg & 0x100; + bool is_key_on_reg = reg_low >= 0xb0 && reg_low < 0xb9; + if (is_key_on_reg) + { + which_reg = (reg_low & 0x0f) + high * 9; + } + } + + return which_reg; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_update_write_buffer(esfm_chip *chip) +{ + esfm_write_buf *write_buf; + bool note_off_written[20]; + bool bassdrum_written = false; + int i; + for (i = 0; i < 20; i++) + { + note_off_written[i] = false; + } + while((write_buf = &chip->write_buf[chip->write_buf_start]), + write_buf->valid && write_buf->timestamp <= chip->write_buf_timestamp) + { + int is_which_note_on_reg = + ESFM_reg_write_chan_idx(chip, write_buf->address); + if (is_which_note_on_reg >= 0) + { + if ((chip->native_mode && (write_buf->data & 0x01) == 0) + || (!chip->native_mode && (write_buf->data & 0x20) == 0) + ) + { + // this is a note off command; note down that we got note off for this channel + note_off_written[is_which_note_on_reg] = true; + } + else + { + // this is a note on command; have we gotten a note off for this channel in this cycle? + if (note_off_written[is_which_note_on_reg]) + { + // we have a conflict; let the note off be processed first and defer the + // rest of the buffer to the next cycle + break; + } + } + } + if ((chip->native_mode && write_buf->address == 0x4bd) + || (!chip->native_mode && (write_buf->address & 0xff) == 0xbd) + ) + { + // bassdrum register write (rhythm mode note-on/off control) + // have we already written to the bassdrum register in this cycle + if (bassdrum_written) { + // we have a conflict + break; + } + bassdrum_written = true; + } + + write_buf->valid = 0; + ESFM_write_reg(chip, write_buf->address, write_buf->data); + chip->write_buf_start = (chip->write_buf_start + 1) % ESFM_WRITEBUF_SIZE; + } + + chip->write_buf_timestamp++; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate(esfm_chip *chip, int16_t *buf) +{ + int channel_idx; + + chip->output_accm[0] = chip->output_accm[1] = 0; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + if (chip->native_mode) + { + ESFM_process_channel(channel); + } + else + { + ESFM_process_channel_emu(channel); + } + } + ESFM_process_feedback(chip); + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + if (chip->native_mode) + { + ESFM_slot_generate(&channel->slots[0]); + } + else + { + ESFM_slot_generate_emu(&channel->slots[0]); + } + chip->output_accm[0] += channel->output[0]; + chip->output_accm[1] += channel->output[1]; + } + + buf[0] = ESFM_clip_sample(chip->output_accm[0]); + buf[1] = ESFM_clip_sample(chip->output_accm[1]); + + ESFM_update_timers(chip); + ESFM_update_write_buffer(chip); +} + +/* ------------------------------------------------------------------------- */ +int16_t +ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx) +{ + int16_t result; + int32_t temp_mix = 0; + int i; + + if (channel_idx < 0 || channel_idx >= 18) + { + return 0; + } + + for (i = 0; i < 4; i++) + { + esfm_slot *slot = &chip->channels[channel_idx].slots[i]; + + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + temp_mix += output_value & slot->out_enable[0]; + temp_mix += output_value & slot->out_enable[1]; + } + } + + if (temp_mix > 32767) + { + temp_mix = 32767; + } + else if (temp_mix < -32768) + { + temp_mix = -32768; + } + result = temp_mix; + return result; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples) +{ + uint32_t i; + + for (i = 0; i < num_samples; i++) + { + ESFM_generate(chip, sndptr); + sndptr += 2; + } +} diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h new file mode 100644 index 000000000..41ac6983f --- /dev/null +++ b/src/sound/esfmu/esfm.h @@ -0,0 +1,289 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - akumanatt + * For helping out with code optimization. + * - And everybody who helped out with real hardware testing + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _esfm_slot esfm_slot; +typedef struct _esfm_slot_internal esfm_slot_internal; +typedef struct _esfm_channel esfm_channel; +typedef struct _esfm_chip esfm_chip; + + +void ESFM_init (esfm_chip *chip); +void ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data); +uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); +uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); +void ESFM_generate(esfm_chip *chip, int16_t *buf); +void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); +int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); + + +// These are fake types just for syntax sugar. +// Beware of their underlying types when reading/writing to them. +typedef uint8_t flag; +typedef uint8_t uint2; +typedef uint8_t uint3; +typedef uint8_t uint4; +typedef uint8_t uint5; +typedef uint8_t uint6; +typedef uint8_t uint8; +typedef uint16_t uint9; +typedef uint16_t uint10; +typedef uint16_t uint11; +typedef uint16_t uint12; +typedef uint16_t uint16; +typedef uint32_t uint19; +typedef uint32_t uint23; +typedef uint32_t uint32; +typedef uint64_t uint36; + +typedef int16_t int13; +typedef int16_t int14; +typedef int16_t int16; +typedef int32_t int32; + +enum eg_states +{ + EG_ATTACK, + EG_DECAY, + EG_SUSTAIN, + EG_RELEASE +}; + + +typedef struct _esfm_write_buf +{ + uint64_t timestamp; + uint16_t address; + uint8_t data; + flag valid; + +} esfm_write_buf; + +typedef struct _emu_slot_channel_mapping +{ + int channel_idx; + int slot_idx; + +} emu_slot_channel_mapping; + +typedef struct _esfm_slot_internal +{ + uint9 eg_position; + uint9 eg_ksl_offset; + uint10 eg_output; + + uint4 keyscale; + + int13 output; + int13 emu_output_enable; + int13 emu_mod_enable; + int13 feedback_buf; + int13 *mod_input; + + uint19 phase_acc; + uint10 phase_out; + flag phase_reset; + flag *key_on; + flag key_on_gate; + + uint2 eg_state; + flag eg_delay_run; + flag eg_delay_transitioned_10; + flag eg_delay_transitioned_10_gate; + flag eg_delay_transitioned_01; + flag eg_delay_transitioned_01_gate; + uint16 eg_delay_counter; + uint16 eg_delay_counter_compare; + +} esfm_slot_internal; + +struct _esfm_slot +{ + // Metadata + esfm_channel *channel; + esfm_chip *chip; + uint2 slot_idx; + + // Register data + int13 out_enable[2]; + uint10 f_num; + uint3 block; + uint3 output_level; + // a.k.a. feedback level in emu mode + uint3 mod_in_level; + + uint6 t_level; + uint4 mult; + uint3 waveform; + // Only for 4th slot + uint2 rhy_noise; + + uint4 attack_rate; + uint4 decay_rate; + uint4 sustain_lvl; + uint4 release_rate; + + flag tremolo_en; + flag tremolo_deep; + flag vibrato_en; + flag vibrato_deep; + flag emu_connection_typ; + flag env_sustaining; + flag ksr; + uint2 ksl; + uint3 env_delay; + // overlaps with env_delay bit 0 + // TODO: check if emu mode only uses this, or if it actually overwrites the channel field used by native mode + flag emu_key_on; + + // Internal state + esfm_slot_internal in; +}; + +struct _esfm_channel +{ + esfm_chip *chip; + esfm_slot slots[4]; + uint5 channel_idx; + int16 output[2]; + flag key_on; + flag emu_mode_4op_enable; + // Only for 17th and 18th channels + flag key_on_2; + flag emu_mode_4op_enable_2; +}; + +#define ESFM_WRITEBUF_SIZE 1024 +#define ESFM_WRITEBUF_DELAY 2 + +struct _esfm_chip +{ + esfm_channel channels[18]; + int32 output_accm[2]; + uint16 addr_latch; + + flag emu_wavesel_enable; + flag emu_newmode; + flag native_mode; + + flag keyscale_mode; + + // Global state + uint36 eg_timer; + uint10 global_timer; + uint8 eg_clocks; + flag eg_tick; + flag eg_timer_overflow; + uint8 tremolo; + uint8 tremolo_pos; + uint8 vibrato_pos; + uint23 lfsr; + + flag rm_hh_bit2; + flag rm_hh_bit3; + flag rm_hh_bit7; + flag rm_hh_bit8; + flag rm_tc_bit3; + flag rm_tc_bit5; + + // 0xbd register in emulation mode, exposed in 0x4bd in native mode + // ("bass drum" register) + uint8 emu_rhy_mode_flags; + + flag emu_vibrato_deep; + flag emu_tremolo_deep; + + double timer_accumulator[2]; + uint8 timer_reload[2]; + uint8 timer_counter[2]; + flag timer_enable[2]; + flag timer_mask[2]; + flag timer_overflow[2]; + flag irq_bit; + + // -- Test bits (NOT IMPLEMENTED) -- + // Halts the envelope generators from advancing. Written on bit 0, read back from bit 5. + flag test_bit_w0_r5_eg_halt; + /* + * Activates some sort of waveform test mode that amplifies the output volume greatly + * and continuously shifts the waveform table downwards, possibly also outputting the + * waveform's derivative? (it's so weird!) + */ + flag test_bit_1_distort; + // Seems to do nothing. + flag test_bit_2; + // Seems to do nothing. + flag test_bit_3; + // Appears to attenuate the output by about 3 dB. + flag test_bit_4_attenuate; + // Written on bit 5, read back from bit 0. Seems to do nothing. + flag test_bit_w5_r0; + // Resets all phase generators and holds them in the reset state while this bit is set. + flag test_bit_6_phase_stop_reset; + // Seems to do nothing. + flag test_bit_7; + + esfm_write_buf write_buf[ESFM_WRITEBUF_SIZE]; + size_t write_buf_start; + size_t write_buf_end; + uint64_t write_buf_timestamp; +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c new file mode 100644 index 000000000..34ce8b19e --- /dev/null +++ b/src/sound/esfmu/esfm_registers.c @@ -0,0 +1,999 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include + + +/* + * Table of KSL values extracted from OPL3 ROM; taken straight from Nuked OPL3 + * source code. + * TODO: Check if ESFM uses the same KSL values. + */ + +static const int16 kslrom[16] = { + 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 +}; + +/* + * This maps the low 5 bits of emulation mode address to an emulation mode + * slot; taken straight from Nuked OPL3. Used for decoding certain emulation + * mode address ranges. + */ +static const int8_t ad_slot[0x20] = { + 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, + 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* + * This maps an emulation mode slot index to a tuple representing the + * corresponding native mode channel and slot. + */ +static const emu_slot_channel_mapping emu_slot_map[36] = +{ + { 0, 0}, { 1, 0}, { 2, 0}, { 0, 1}, { 1, 1}, { 2, 1}, + { 3, 0}, { 4, 0}, { 5, 0}, { 3, 1}, { 4, 1}, { 5, 1}, + { 6, 0}, { 7, 0}, { 8, 0}, { 6, 1}, { 7, 1}, { 8, 1}, + { 9, 0}, {10, 0}, {11, 0}, { 9, 1}, {10, 1}, {11, 1}, + {12, 0}, {13, 0}, {14, 0}, {12, 1}, {13, 1}, {14, 1}, + {15, 0}, {16, 0}, {17, 0}, {15, 1}, {16, 1}, {17, 1} +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * This encodes the operator outputs to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1, OP2, OP3, OP4 + */ +static const bool emu_4op_alg_output_enable[4][4] = +{ + {0, 0, 0, 1}, + {0, 1, 0, 1}, + {1, 0, 0, 1}, + {1, 0, 1, 1} +}; + +/* + * This encodes the operator interconnections to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1FB, OP1->2, OP2->3, OP3->4 + */ +static const bool emu_4op_alg_mod_enable[4][4] = +{ + {1, 1, 1, 1}, + {1, 1, 0, 1}, + {1, 0, 1, 1}, + {1, 0, 1, 0} +}; + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_rearrange_connections(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + uint2 algorithm = ((channel->slots[0].emu_connection_typ != 0) << 1) + | (secondary->slots[0].emu_connection_typ != 0); + int i; + + secondary->slots[0].in.mod_input = &channel->slots[1].in.output; + + for (i = 0; i < 2; i++) + { + channel->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i] ? ~((int13) 0) : 0; + channel->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i] ? ~((int13) 0) : 0; + + secondary->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + secondary->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + } + } + else if ((channel->chip->emu_rhy_mode_flags & 0x20) != 0 + && (channel->channel_idx == 7 || channel->channel_idx == 8)) + { + channel->slots[0].in.emu_mod_enable = 0; + channel->slots[1].in.emu_mod_enable = 0; + channel->slots[0].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_output_enable = ~((int13) 0); + } + else + { + channel->slots[0].in.mod_input = &channel->slots[0].in.feedback_buf; + + channel->slots[0].in.emu_mod_enable = ~((int13) 0); + channel->slots[0].in.emu_output_enable = + (channel->slots[0].emu_connection_typ != 0) ? ~((int13) 0) : 0; + channel->slots[1].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_mod_enable = + (channel->slots[0].emu_connection_typ != 0) ? 0 : ~((int13) 0); + } +} + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_to_native_switch(esfm_chip *chip) +{ + size_t channel_idx, slot_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + esfm_slot *slot = &channel->slots[slot_idx]; + + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_native_to_emu_switch(esfm_chip *chip) +{ + size_t channel_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + ESFM_emu_rearrange_connections(&chip->channels[channel_idx]); + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_update_keyscale(esfm_slot *slot) +{ + if (slot->slot_idx > 0 && !slot->chip->native_mode) + { + return; + } + + int16 ksl = (kslrom[slot->f_num >> 6] << 2) - ((0x08 - slot->block) << 5); + if (ksl < 0) + { + ksl = 0; + } + slot->in.eg_ksl_offset = ksl; + slot->in.keyscale = (slot->block << 1) + | ((slot->f_num >> (8 + !slot->chip->keyscale_mode)) & 0x01); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_channel_update_keyscale(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + ESFM_slot_update_keyscale(&channel->slots[0]); + channel->slots[1].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + channel->slots[1].in.keyscale = channel->slots[0].in.keyscale; + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + int i; + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + secondary->slots[0].f_num = channel->slots[0].f_num; + secondary->slots[0].block = channel->slots[0].block; + + for (i = 0; i < 2; i++) + { + secondary->slots[i].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + secondary->slots[i].in.keyscale = channel->slots[0].in.keyscale; + } + } +} + +/* ------------------------------------------------------------------------- */ +static inline uint8_t +ESFM_slot_readback (esfm_slot *slot, uint8_t register_idx) +{ + uint8_t data = 0; + switch (register_idx & 0x07) + { + case 0x00: + data |= (slot->tremolo_en != 0) << 7; + data |= (slot->vibrato_en != 0) << 6; + data |= (slot->env_sustaining != 0) << 5; + data |= (slot->vibrato_en != 0) << 4; + data |= slot->mult & 0x0f; + break; + case 0x01: + data |= slot->ksl << 6; + data |= slot->t_level & 0x3f; + break; + case 0x02: + data |= slot->attack_rate << 4; + data |= slot->decay_rate & 0x0f; + break; + case 0x03: + data |= slot->sustain_lvl << 4; + data |= slot->release_rate & 0x0f; + break; + case 0x04: + data = slot->f_num & 0xff; + break; + case 0x05: + data |= slot->env_delay << 5; + data |= (slot->block & 0x07) << 2; + data |= (slot->f_num >> 8) & 0x03; + break; + case 0x06: + data |= (slot->tremolo_deep != 0) << 7; + data |= (slot->vibrato_deep != 0) << 6; + data |= (slot->out_enable[1] != 0) << 5; + data |= (slot->out_enable[0] != 0) << 4; + data |= (slot->mod_in_level & 0x07) << 1; + data |= slot->emu_connection_typ & 0x01; + break; + case 0x07: + data |= slot->output_level << 5; + data |= (slot->rhy_noise & 0x03) << 3; + data |= slot->waveform & 0x07; + break; + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static inline void +ESFM_slot_write (esfm_slot *slot, uint8_t register_idx, uint8_t data) +{ + switch (register_idx & 0x07) + { + case 0x00: + slot->tremolo_en = (data & 0x80) != 0; + slot->vibrato_en = (data & 0x40) != 0; + slot->env_sustaining = (data & 0x20) != 0; + slot->ksr = (data & 0x10) != 0; + slot->mult = data & 0x0f; + break; + case 0x01: + slot->ksl = data >> 6; + slot->t_level = data & 0x3f; + ESFM_slot_update_keyscale(slot); + break; + case 0x02: + slot->attack_rate = data >> 4; + slot->decay_rate = data & 0x0f; + break; + case 0x03: + slot->sustain_lvl = data >> 4; + slot->release_rate = data & 0x0f; + break; + case 0x04: + slot->f_num = (slot->f_num & 0x300) | data; + ESFM_slot_update_keyscale(slot); + break; + case 0x05: + if (slot->env_delay < (data >> 5)) + { + slot->in.eg_delay_transitioned_01 = 1; + } + else if (slot->env_delay > (data >> 5)) + { + slot->in.eg_delay_transitioned_10 = 1; + } + slot->env_delay = data >> 5; + slot->emu_key_on = (data >> 5) & 0x01; + slot->block = (data >> 2) & 0x07; + slot->f_num = (slot->f_num & 0xff) | ((data & 0x03) << 8); + ESFM_slot_update_keyscale(slot); + break; + case 0x06: + slot->tremolo_deep = (data & 0x80) != 0; + slot->vibrato_deep = (data & 0x40) != 0; + slot->out_enable[1] = (data & 0x20) ? ~((int13) 0) : 0; + slot->out_enable[0] = (data & 0x10) ? ~((int13) 0) : 0; + slot->mod_in_level = (data >> 1) & 0x07; + slot->emu_connection_typ = data & 0x01; + break; + case 0x07: + slot->output_level = data >> 5; + slot->rhy_noise = (data >> 3) & 0x03; + slot->waveform = data & 0x07; + break; + } +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +#define TIMER1_REG (0x402) +#define TIMER2_REG (0x403) +#define TIMER_SETUP_REG (0x404) +#define CONFIG_REG (0x408) +#define BASSDRUM_REG (0x4bd) +#define TEST_REG (0x501) +#define FOUROP_CONN_REG (0x504) +#define NATIVE_MODE_REG (0x505) + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_native (esfm_chip *chip, uint16_t address, uint8_t data) +{ + int i; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register write + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + ESFM_slot_write(slot, register_idx, data); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + channel->key_on_2 = data & 0x01; + channel->emu_mode_4op_enable_2 = (data & 0x02) != 0; + } + else + { + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + chip->timer_reload[0] = data; + break; + case TIMER2_REG: + chip->timer_reload[1] = data; + break; + case TIMER_SETUP_REG: + if (data & 0x80) + { + chip->timer_overflow[0] = 0; + chip->timer_overflow[1] = 0; + chip->irq_bit = 0; + } + chip->timer_enable[0] = (data & 0x01) != 0; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + break; + case CONFIG_REG: + chip->keyscale_mode = (data & 0x40) != 0; + break; + case BASSDRUM_REG: + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + break; + case TEST_REG: + chip->test_bit_w0_r5_eg_halt = (data & 0x01) | ((data & 0x20) != 0); + chip->test_bit_1_distort = (data & 0x02) != 0; + chip->test_bit_2 = (data & 0x04) != 0; + chip->test_bit_3 = (data & 0x08) != 0; + chip->test_bit_4_attenuate = (data & 0x10) != 0; + chip->test_bit_w5_r0 = (data & 0x20) != 0; + chip->test_bit_6_phase_stop_reset = (data & 0x40) != 0; + chip->test_bit_7 = (data & 0x80) != 0; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +static uint8_t +ESFM_readback_reg_native (esfm_chip *chip, uint16_t address) +{ + int i; + uint8_t data = 0; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register read + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + data = ESFM_slot_readback(slot, register_idx); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + data |= channel->key_on_2 != 0; + data |= (channel->emu_mode_4op_enable_2 != 0) << 1; + } + else + { + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + data = chip->timer_reload[0]; + break; + case TIMER2_REG: + data = chip->timer_reload[1]; + break; + case TIMER_SETUP_REG: + data |= chip->timer_enable[0] != 0; + data |= (chip->timer_enable[1] != 0) << 1; + data |= (chip->timer_mask[0] != 0) << 5; + data |= (chip->timer_mask[1] != 0) << 6; + break; + case CONFIG_REG: + data |= (chip->keyscale_mode != 0) << 6; + break; + case BASSDRUM_REG: + data |= chip->emu_rhy_mode_flags; + data |= chip->emu_vibrato_deep << 6; + data |= chip->emu_tremolo_deep << 7; + break; + case TEST_REG: + data |= chip->test_bit_w5_r0 != 0; + data |= (chip->test_bit_1_distort != 0) << 1; + data |= (chip->test_bit_2 != 0) << 2; + data |= (chip->test_bit_3 != 0) << 3; + data |= (chip->test_bit_4_attenuate != 0) << 4; + data |= (chip->test_bit_w0_r5_eg_halt != 0) << 5; + data |= (chip->test_bit_6_phase_stop_reset != 0) << 6; + data |= (chip->test_bit_7 != 0) << 7; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + data |= (chip->channels[i].emu_mode_4op_enable != 0) << i; + data |= (chip->channels[i + 9].emu_mode_4op_enable != 0) << (i + 3); + } + break; + case NATIVE_MODE_REG: + data |= (chip->emu_newmode != 0); + data |= (chip->native_mode != 0) << 7; + break; + } + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) +{ + bool high = (address & 0x100) != 0; + uint8_t reg = address & 0xff; + int emu_slot_idx = ad_slot[address & 0x1f]; + int natv_chan_idx = -1; + int natv_slot_idx = -1; + int emu_chan_idx = (reg & 0x0f) > 8 ? -1 : ((reg & 0x0f) + high * 9); + + if (emu_slot_idx >= 0) + { + if (high) + { + emu_slot_idx += 18; + } + + natv_chan_idx = emu_slot_map[emu_slot_idx].channel_idx; + natv_slot_idx = emu_slot_map[emu_slot_idx].slot_idx; + } + + if (reg == 0xbd) + { + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + if (chip->emu_rhy_mode_flags & 0x20) + { + // TODO: check if writes to 0xbd actually affect the readable key-on flags at + // 0x246, 0x247, 0x248; and if there's any visible effect from the SD and TC flags + chip->channels[6].key_on = (data & 0x10) != 0; + chip->channels[7].key_on = (data & 0x01) != 0; + chip->channels[8].key_on = (data & 0x04) != 0; + chip->channels[7].key_on_2 = (data & 0x08) != 0; + chip->channels[8].key_on_2 = (data & 0x02) != 0; + } + ESFM_emu_rearrange_connections(&chip->channels[7]); + ESFM_emu_rearrange_connections(&chip->channels[8]); + return; + } + + switch(reg & 0xf0) + { + case 0x00: + if (high) + { + int i; + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + for (i = 0; i < 6; i++) + { + ESFM_emu_rearrange_connections(&chip->channels[i]); + ESFM_emu_rearrange_connections(&chip->channels[i + 9]); + } + break; + case 0x05: + chip->emu_newmode = data & 0x01; + if ((data & 0x80) != 0) + { + chip->native_mode = 1; + ESFM_emu_to_native_switch(chip); + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + else + { + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + chip->timer_enable[0] = data & 0x01; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + if (data & 0x80) + { + chip->irq_bit = 0; + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + break; + case 0x20: case 0x30: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x0, data); + } + break; + case 0x40: case 0x50: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x1, data); + ESFM_emu_channel_update_keyscale(&chip->channels[natv_chan_idx]); + } + break; + case 0x60: case 0x70: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x2, data); + } + break; + case 0x80: case 0x90: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x3, data); + } + break; + case 0xa0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x4, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xb0: + if (emu_chan_idx >= 0) + { + esfm_channel *channel = &chip->channels[emu_chan_idx]; + // TODO: check if emulation mode actually writes to the native mode key on registers + // it might only use slot 0's emu key on field... + channel->key_on = (data & 0x20) != 0; + if (channel->channel_idx == 7 || channel->channel_idx == 8) + { + channel->key_on_2 = (data & 0x20) != 0; + } + ESFM_slot_write(&channel->slots[0], 0x5, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xc0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x6, data); + ESFM_emu_rearrange_connections(&chip->channels[emu_chan_idx]); + } + break; + case 0xe0: case 0xf0: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x7, data); + } + break; + } +} + + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data) +{ + if (chip->native_mode) + { + ESFM_write_reg_native(chip, address, data); + return; + } + else + { + ESFM_write_reg_emu(chip, address, data); + return; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data) +{ + uint64_t timestamp; + esfm_write_buf *new_entry, *last_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + last_entry = &chip->write_buf[(chip->write_buf_end - 1) % ESFM_WRITEBUF_SIZE]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + timestamp = last_entry->timestamp + ESFM_WRITEBUF_DELAY; + if (timestamp < chip->write_buf_timestamp) + { + timestamp = chip->write_buf_timestamp; + } + + new_entry->timestamp = timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data) +{ + esfm_write_buf *new_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + new_entry->timestamp = chip->write_buf_timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_readback_reg (esfm_chip *chip, uint16_t address) +{ + if (chip->native_mode) + { + return ESFM_readback_reg_native(chip, address); + } + else + { + return 0; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data) +{ + if (chip->native_mode) + { + switch(offset) + { + case 0: + chip->native_mode = 0; + ESFM_native_to_emu_switch(chip); + // TODO: verify if the address write goes through + chip->addr_latch = data; + break; + case 1: + ESFM_write_reg_native(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (chip->addr_latch & 0xff00) | data; + break; + case 3: + chip->addr_latch = chip->addr_latch & 0xff; + chip->addr_latch |= (uint16)data << 8; + break; + } + } + else + { + switch(offset) + { + case 0: + chip->addr_latch = data; + break; + case 1: case 3: + ESFM_write_reg_emu(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (uint16)data | 0x100; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_read_port (esfm_chip *chip, uint8_t offset) +{ + uint8_t data = 0; + + switch(offset) + { + case 0: + data |= (chip->irq_bit != 0) << 7; + data |= (chip->timer_overflow[0] != 0) << 6; + data |= (chip->timer_overflow[1] != 0) << 5; + break; + case 1: + if (chip->native_mode) + { + data = ESFM_readback_reg_native(chip, chip->addr_latch); + } + else + { + data = 0; + } + break; + case 2: case 3: + // This matches OPL3 behavior. + data = 0xff; + break; + } + + return data; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_set_mode (esfm_chip *chip, bool native_mode) +{ + native_mode = native_mode != 0; + + if (native_mode != (chip->native_mode != 0)) + { + chip->native_mode = native_mode; + if (native_mode) + { + ESFM_emu_to_native_switch(chip); + } + else + { + ESFM_native_to_emu_switch(chip); + } + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_init (esfm_chip *chip) +{ + esfm_slot *slot; + esfm_channel *channel; + size_t channel_idx, slot_idx; + + memset(chip, 0, sizeof(esfm_chip)); + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + channel = &chip->channels[channel_idx]; + slot = &channel->slots[slot_idx]; + + channel->chip = chip; + channel->channel_idx = channel_idx; + slot->channel = channel; + slot->chip = chip; + slot->slot_idx = slot_idx; + slot->in.eg_position = slot->in.eg_output = 0x1ff; + slot->in.eg_state = EG_RELEASE; + slot->in.emu_mod_enable = ~((int13) 0); + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + + if (slot_idx == 1) + { + slot->in.emu_output_enable = ~((int13) 0); + } + + if (channel_idx > 15 && slot_idx & 0x02) + { + slot->in.key_on = &channel->key_on_2; + } + else + { + slot->in.key_on = &channel->key_on; + } + + slot->out_enable[0] = slot->out_enable[1] = ~((int13) 0); + } + } + + chip->lfsr = 1; +} + diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c new file mode 100644 index 000000000..f7372730c --- /dev/null +++ b/src/sound/snd_opl_esfm.c @@ -0,0 +1,223 @@ +/* + * 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. + * + * ESFMu ESFM emulator. + * + * + * Authors: Fred N. van Kempen, + * Miran Grca, + * Alexey Khokholov (Nuke.YKT) + * Cacodemon345 + * + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2013-2018 Alexey Khokholov (Nuke.YKT) + * Copyright 2024 Cacodemon345 + */ + +#include +#include +#include +#include +#include + +#include "esfmu/esfm.h" + +#define HAVE_STDARG_H +#define NO_SOFTFLOAT_INCLUDE +#include <86box/86box.h> +#include <86box/sound.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/snd_opl.h> + +#define RSM_FRAC 10 + +enum { + FLAG_CYCLES = 0x02, + FLAG_OPL3 = 0x01 +}; + +typedef struct { + esfm_chip opl; + int8_t flags; + int8_t pad; + + uint16_t port; + uint8_t status; + uint8_t timer_ctrl; + uint16_t timer_count[2]; + uint16_t timer_cur_count[2]; + + // OPL3L + int32_t rateratio; + int32_t samplecnt; + int32_t oldsamples[2]; + int32_t samples[2]; + + int pos; + int32_t buffer[SOUNDBUFLEN * 2]; +} esfm_drv_t; + +void +esfm_drv_generate_resampled(esfm_drv_t *dev, int32_t *bufp) +{ + while (dev->samplecnt >= dev->rateratio) { + int16_t samples[2] = { 0, 0 }; + dev->oldsamples[0] = dev->samples[0]; + dev->oldsamples[1] = dev->samples[1]; + ESFM_generate(&dev->opl, samples); + dev->samples[0] = samples[0]; + dev->samples[1] = samples[1]; + dev->samplecnt -= dev->rateratio; + } + + bufp[0] = (int32_t) ((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) + + dev->samples[0] * dev->samplecnt) + / dev->rateratio); + bufp[1] = (int32_t) ((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) + + dev->samples[1] * dev->samplecnt) + / dev->rateratio); + + dev->samplecnt += 1 << RSM_FRAC; +} + +void +esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) +{ + for (uint32_t i = 0; i < num; i++) { + esfm_drv_generate_resampled(dev, sndptr); + sndptr += 2; + } +} + +static void +esfm_drv_set_do_cycles(void *priv, int8_t do_cycles) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (do_cycles) + dev->flags |= FLAG_CYCLES; + else + dev->flags &= ~FLAG_CYCLES; +} + +static void * +esfm_drv_init(const device_t *info) +{ + esfm_drv_t *dev = (esfm_drv_t *) calloc(1, sizeof(esfm_drv_t)); + dev->flags = FLAG_CYCLES | FLAG_OPL3; + + /* Initialize the ESFMu object. */ + ESFM_init(&dev->opl); + dev->rateratio = (SOUND_FREQ << RSM_FRAC) / 49716; + + return dev; +} + +static void +esfm_drv_close(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + free(dev); +} + +static int32_t * +esfm_drv_update(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->pos >= sound_pos_global) + return dev->buffer; + + esfm_drv_generate_stream(dev, + &dev->buffer[dev->pos * 2], + sound_pos_global - dev->pos); + + for (; dev->pos < sound_pos_global; dev->pos++) { + dev->buffer[dev->pos * 2] /= 2; + dev->buffer[(dev->pos * 2) + 1] /= 2; + } + + return dev->buffer; +} + + +static void +esfm_drv_reset_buffer(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + dev->pos = 0; +} + +static uint8_t +esfm_drv_read(uint16_t port, void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->flags & FLAG_CYCLES) + cycles -= ((int) (isa_timing * 8)); + + esfm_drv_update(dev); + + uint8_t ret = 0xff; + + ret = ESFM_read_port(&dev->opl, port & 3); + + return ret; +} + +static void +esfm_drv_write(uint16_t port, uint8_t val, void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->flags & FLAG_CYCLES) + cycles -= ((int) (isa_timing * 8)); + + esfm_drv_update(dev); + + if (dev->opl.native_mode) { + if ((port & 3) == 1) { + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + } else { + ESFM_write_port(&dev->opl, port & 3, val); + } + } else { + if ((port & 3) == 1 || (port & 3) == 3) { + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + } else { + ESFM_write_port(&dev->opl, port & 3, val); + } + } +} + +const device_t esfm_esfmu_device = { + .name = "ESS Technology ESFM (ESFMu)", + .internal_name = "ymf262_nuked", + .flags = 0, + .local = FM_YMF262, + .init = esfm_drv_init, + .close = esfm_drv_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const fm_drv_t nuked_opl_drv = { + &esfm_drv_read, + &esfm_drv_write, + &esfm_drv_update, + &esfm_drv_reset_buffer, + &esfm_drv_set_do_cycles, + NULL, + NULL, +}; From eec49e4a76400273edb402e1c5f63041836b2e4b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 22:21:25 +0600 Subject: [PATCH 289/690] Fix multiple symbol definition error --- src/sound/snd_opl_esfm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index f7372730c..ec549700a 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -212,7 +212,7 @@ const device_t esfm_esfmu_device = { .config = NULL }; -const fm_drv_t nuked_opl_drv = { +const fm_drv_t esfmu_opl_drv = { &esfm_drv_read, &esfm_drv_write, &esfm_drv_update, From 12c64ab43d7d5164deabc7c09f763be669808fa4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 22:57:51 +0600 Subject: [PATCH 290/690] Fix incorrect internal name --- src/sound/snd_opl_esfm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index ec549700a..47796a911 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -200,9 +200,9 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) const device_t esfm_esfmu_device = { .name = "ESS Technology ESFM (ESFMu)", - .internal_name = "ymf262_nuked", + .internal_name = "esfm_esfmu", .flags = 0, - .local = FM_YMF262, + .local = 0, .init = esfm_drv_init, .close = esfm_drv_close, .reset = NULL, From 2341b28c7f4cb222dededb44a69873e9ce57f315 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 01:58:48 +0600 Subject: [PATCH 291/690] Add FM_ESFM type --- src/include/86box/snd_opl.h | 6 +++++- src/sound/snd_opl.c | 5 +++++ src/sound/snd_opl_esfm.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 0d89589c4..441e2a119 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -22,7 +22,8 @@ enum fm_type { FM_YMF262 = 1, /* OPL3 */ FM_YMF289B = 2, /* OPL3-L */ FM_YMF278B = 3, /* OPL 4 */ - FM_MAX = 4 + FM_ESFM = 4, /* ESFM */ + FM_MAX = 5 }; enum fm_driver { @@ -45,6 +46,7 @@ extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); extern const fm_drv_t nuked_opl_drv; extern const fm_drv_t ymfm_drv; +extern const fm_drv_t esfmu_opl_drv; #ifdef EMU_DEVICE_H extern const device_t ym3812_nuked_device; @@ -54,6 +56,8 @@ extern const device_t ym3812_ymfm_device; extern const device_t ymf262_ymfm_device; extern const device_t ymf289b_ymfm_device; extern const device_t ymf278b_ymfm_device; + +extern const device_t esfm_esfmu_device; #endif #endif /*SOUND_OPL_H*/ diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 21cc66f04..d98b3ccc2 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -68,6 +68,11 @@ fm_driver_get(int chip_id, fm_drv_t *drv) *drv = ymfm_drv; drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); break; + + case FM_ESFM: + *drv = esfmu_opl_drv; + drv->priv = device_add_inst(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++); + break; default: return 0; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 47796a911..d8e350418 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -202,7 +202,7 @@ const device_t esfm_esfmu_device = { .name = "ESS Technology ESFM (ESFMu)", .internal_name = "esfm_esfmu", .flags = 0, - .local = 0, + .local = FM_ESFM, .init = esfm_drv_init, .close = esfm_drv_close, .reset = NULL, From e1badc3e0f70b0d28d39888e820f543ebb65ae69 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 13:10:06 +0600 Subject: [PATCH 292/690] ESFM update --- src/sound/esfmu/esfm.c | 3 ++- src/sound/esfmu/esfm_registers.c | 15 +++++++++++---- src/sound/snd_opl_esfm.c | 32 ++++++-------------------------- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 7409603fe..08beadb5a 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -2117,7 +2117,7 @@ ESFM_update_timers(esfm_chip *chip) { if (chip->timer_enable[i]) { - chip->timer_accumulator[i] += i == 0 ? TIMER1_CONST : TIMER2_CONST; + chip->timer_accumulator[i] += (i == 0) ? TIMER1_CONST : TIMER2_CONST; if (chip->timer_accumulator[i] > 1.0) { chip->timer_accumulator[i] -= 1.0; @@ -2126,6 +2126,7 @@ ESFM_update_timers(esfm_chip *chip) { if (chip->timer_mask[i] == 0) { + chip->irq_bit = true; chip->timer_overflow[i] = true; } chip->timer_counter[i] = chip->timer_reload[i]; diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c index 34ce8b19e..653d91e9a 100644 --- a/src/sound/esfmu/esfm_registers.c +++ b/src/sound/esfmu/esfm_registers.c @@ -647,9 +647,11 @@ ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) break; case 0x02: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case 0x03: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case 0x04: for (i = 0; i < 3; i++) @@ -685,19 +687,24 @@ ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) break; case 0x02: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case 0x03: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case 0x04: - chip->timer_enable[0] = data & 0x01; - chip->timer_enable[1] = (data & 0x02) != 0; - chip->timer_mask[0] = (data & 0x20) != 0; - chip->timer_mask[1] = (data & 0x40) != 0; if (data & 0x80) { chip->irq_bit = 0; + chip->timer_overflow[0] = 0; + chip->timer_overflow[1] = 0; + break; } + chip->timer_enable[0] = data & 0x01; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[1] = (data & 0x20) != 0; + chip->timer_mask[0] = (data & 0x40) != 0; break; case 0x08: chip->keyscale_mode = (data & 0x40) != 0; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index d8e350418..16f728ab3 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -54,44 +54,25 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; - // OPL3L - int32_t rateratio; - int32_t samplecnt; - int32_t oldsamples[2]; - int32_t samples[2]; - int pos; int32_t buffer[SOUNDBUFLEN * 2]; } esfm_drv_t; void -esfm_drv_generate_resampled(esfm_drv_t *dev, int32_t *bufp) +esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - while (dev->samplecnt >= dev->rateratio) { - int16_t samples[2] = { 0, 0 }; - dev->oldsamples[0] = dev->samples[0]; - dev->oldsamples[1] = dev->samples[1]; - ESFM_generate(&dev->opl, samples); - dev->samples[0] = samples[0]; - dev->samples[1] = samples[1]; - dev->samplecnt -= dev->rateratio; - } + int16_t samples[2] = { 0, 0 }; + ESFM_generate(&dev->opl, samples); - bufp[0] = (int32_t) ((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) - + dev->samples[0] * dev->samplecnt) - / dev->rateratio); - bufp[1] = (int32_t) ((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) - + dev->samples[1] * dev->samplecnt) - / dev->rateratio); - - dev->samplecnt += 1 << RSM_FRAC; + bufp[0] = (int32_t) samples[0]; + bufp[1] = (int32_t) samples[1]; } void esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) { for (uint32_t i = 0; i < num; i++) { - esfm_drv_generate_resampled(dev, sndptr); + esfm_generate_raw(dev, sndptr); sndptr += 2; } } @@ -115,7 +96,6 @@ esfm_drv_init(const device_t *info) /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); - dev->rateratio = (SOUND_FREQ << RSM_FRAC) / 49716; return dev; } From 5d97fb886fb6ac8ea78b71e765a60eb193ebd93e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 16:10:31 +0600 Subject: [PATCH 293/690] Fix bad audio on ESFM emulation --- src/sound/snd_opl_esfm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 16f728ab3..3720c8ada 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -112,14 +112,14 @@ esfm_drv_update(void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - if (dev->pos >= sound_pos_global) + if (dev->pos >= music_pos_global) return dev->buffer; esfm_drv_generate_stream(dev, &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + music_pos_global - dev->pos); - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; dev->buffer[(dev->pos * 2) + 1] /= 2; } From d806ce250ea51bb4ccd44411cd7ddcd4465edac8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 22:14:41 +0600 Subject: [PATCH 294/690] ESFMu update --- src/sound/esfmu/esfm_registers.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c index 653d91e9a..e2f432ed1 100644 --- a/src/sound/esfmu/esfm_registers.c +++ b/src/sound/esfmu/esfm_registers.c @@ -453,21 +453,24 @@ ESFM_write_reg_native (esfm_chip *chip, uint16_t address, uint8_t data) { case TIMER1_REG: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case TIMER2_REG: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case TIMER_SETUP_REG: if (data & 0x80) { + chip->irq_bit = 0; chip->timer_overflow[0] = 0; chip->timer_overflow[1] = 0; - chip->irq_bit = 0; + break; } chip->timer_enable[0] = (data & 0x01) != 0; chip->timer_enable[1] = (data & 0x02) != 0; - chip->timer_mask[0] = (data & 0x20) != 0; - chip->timer_mask[1] = (data & 0x40) != 0; + chip->timer_mask[1] = (data & 0x20) != 0; + chip->timer_mask[0] = (data & 0x40) != 0; break; case CONFIG_REG: chip->keyscale_mode = (data & 0x40) != 0; @@ -547,16 +550,16 @@ ESFM_readback_reg_native (esfm_chip *chip, uint16_t address) switch (address & 0x5ff) { case TIMER1_REG: - data = chip->timer_reload[0]; + data = chip->timer_counter[0]; break; case TIMER2_REG: - data = chip->timer_reload[1]; + data = chip->timer_counter[1]; break; case TIMER_SETUP_REG: data |= chip->timer_enable[0] != 0; data |= (chip->timer_enable[1] != 0) << 1; - data |= (chip->timer_mask[0] != 0) << 5; - data |= (chip->timer_mask[1] != 0) << 6; + data |= (chip->timer_mask[1] != 0) << 5; + data |= (chip->timer_mask[0] != 0) << 6; break; case CONFIG_REG: data |= (chip->keyscale_mode != 0) << 6; From 8308f410694b3b46670efbd5c3fb41622d712447 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 02:51:07 +0600 Subject: [PATCH 295/690] A bit of ESS --- src/include/86box/snd_sb_dsp.h | 5 +++++ src/sound/snd_sb_dsp.c | 27 ++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 3e0e40e80..568b02f47 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -5,6 +5,11 @@ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ +#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ +#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ + +/* ESS-related */ +#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index cf4498b4b..d94faa29e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -906,17 +906,21 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_pause = 1; break; case 0xD1: /* Speaker on */ - if (dsp->sb_type < SB15) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 0; + if (!IS_ESS(dsp)) { + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 0; + } dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ - if (dsp->sb_type < SB15) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 1; + if (!IS_ESS(dsp)) { + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 1; + } dsp->sb_speaker = 0; break; case 0xD4: /* Continue 8-bit DMA */ @@ -944,6 +948,11 @@ sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, ~dsp->sb_data[0]); break; case 0xE1: /* Get DSP version */ + if (IS_ESS(dsp)) { + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + break; + } if (IS_AZTECH(dsp)) { if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { sb_add_data(dsp, 0x3); @@ -1036,7 +1045,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) + if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; switch (a & 0xF) { From d5dad279c4e9a7bb12286ef35a38e98e4fe546fa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 16:50:29 +0600 Subject: [PATCH 296/690] ESSreg macro --- src/include/86box/snd_sb_dsp.h | 2 ++ src/sound/snd_sb_dsp.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 568b02f47..bf9ceab53 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -140,6 +140,8 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ + uint8_t ess_regs[256]; /* ESS registers. */ + mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d94faa29e..79415ac5b 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -135,6 +135,8 @@ sb_dsp_log(const char *fmt, ...) # define sb_dsp_log(fmt, ...) #endif +#define ESSreg(reg) (dsp)->ess_regs[reg - 0xA0] + static __inline double sinc(double x) { From 97b239aed50c3b5c149e4195548cc1d75e3677e0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:12:26 +0600 Subject: [PATCH 297/690] More small pieces of ESS emulation --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index bf9ceab53..6f94a9801 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -141,6 +141,7 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ uint8_t ess_regs[256]; /* ESS registers. */ + uint8_t ess_playback_mode; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 79415ac5b..1e2d469a2 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1332,6 +1332,15 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, dsp->dma_priv = priv; } +void +sb_ess_finish_dma(sb_dsp_t *dsp) +{ + if (!dsp->ess_playback_mode) + return; + ESSreg(0xB8) &= ~0x01; + dma_set_drq(dsp->sb_8_dmanum, 0); +} + void pollsb(void *priv) { @@ -1530,6 +1539,7 @@ pollsb(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); } @@ -1582,6 +1592,7 @@ pollsb(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); } From 3f72c788bdd837cb8c940f1559f76929e6e3ffbd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:29:05 +0600 Subject: [PATCH 298/690] ESS bits for IRQ raise --- src/sound/snd_sb_dsp.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 1e2d469a2..c028f98c1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -224,6 +224,12 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) break; } + /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ + if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { + if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + return; + } + if (set && !masked) dsp->irq_update(dsp->irq_priv, 1); else if (!set) @@ -377,6 +383,9 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) if (!timer_is_enabled(&dsp->output_timer)) timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); } + + /* This will be set later for ESS playback/record modes. */ + dsp->ess_playback_mode = 0; } void @@ -409,6 +418,32 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } +void +sb_start_dma_ess(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +{ + if (IS_ESS(dsp)) { + dma_set_drq(dsp->sb_8_dmanum, 0); + dma_set_drq(dsp->sb_16_8_dmanum, 0); + } + sb_start_dma(dsp, dma8, autoinit, format, len); + dsp->ess_playback_mode = 1; + dma_set_drq(dsp->sb_8_dmanum, 1); + dma_set_drq(dsp->sb_16_8_dmanum, 1); +} + +void +sb_start_dma_ess_i(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +{ + if (IS_ESS(dsp)) { + dma_set_drq(dsp->sb_8_dmanum, 0); + dma_set_drq(dsp->sb_16_8_dmanum, 0); + } + sb_start_dma_i(dsp, dma8, autoinit, format, len); + dsp->ess_playback_mode = 1; + dma_set_drq(dsp->sb_8_dmanum, 1); + dma_set_drq(dsp->sb_16_8_dmanum, 1); +} + int sb_8_read_dma(void *priv) { From 4369284f6549258ee465566416b3c93ee4b59d0e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:36:55 +0600 Subject: [PATCH 299/690] ESS register 0xA2 update function --- src/sound/snd_sb_dsp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index c028f98c1..12b04a008 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -585,6 +585,18 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } +/* TODO: Investigate ESS cards' filtering on real hardware as well. + (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ +static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { + if (dsp->sb_freq >= 22050) + ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); + else + ESSreg(0xA1) = 128 - (397700UL / dsp->sb_freq); + + unsigned int freq = ((dsp->sb_freq * 4) / (5 * 2)); /* 80% of 1/2 the sample rate */ + ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -796,6 +808,9 @@ sb_exec_command(sb_dsp_t *dsp) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; + if (IS_ESS(dsp)) { + sb_ess_update_filter_freq(dsp); + } break; case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ From 3f7fbc7467266e5456281b7808222cd6c9622a79 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:41:51 +0600 Subject: [PATCH 300/690] Extended mode toggle --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 6f94a9801..f04734ebb 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -142,6 +142,7 @@ typedef struct sb_dsp_t { uint8_t ess_regs[256]; /* ESS registers. */ uint8_t ess_playback_mode; + uint8_t ess_extended_mode; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 12b04a008..08a69ec82 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -610,6 +610,13 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; + if (IS_ESS(dsp)) { + if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7){ + dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); + return; + } + } + switch (dsp->sb_command) { case 0x01: /* ???? */ if (dsp->sb_type >= SB16) From eda528d98c0f2371b555dc6c61abd67b6e34daff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:48:21 +0600 Subject: [PATCH 301/690] ESS register read function --- src/sound/snd_sb_dsp.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 08a69ec82..05b6abe43 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -587,7 +587,8 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ -static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { +static void sb_ess_update_filter_freq(sb_dsp_t *dsp) +{ if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); else @@ -597,6 +598,27 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); } +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +{ + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + +static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +{ + switch (reg) { + default: + return ESSreg(reg); + } + + return 0xFF; +} + void sb_exec_command(sb_dsp_t *dsp) { From e7e582cd740541dfe61f290967e77e5e1d618f51 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:02:56 +0600 Subject: [PATCH 302/690] Finish DSP part of ESS --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/CMakeLists.txt | 2 +- src/sound/snd_ess.c | 258 +++++++++++++++++++++++++++++++++ src/sound/snd_sb_dsp.c | 219 ++++++++++++++++++++++++---- 4 files changed, 454 insertions(+), 26 deletions(-) create mode 100644 src/sound/snd_ess.c diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f04734ebb..2b39a0303 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -143,6 +143,7 @@ typedef struct sb_dsp_t { uint8_t ess_regs[256]; /* ESS registers. */ uint8_t ess_playback_mode; uint8_t ess_extended_mode; + uint8_t ess_reload_len; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 9b2cc1416..9206f6be9 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c snd_ess.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c new file mode 100644 index 000000000..d762117cd --- /dev/null +++ b/src/sound/snd_ess.c @@ -0,0 +1,258 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/filters.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/isapnp.h> +#include <86box/hdc_ide.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/midi.h> +#include <86box/pic.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/timer.h> +#include <86box/snd_sb.h> +#include <86box/plat_unused.h> + +static const double sb_att_4dbstep_3bits[] = { + 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 +}; + +static const double sb_att_7dbstep_2bits[] = { + 164.0, 6537.0, 14637.0, 32767.0 +}; + +/* SB PRO */ +typedef struct ess_mixer_t { + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; + double mic; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; +} ess_mixer_t; + +typedef struct ess_t { + uint8_t mixer_enabled; + fm_drv_t opl; + sb_dsp_t dsp; + union { + ess_mixer_t mixer_sbpro; + }; + mpu_t *mpu; + emu8k_t emu8k; + void *gameport; + + int pnp; + + uint8_t pos_regs[8]; + uint8_t pnp_rom[512]; + + uint16_t opl_pnp_addr; + uint16_t gameport_addr; + + void *opl_mixer; + void (*opl_mix)(void*, double*, double*); +} ess_t; + +static inline uint8_t expand16to32(const uint8_t t) { + /* 4-bit -> 5-bit expansion. + * + * 0 -> 0 + * 1 -> 2 + * 2 -> 4 + * 3 -> 6 + * .... + * 7 -> 14 + * 8 -> 17 + * 9 -> 19 + * 10 -> 21 + * 11 -> 23 + * .... + * 15 -> 31 */ + return (t << 1) | (t >> 3); +} + +void +ess_mixer_write(uint16_t addr, uint8_t val, void *priv) +{ + ess_t *ess = (ess_t *) priv; + ess_mixer_t *mixer = &ess->mixer_sbpro; + + if (!(addr & 1)) { + mixer->index = val; + mixer->regs[0x01] = val; + } else { + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; + mixer->regs[0x0e] = 0x00; + /* Changed default from -11dB to 0dB */ + mixer->regs[0x04] = mixer->regs[0x22] = 0xee; + mixer->regs[0x26] = mixer->regs[0x28] = 0xee; + mixer->regs[0x2e] = 0x00; + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); + } else { + mixer->regs[mixer->index] = val; + + switch (mixer->index) { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: + case 0x06: + case 0x08: + mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); + break; + + case 0x22: + case 0x26: + case 0x28: + mixer->regs[mixer->index - 0x20] = (val & 0xe); + break; + + /* More compatibility: + SoundBlaster Pro selects register 020h for 030h, 022h for 032h, + 026h for 036h, and 028h for 038h. */ + case 0x30: + case 0x32: + case 0x36: + case 0x38: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x2e: + break; + + default: + //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + + mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; + mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; + mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; + mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; + mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; + mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; + mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; + mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; + mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; + mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; + + mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + + mixer->output_filter = !(mixer->regs[0xe] & 0x20); + mixer->input_filter = !(mixer->regs[0xc] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xe] & 2; + if (mixer->index == 0xe) + sb_dsp_set_stereo(&ess->dsp, val & 2); + + switch (mixer->regs[0xc] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + + /* TODO: pcspeaker volume? Or is it not worth? */ + } +} + +uint8_t +ess_mixer_read(uint16_t addr, void *priv) +{ + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + + if (!(addr & 1)) + return mixer->index; + + switch (mixer->index) { + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + return mixer->regs[mixer->index]; + + default: + //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + return 0xff; +} + +void +ess_mixer_reset(ess_t *ess) +{ + ess_mixer_write(4, 0, ess); + ess_mixer_write(5, 0, ess); +} \ No newline at end of file diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 05b6abe43..29b065477 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -6,6 +6,7 @@ #define _USE_MATH_DEFINES #include +#include #include #include #include @@ -418,30 +419,65 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } -void -sb_start_dma_ess(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) + +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) { + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + +void +sb_start_dma_ess(sb_dsp_t* dsp) +{ + uint8_t real_format = 0; + uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; + + if (!dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + } + if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); dma_set_drq(dsp->sb_16_8_dmanum, 0); } - sb_start_dma(dsp, dma8, autoinit, format, len); + real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; + real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; + if (!!(ESSreg(0xB8) & 8)) + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + else + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); } void -sb_start_dma_ess_i(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +sb_stop_dma_ess(sb_dsp_t* dsp) { - if (IS_ESS(dsp)) { - dma_set_drq(dsp->sb_8_dmanum, 0); - dma_set_drq(dsp->sb_16_8_dmanum, 0); + dsp->sb_8_enable = dsp->sb_16_enable = 0; + dma_set_drq(dsp->sb_16_8_dmanum, 0); + dma_set_drq(dsp->sb_8_dmanum, 0); +} + +static void sb_ess_update_dma_status(sb_dsp_t* dsp) +{ + bool dma_en = (ESSreg(0xB8) & 1)?true:false; + + // if the DRQ is disabled, do not start + if (!(ESSreg(0xB2) & 0x40)) + dma_en = false; + + if (dma_en) { + if (!dsp->sb_8_enable && !dsp->sb_16_enable) sb_start_dma_ess(dsp); + } + else { + if (dsp->sb_8_enable || dsp->sb_16_enable) sb_stop_dma_ess(dsp); } - sb_start_dma_i(dsp, dma8, autoinit, format, len); - dsp->ess_playback_mode = 1; - dma_set_drq(dsp->sb_8_dmanum, 1); - dma_set_drq(dsp->sb_16_8_dmanum, 1); } int @@ -598,17 +634,6 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); } -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) -{ - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; -} - static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { @@ -619,6 +644,120 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } +static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +{ + uint8_t chg = 0x00; + sb_dsp_log("ESS register write reg=%02xh val=%02xh\n",reg,data); + + switch (reg) { + case 0xA1: /* Extended Mode Sample Rate Generator */ + { + ESSreg(reg) = data; + if (data & 0x80) + dsp->sb_freq = 795500UL / (256ul - data); + else + dsp->sb_freq = 397700UL / (128ul - data); + + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + break; + } + case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ + ESSreg(reg) = data; + break; + + case 0xA4: /* DMA Transfer Count Reload (low) */ + case 0xA5: /* DMA Transfer Count Reload (high) */ + ESSreg(reg) = data; + if (dsp->sb_16_length == 0 || dsp->sb_8_length == 0) + dsp->ess_reload_len = 1; + break; + + case 0xA8: /* Analog Control */ + /* bits 7:5 0 Reserved. Always write 0 + * bit 4 1 Reserved. Always write 1 + * bit 3 Record monitor 1=Enable record monitor + * enable + * bit 2 0 Reserved. Always write 0 + * bits 1:0 Stereo/mono select 00=Reserved + * 01=Stereo + * 10=Mono + * 11=Reserved */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + if (chg & 0x3) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + } + break; + + case 0xB1: /* Legacy Audio Interrupt Control */ + case 0xB2: /* DRQ Control */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + if (chg & 0x40) sb_ess_update_dma_status(dsp); + break; + case 0xB5: /* DAC Direct Access Holding (low) */ + case 0xB6: /* DAC Direct Access Holding (high) */ + ESSreg(reg) = data; + break; + + case 0xB7: /* Audio 1 Control 1 */ + /* bit 7 Enable FIFO to/from codec + * bit 6 Opposite from bit 3 Must be set opposite to bit 3 + * bit 5 FIFO signed mode 1=Data is signed twos-complement 0=Data is unsigned + * bit 4 Reserved Always write 1 + * bit 3 FIFO stereo mode 1=Data is stereo + * bit 2 FIFO 16-bit mode 1=Data is 16-bit + * bit 1 Reserved Always write 0 + * bit 0 Generate load signal */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + if (chg & 0x0C) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + } + break; + + case 0xB8: /* Audio 1 Control 2 */ + /* bits 7:4 reserved + * bit 3 CODEC mode 1=first DMA converter in ADC mode + * 0=first DMA converter in DAC mode + * bit 2 DMA mode 1=auto-initialize mode + * 0=normal DMA mode + * bit 1 DMA read enable 1=first DMA is read (for ADC) + * 0=first DMA is write (for DAC) + * bit 0 DMA xfer enable 1=DMA is allowed to proceed */ + data &= 0xF; + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + + if (chg & 1) + dsp->ess_reload_len = 1; + + if (chg & 0xB) { + if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ + sb_ess_update_dma_status(dsp); + } + break; + + case 0xB9: /* Audio 1 Transfer Type */ + case 0xBA: /* Left Channel ADC Offset Adjust */ + case 0xBB: /* Right Channel ADC Offset Adjust */ + ESSreg(reg) = data; + break; + + default: + break; + } +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -632,11 +771,17 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; - if (IS_ESS(dsp)) { - if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7){ + if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; } + if (dsp->sb_command == 0xC0) { + sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); + } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); + } + return; } switch (dsp->sb_command) { @@ -1062,12 +1207,29 @@ sb_exec_command(sb_dsp_t *dsp) while (sb16_copyright[c]) sb_add_data(dsp, sb16_copyright[c++]); sb_add_data(dsp, 0); + } else if (IS_ESS(dsp)) { + sb_add_data(dsp, 0); } break; case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; - case 0xE7: /* ???? */ + case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ + if (IS_ESS(dsp)) { + switch (dsp->sb_subtype) { + default: + break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; + case SB_SUBTYPE_ESS_ES1688: + // Determined via Windows driver debugging. + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x09); + break; + } + } break; case 0xE8: /* Read test register */ sb_add_data(dsp, dsp->sb_test); @@ -1170,6 +1332,13 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } + if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command <= 0xC0) { + sb_commands[dsp->sb_command] = 1; + } else { + sb_commands[dsp->sb_command] = 0; + } + } } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); From 7f9f072b3e51324a299b07bd2140f1cebebcb261 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:19:01 +0600 Subject: [PATCH 303/690] Add ESS ES1688 (COMPLETELY UNTESTED!!!) --- src/include/86box/sound.h | 4 + src/sound/snd_ess.c | 261 +++++++++++++++++++++++++++++++++++++- src/sound/sound.c | 1 + 3 files changed, 265 insertions(+), 1 deletion(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index b8f9be5b2..c6fdada89 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -184,6 +184,10 @@ extern const device_t cmi8338_onboard_device; extern const device_t cmi8738_device; extern const device_t cmi8738_onboard_device; extern const device_t cmi8738_6ch_onboard_device; + +/* ESS Technology */ +extern const device_t ess_1688_device; + #endif #endif /*EMU_SOUND_H*/ diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index d762117cd..5b6852b68 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -255,4 +255,263 @@ ess_mixer_reset(ess_t *ess) { ess_mixer_write(4, 0, ess); ess_mixer_write(5, 0, ess); -} \ No newline at end of file +} + +void +ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + + sb_dsp_update(&sb->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_filter) { + out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; + out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + } else { + out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + sb->dsp.pos = 0; +} + +void +ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + const int32_t *opl2_buf = NULL; + + opl_buf = ess->opl.update(ess->opl.priv); + + sb_dsp_update(&ess->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->opl.reset_buffer(ess->opl.priv); +} + +void +ess_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; + + if (mixer->output_filter) + c = (sb_iir(2, channel, *buffer) * cd) / 3.9; + else + c = (*buffer * cd) / 3.0; + *buffer = c * master; +} + +static void * +ess_1688_init(UNUSED(const device_t *info)) +{ + /* SB Pro 2 port mappings, 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface. */ + ess_t *ess = malloc(sizeof(ess_t)); + uint16_t addr = device_get_config_hex16("base"); + memset(ess, 0, sizeof(ess_t)); + + fm_driver_get(FM_ESFM, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_setaddr(&ess->dsp, addr); + sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + ess_mixer_reset(ess); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + ess->mixer_enabled = 1; + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + sound_add_handler(ess_get_buffer_sbpro, ess); + music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + return ess; +} + +void +ess_close(void *priv) +{ + ess_t *ess = (ess_t *) priv; + sb_dsp_close(&ess->dsp); + + free(ess); +} + +void +ess_speed_changed(void *priv) +{ + ess_t *ess = (ess_t *) priv; + + sb_dsp_speed_changed(&ess->dsp); +} + +static const device_config_t ess_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t ess_1688_device = { + .name = "ESS Technology ESS1688", + .internal_name = "ess_1688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_1688_init, + .close = ess_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = ess_speed_changed, + .force_redraw = NULL, + .config = ess_config +}; \ No newline at end of file diff --git a/src/sound/sound.c b/src/sound/sound.c index 81f70d921..2f6b91aca 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -165,6 +165,7 @@ static const SOUND_CARD sound_cards[] = { { &es1371_device }, { &ad1881_device }, { &cs4297a_device }, + { &ess_1688_device }, { NULL } // clang-format on }; From 6ab45767e5fad8b8d1638c677a3be07cf8e55d50 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:26:49 +0600 Subject: [PATCH 304/690] Some cleanup and crash fixes --- src/sound/snd_ess.c | 1 - src/sound/snd_opl_esfm.c | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 5b6852b68..f0f1b5ec7 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -299,7 +299,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; - const int32_t *opl2_buf = NULL; opl_buf = ess->opl.update(ess->opl.priv); diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 3720c8ada..cbd9a93a3 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -54,18 +54,19 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; + int16_t samples[2]; + int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[MUSICBUFLEN * 2]; } esfm_drv_t; void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - int16_t samples[2] = { 0, 0 }; - ESFM_generate(&dev->opl, samples); + ESFM_generate(&dev->opl, &dev->samples[0]); - bufp[0] = (int32_t) samples[0]; - bufp[1] = (int32_t) samples[1]; + bufp[0] = dev->samples[0]; + bufp[1] = dev->samples[1]; } void From d46e00e5a05307e25ed24dfb7540a6ec8f393432 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 00:16:04 +0600 Subject: [PATCH 305/690] Autolen updating --- src/sound/snd_sb_dsp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 29b065477..ed74fea68 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -644,6 +644,10 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } +static void sb_ess_update_autolen(sb_dsp_t *dsp) { + dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); +} + static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; @@ -671,7 +675,8 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA4: /* DMA Transfer Count Reload (low) */ case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; - if (dsp->sb_16_length == 0 || dsp->sb_8_length == 0) + sb_ess_update_autolen(dsp); + if (dsp->sb_16_length < 0 || dsp->sb_8_length < 0) dsp->ess_reload_len = 1; break; @@ -741,6 +746,9 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) dsp->ess_reload_len = 1; + if (chg & 4) + sb_ess_update_autolen(dsp); + if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); From 650b7e633beecd54d278707719b74b055426739e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 00:20:27 +0600 Subject: [PATCH 306/690] Minor fixing --- src/sound/snd_sb_dsp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ed74fea68..7977cc030 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -722,6 +722,10 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * bit 0 Generate load signal */ chg = ESSreg(reg) ^ data; ESSreg(reg) = data; + + if (chg & 4) + sb_ess_update_autolen(dsp); + if (chg & 0x0C) { if (dsp->sb_16_enable || dsp->sb_8_enable) { sb_stop_dma_ess(dsp); @@ -746,9 +750,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) dsp->ess_reload_len = 1; - if (chg & 4) - sb_ess_update_autolen(dsp); - if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); From 68f6779b2f53216308841fbead06f23f07383a66 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 01:35:34 +0600 Subject: [PATCH 307/690] Handle length reloading correctly --- src/sound/snd_sb_dsp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7977cc030..58131515d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -437,8 +437,9 @@ sb_start_dma_ess(sb_dsp_t* dsp) uint8_t real_format = 0; uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - if (!dsp->ess_reload_len) { + if (dsp->ess_reload_len) { len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; } if (IS_ESS(dsp)) { @@ -676,7 +677,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - if (dsp->sb_16_length < 0 || dsp->sb_8_length < 0) + if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -1912,6 +1913,7 @@ sb_poll_i(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); } @@ -1960,6 +1962,7 @@ sb_poll_i(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); } From dfa0ec6be80dab9dc800724dd988d9c9584eeae9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 02:00:07 +0600 Subject: [PATCH 308/690] Implement ESS identification mixer register --- src/sound/snd_ess.c | 21 +++++++++++++++++++-- src/sound/snd_sb_dsp.c | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f0f1b5ec7..9347a755e 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -76,6 +76,9 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; + + uint8_t ess_id_str[4]; + uint8_t ess_id_str_pos : 2; } ess_mixer_t; typedef struct ess_t { @@ -128,6 +131,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (!(addr & 1)) { mixer->index = val; mixer->regs[0x01] = val; + if (val == 0x40) + mixer->ess_id_str_pos = 0; } else { if (mixer->index == 0) { /* Reset */ @@ -218,8 +223,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint8_t ess_mixer_read(uint16_t addr, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + ess_t *ess = (ess_t *) priv; + ess_mixer_t *mixer = &ess->mixer_sbpro; if (!(addr & 1)) return mixer->index; @@ -242,6 +247,11 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x38: return mixer->regs[mixer->index]; + case 0x40: + { + return mixer->ess_id_str[mixer->ess_id_str_pos++]; + } + default: //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; @@ -391,6 +401,13 @@ ess_1688_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + { + ess->mixer_sbpro.ess_id_str[0] = 0x16; + ess->mixer_sbpro.ess_id_str[1] = 0x88; + ess->mixer_sbpro.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; + } + return ess; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 58131515d..45f8440a2 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -900,6 +900,9 @@ sb_exec_command(sb_dsp_t *dsp) case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; + // FIXME: What does the ESS AudioDrive do to its filter/sample rate divider registers when emulating this Sound Blaster command? + ESSreg(0xA1) = 128 - (397700 / 22050); + ESSreg(0xA2) = 256 - (7160000 / (82 * ((4 * 22050) / 10))); break; case 0x14: /* 8-bit single cycle DMA output */ sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); From a2b13cadbff2d8ca9c295cd9431371527b5e3b75 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 13:18:50 +0600 Subject: [PATCH 309/690] ESS: implement mixer regs and fix ESS-specific DMA --- src/sound/snd_ess.c | 105 ++++++++++++++++++++++++++++++++++++----- src/sound/snd_sb_dsp.c | 17 +++++-- 2 files changed, 106 insertions(+), 16 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 9347a755e..b58618c3a 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define HAVE_STDARG_H @@ -122,6 +123,11 @@ static inline uint8_t expand16to32(const uint8_t t) { return (t << 1) | (t >> 3); } +static double ess_mixer_get_vol_4bit(uint8_t vol) +{ + return (48.0 + (20.0 * log((vol & 0xF) / 15.0))) / 48.0; +} + void ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -142,6 +148,14 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x04] = mixer->regs[0x22] = 0xee; mixer->regs[0x26] = mixer->regs[0x28] = 0xee; mixer->regs[0x2e] = 0x00; + + /* Initialize ESS regs. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0x88; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x00; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; @@ -153,20 +167,29 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x08: mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); break; + + case 0x14: + mixer->regs[0x4] = val & 0xee; + break; case 0x22: case 0x26: case 0x28: + case 0x2E: mixer->regs[mixer->index - 0x20] = (val & 0xe); + mixer->regs[mixer->index + 0x10] = val; break; /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ case 0x30: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; case 0x32: case 0x36: case 0x38: + case 0x3e: mixer->regs[mixer->index - 0x10] = (val & 0xee); break; @@ -175,25 +198,75 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x0a: case 0x0c: case 0x0e: - case 0x2e: break; + case 0x40: { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if (mixer->regs[0x40] & 1) { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + switch ((mixer->regs[0x40] >> 5) & 7) { + case 0: + mpu401_change_addr(ess->mpu, 0x00); + mpu401_setirq(ess->mpu, -1); + break; + case 1: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 2: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); + break; + case 3: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xE); + break; + case 4: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xA); + break; + case 5: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xB); + break; + case 6: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xC); + break; + case 7: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xD); + break; + } + break; + } + default: //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } - mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; - mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; - mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; - mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; - mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; - mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; - mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; - mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; - mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; - mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; + mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14]); + mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); + mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32]); + mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); + mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36]); + mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); + mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38]); + mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); + mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); + mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; @@ -372,6 +445,8 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); /* DSP I/O handler is activated in sb_dsp_setaddr */ { @@ -408,6 +483,14 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(ess->mpu, 0, 0, M_UART, 1); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport_addr = 0x000; + gameport_remap(ess->gameport, ess->gameport_addr); + return ess; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 45f8440a2..fa3133768 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -437,7 +437,7 @@ sb_start_dma_ess(sb_dsp_t* dsp) uint8_t real_format = 0; uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - if (dsp->ess_reload_len) { + if (dsp->ess_reload_len || len <= 0) { len = sb_ess_get_dma_len(dsp); dsp->ess_reload_len = 0; } @@ -449,9 +449,9 @@ sb_start_dma_ess(sb_dsp_t* dsp) real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; if (!!(ESSreg(0xB8) & 8)) - sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); else - sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); @@ -748,8 +748,15 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) chg = ESSreg(reg) ^ data; ESSreg(reg) = data; - if (chg & 1) - dsp->ess_reload_len = 1; + if (chg & 1) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + if (dsp->sb_16_enable) + dsp->sb_16_length = sb_ess_get_dma_len(dsp); + if (dsp->sb_8_enable) + dsp->sb_8_length = sb_ess_get_dma_len(dsp); + } else + dsp->ess_reload_len = 1; + } if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ From 181d42610fa7299d6b55e2a3570e67c7ed18a94f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 13:20:20 +0600 Subject: [PATCH 310/690] Correct name of ESS device --- src/sound/snd_ess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b58618c3a..d3e02bf2f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -602,8 +602,8 @@ static const device_config_t ess_config[] = { }; const device_t ess_1688_device = { - .name = "ESS Technology ESS1688", - .internal_name = "ess_1688", + .name = "ESS Technology ES1688", + .internal_name = "ess_es1688", .flags = DEVICE_ISA, .local = 0, .init = ess_1688_init, From 2446c4ebd4671c16b289163d26d09ea76190ac63 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 14:56:07 +0600 Subject: [PATCH 311/690] Fix some stale functions --- src/sound/snd_ess.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index d3e02bf2f..504122a0b 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -78,27 +78,19 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; - uint8_t ess_id_str[4]; - uint8_t ess_id_str_pos : 2; + uint8_t ess_id_str[256]; + uint8_t ess_id_str_pos; } ess_mixer_t; typedef struct ess_t { uint8_t mixer_enabled; fm_drv_t opl; sb_dsp_t dsp; - union { - ess_mixer_t mixer_sbpro; - }; + ess_mixer_t mixer_sbpro; + mpu_t *mpu; - emu8k_t emu8k; void *gameport; - int pnp; - - uint8_t pos_regs[8]; - uint8_t pnp_rom[512]; - - uint16_t opl_pnp_addr; uint16_t gameport_addr; void *opl_mixer; @@ -322,7 +314,11 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x40: { - return mixer->ess_id_str[mixer->ess_id_str_pos++]; + uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + mixer->ess_id_str_pos++; + if (mixer->ess_id_str_pos >= 4) + mixer->ess_id_str_pos = 0; + return val; } default: @@ -343,12 +339,12 @@ ess_mixer_reset(ess_t *ess) void ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; double out_l = 0.0; double out_r = 0.0; - sb_dsp_update(&sb->dsp); + sb_dsp_update(&ess->dsp); for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; @@ -356,11 +352,11 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { - out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; - out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + out_l += (sb_iir(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.9; + out_r += (sb_iir(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; } else { - out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; - out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; } /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ @@ -371,7 +367,7 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->dsp.pos = 0; + ess->dsp.pos = 0; } void @@ -434,9 +430,8 @@ ess_1688_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = malloc(sizeof(ess_t)); + ess_t *ess = calloc(sizeof(ess_t), 1); uint16_t addr = device_get_config_hex16("base"); - memset(ess, 0, sizeof(ess_t)); fm_driver_get(FM_ESFM, &ess->opl); From 6ae6ca11714b746b2967fa1b8a18f2587c02f9d8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 15:04:17 +0600 Subject: [PATCH 312/690] Fix OPL address decoding getting disabled for some reason --- src/sound/snd_ess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 504122a0b..0d507dc5f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -195,6 +195,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + /* This doesn't work yet. */ + /* io_removehandler(0x0388, 0x0004, ess->opl.read, NULL, NULL, ess->opl.write, NULL, NULL, @@ -204,7 +206,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) ess->opl.read, NULL, NULL, ess->opl.write, NULL, NULL, ess->opl.priv); - } + }*/ switch ((mixer->regs[0x40] >> 5) & 7) { case 0: From 2bdd5ca9bcfa4361650367003173855e14b44eb8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 15:58:02 +0600 Subject: [PATCH 313/690] Correct IRQ selection and detection fixes --- src/sound/snd_ess.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0d507dc5f..7f48c95c0 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -79,7 +79,7 @@ typedef struct ess_mixer_t { uint8_t regs[256]; uint8_t ess_id_str[256]; - uint8_t ess_id_str_pos; + uint8_t ess_id_str_pos : 2; } ess_mixer_t; typedef struct ess_t { @@ -192,6 +192,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x0e: break; + case 0x64: + mixer->regs[mixer->index] &= ~0x8; + break; + case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); @@ -223,23 +227,23 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 3: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xE); + mpu401_setirq(ess->mpu, 11); break; case 4: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xA); + mpu401_setirq(ess->mpu, 9); break; case 5: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xB); + mpu401_setirq(ess->mpu, 5); break; case 6: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xC); + mpu401_setirq(ess->mpu, 7); break; case 7: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xD); + mpu401_setirq(ess->mpu, 10); break; } break; @@ -302,6 +306,7 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x0a: case 0x0c: case 0x0e: + case 0x14: case 0x22: case 0x26: case 0x28: @@ -312,8 +317,12 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x32: case 0x36: case 0x38: + case 0x3e: return mixer->regs[mixer->index]; + case 0x64: + return mixer->regs[mixer->index] & 7; + case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; @@ -324,11 +333,11 @@ ess_mixer_read(uint16_t addr, void *priv) } default: - //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0xff; + return 0x00; } void From 552f595bc549b17a754fe57bb73ba8ae8434dfc3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 16:00:41 +0600 Subject: [PATCH 314/690] Fix AudioDrive detection on Windows 3.1 Sound is not working, and neither is MPU-401 --- src/sound/snd_ess.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 7f48c95c0..400983aba 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -320,9 +320,6 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x3e: return mixer->regs[mixer->index]; - case 0x64: - return mixer->regs[mixer->index] & 7; - case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; From 2e9e20c0787a37301493c3c7896ebd73cb08097a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 14:06:20 +0600 Subject: [PATCH 315/690] Deal with edge cases where drivers use non-ESS playback route --- src/sound/snd_sb_dsp.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index fa3133768..90d66c144 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -353,11 +353,27 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +{ + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { dsp->sb_pausetime = -1; + if (dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; + } + if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -392,6 +408,11 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { + if (dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; + } + if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -419,18 +440,6 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } - -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) -{ - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; -} - void sb_start_dma_ess(sb_dsp_t* dsp) { From 0362f563f6ffbac876a002c7e552885cbf358d34 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 16:14:50 +0600 Subject: [PATCH 316/690] Some fixes --- src/sound/snd_ess.c | 4 ++-- src/sound/snd_sb_dsp.c | 43 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 400983aba..57ba092c3 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -250,7 +250,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -334,7 +334,7 @@ ess_mixer_read(uint16_t addr, void *priv) break; } - return 0x00; + return 0x0a; } void diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 90d66c144..7cc189d30 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -585,15 +585,53 @@ sb_16_write_dma(void *priv, uint16_t val) void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { + uint8_t t = 0x00; sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; + + /* legacy audio interrupt control */ + t = 0x80;/*game compatible IRQ*/ + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + ESSreg(0xB1) = t; + + /* DRQ control */ + t = 0x80;/*game compatible DRQ */ + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = t; } void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { + uint8_t t = 0x00; sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; + + /* legacy audio interrupt control */ + t = 0x80;/*game compatible IRQ*/ + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + ESSreg(0xB1) = t; + + /* DRQ control */ + t = 0x80;/*game compatible DRQ */ + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = t; } void @@ -661,7 +699,7 @@ static void sb_ess_update_autolen(sb_dsp_t *dsp) { static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; - sb_dsp_log("ESS register write reg=%02xh val=%02xh\n",reg,data); + pclog("ESS register write reg=%02xh val=%02xh\n",reg,data); switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ @@ -798,6 +836,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8051_ram[0x20] = dsp->sb_command; if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; @@ -1365,7 +1404,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_command <= 0xC0) { sb_commands[dsp->sb_command] = 1; } else { - sb_commands[dsp->sb_command] = 0; + sb_commands[dsp->sb_command] = -1; } } } From f4c2a9c3ac6daffba83d395ae3b64bc672cd31e3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 21:43:57 +0600 Subject: [PATCH 317/690] Logging aids --- src/sound/snd_ess.c | 6 +++++- src/sound/snd_sb_dsp.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 57ba092c3..a97d5e244 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -151,6 +151,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; + pclog("ess: Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -197,6 +198,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x40: { + break; uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); /* This doesn't work yet. */ @@ -318,6 +320,7 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: + pclog("ess: Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: @@ -326,6 +329,7 @@ ess_mixer_read(uint16_t addr, void *priv) mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; + pclog("ess: ID READ: %02X (pos %d)\n", val, mixer->ess_id_str_pos); return val; } @@ -491,7 +495,7 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&ess->dsp, ess->mpu); ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x000; + ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); return ess; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7cc189d30..a6069226d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -834,9 +834,9 @@ sb_exec_command(sb_dsp_t *dsp) See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; + pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; From b8ff131996de0538bc6b5c6cb86c050d7ac803bd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 23:41:38 +0600 Subject: [PATCH 318/690] More changes --- src/sound/snd_sb_dsp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index a6069226d..44d9d0950 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -710,10 +710,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) else dsp->sb_freq = 397700UL / (128ul - data); - if (dsp->sb_16_enable || dsp->sb_8_enable) { - sb_stop_dma_ess(dsp); - sb_start_dma_ess(dsp); - } break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -742,8 +738,15 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) ESSreg(reg) = data; if (chg & 0x3) { if (dsp->sb_16_enable || dsp->sb_8_enable) { - sb_stop_dma_ess(dsp); - sb_start_dma_ess(dsp); + uint8_t real_format = 0x00; + real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; + real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; + + if (dsp->sb_16_enable) + dsp->sb_16_format = real_format; + + if (dsp->sb_8_enable) + dsp->sb_8_format = real_format; } } break; From c76ada30b7105f09700b9fe0f6e72248d1c5bc8d Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 5 Mar 2024 21:22:15 -0300 Subject: [PATCH 319/690] Some cleanup, implementing IRQ and DMA channel register update --- src/sound/snd_ess.c | 62 +++++++++++++++---------- src/sound/snd_sb_dsp.c | 102 +++++++++++++++++++++++++++-------------- 2 files changed, 105 insertions(+), 59 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index a97d5e244..0193c69c9 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -6,16 +6,20 @@ * * This file is part of the 86Box distribution. * - * Sound Blaster emulation. + * ESS AudioDrive emulation. * * * * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, + * Cacodemon345, + * Kagamiin~, * * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. + * Copyright 2024 Cacodemon345 + * Copyright 2024 Kagamiin~ */ #include #include @@ -79,7 +83,7 @@ typedef struct ess_mixer_t { uint8_t regs[256]; uint8_t ess_id_str[256]; - uint8_t ess_id_str_pos : 2; + uint8_t ess_id_str_pos; } ess_mixer_t; typedef struct ess_t { @@ -130,7 +134,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->index = val; mixer->regs[0x01] = val; if (val == 0x40) + { + pclog("ess: Mixer addr 0x40 selected, ID string offset reset\n"); mixer->ess_id_str_pos = 0; + } } else { if (mixer->index == 0) { /* Reset */ @@ -151,7 +158,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; - pclog("ess: Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Mixer Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -198,23 +205,27 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x40: { - break; - uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - /* This doesn't work yet. */ - /* - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if (mixer->regs[0x40] & 1) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - }*/ + /* TODO: Implement "Read-Sequence-Key" method of software address selection + * (needed for ESSCFG.EXE to work properly) */ - switch ((mixer->regs[0x40] >> 5) & 7) { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + + /* This doesn't work yet. */ +#if 1 + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) + { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } +#endif + switch ((mixer->regs[0x40] >> 5) & 0x7) { case 0: mpu401_change_addr(ess->mpu, 0x00); mpu401_setirq(ess->mpu, -1); @@ -252,7 +263,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - pclog("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -320,21 +331,22 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - pclog("ess: Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; - pclog("ess: ID READ: %02X (pos %d)\n", val, mixer->ess_id_str_pos); + pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } default: - pclog("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } @@ -491,7 +503,7 @@ ess_1688_init(UNUSED(const device_t *info)) } ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - mpu401_init(ess->mpu, 0, 0, M_UART, 1); + mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); ess->gameport = gameport_add(&gameport_pnp_device); @@ -620,4 +632,4 @@ const device_t ess_1688_device = { .speed_changed = ess_speed_changed, .force_redraw = NULL, .config = ess_config -}; \ No newline at end of file +}; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 44d9d0950..d14b41d9e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -582,6 +582,37 @@ sb_16_write_dma(void *priv, uint16_t val) return ret; } +void +sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) +{ + uint8_t t = 0x00; + /* IRQ control */ + if (legacy) + { + t |= 0x80; + } + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + pclog("ESSreg 0xB1 was %02X, irqnum is %d, t is %02X; new 0xB1 is %02X\n", ESSreg(0xB1), dsp->sb_irqnum, t, (ESSreg(0xB1) & 0xF0) | t); + ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; + + /* DRQ control */ + t = 0x00; + if (legacy) + { + t |= 0x80; + } + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = (ESSreg(0xB2) & 0xF0) | t; +} + void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { @@ -589,23 +620,7 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; - /* legacy audio interrupt control */ - t = 0x80;/*game compatible IRQ*/ - switch (dsp->sb_irqnum) { - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; - } - ESSreg(0xB1) = t; - - /* DRQ control */ - t = 0x80;/*game compatible DRQ */ - switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; - } - ESSreg(0xB2) = t; + sb_ess_update_irq_drq_readback_regs(dsp, true); } void @@ -615,23 +630,7 @@ sb_dsp_setdma8(sb_dsp_t *dsp, int dma) sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; - /* legacy audio interrupt control */ - t = 0x80;/*game compatible IRQ*/ - switch (dsp->sb_irqnum) { - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; - } - ESSreg(0xB1) = t; - - /* DRQ control */ - t = 0x80;/*game compatible DRQ */ - switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; - } - ESSreg(0xB2) = t; + sb_ess_update_irq_drq_readback_regs(dsp, true); } void @@ -686,6 +685,7 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: + pclog("ESS register read reg=%02xh val=%02xh\n",reg, ESSreg(reg)); return ESSreg(reg); } @@ -752,9 +752,43 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; case 0xB1: /* Legacy Audio Interrupt Control */ + ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + switch (data & 0x0C) + { + case 0x00: + dsp->sb_irqnum = 2; + break; + case 0x04: + dsp->sb_irqnum = 5; + break; + case 0x08: + dsp->sb_irqnum = 7; + break; + case 0x0C: + dsp->sb_irqnum = 10; + break; + } + sb_ess_update_irq_drq_readback_regs(dsp, false); + break; case 0xB2: /* DRQ Control */ chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + switch (data & 0x0C) + { + case 0x00: + dsp->sb_8_dmanum = -1; + break; + case 0x04: + dsp->sb_8_dmanum = 0; + break; + case 0x08: + dsp->sb_8_dmanum = 1; + break; + case 0x0C: + dsp->sb_8_dmanum = 3; + break; + } + sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; case 0xB5: /* DAC Direct Access Holding (low) */ From d3aa111ba3b4e93667fdcf1181459621539225c5 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 8 Mar 2024 12:13:09 -0300 Subject: [PATCH 320/690] Fix bug in command length override; fix some other stuff; logging galore --- src/sound/snd_ess.c | 8 +++++ src/sound/snd_sb_dsp.c | 74 +++++++++++++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0193c69c9..3de6615a3 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -335,7 +335,10 @@ ess_mixer_read(uint16_t addr, void *priv) return mixer->regs[mixer->index]; case 0x40: + + if (0) { + // not on ES1688 uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; @@ -344,6 +347,11 @@ ess_mixer_read(uint16_t addr, void *priv) pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } + else + { + pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + return mixer->regs[mixer->index]; + } default: pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d14b41d9e..fdcaf4587 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -228,7 +228,10 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked"); return; + } } if (set && !masked) @@ -240,6 +243,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) void sb_irq(sb_dsp_t *dsp, int irq8) { + pclog("sb: IRQ raised\n"); sb_update_status(dsp, !irq8, 1); } @@ -330,6 +334,9 @@ sb_doreset(sb_dsp_t *dsp) dsp->sb_asp_regs[5] = 0x01; dsp->sb_asp_regs[9] = 0xf8; + + /* Initialize ESS registers */ + ESSreg(0xA5) = 0xf8; } void @@ -596,7 +603,6 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) case 7: t |= 0xA; break; case 10: t |= 0xF; break; } - pclog("ESSreg 0xB1 was %02X, irqnum is %d, t is %02X; new 0xB1 is %02X\n", ESSreg(0xB1), dsp->sb_irqnum, t, (ESSreg(0xB1) & 0xF0) | t); ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; /* DRQ control */ @@ -704,11 +710,16 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ { + double temp; ESSreg(reg) = data; if (data & 0x80) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); + temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_timei = dsp->sb_timeo; + pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); break; } @@ -720,6 +731,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); + pclog("ess: DMA Transfer Count Reload length set to %d samples\n", sb_ess_get_dma_len(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -855,6 +867,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: + pclog("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); break; } } @@ -870,8 +883,21 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) + { dsp->sb_8051_ram[0x20] = dsp->sb_command; - pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); + } + + { + int i; + char data_s[256]; + data_s[0] = '\0'; + + for (i = 0; i < sb_commands[dsp->sb_command]; i++) + { + snprintf(data_s, 256, " 0x%02X", dsp->sb_data[i]); + } + pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); + } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { @@ -1083,7 +1109,8 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; - sb_dsp_log("Sample rate - %ihz (%i)\n", temp, dsp->sblatcho); + sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); + pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1095,7 +1122,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x42: /* Set input sampling rate */ if (dsp->sb_type >= SB16) { dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); - sb_dsp_log("Sample rate - %ihz (%i)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + pclog("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256LL + dsp->sb_freq; @@ -1396,6 +1424,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; + //pclog("sb: port write %03x %02x\n", a, v); + switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -1428,8 +1458,6 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (v == 0x01) sb_add_data(dsp, 0); dsp->sb_data_stat++; - } else { - dsp->sb_data[dsp->sb_data_stat++] = v; if (IS_AZTECH(dsp)) { /* variable length commands */ if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) @@ -1444,6 +1472,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = -1; } } + } else { + dsp->sb_data[dsp->sb_data_stat++] = v; } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); @@ -1469,7 +1499,13 @@ sb_read(uint16_t a, void *priv) /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ if (dsp->sb_type < SB16) - a &= 0xfffe; + { + /* Exception: ESS AudioDrive does not alias port base+0xf */ + if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) + { + a &= 0xfffe; + } + } switch (a & 0xf) { case 0xA: /* Read data */ @@ -1509,6 +1545,10 @@ sb_read(uint16_t a, void *priv) break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); + if (dsp->sb_irq8 || dsp->sb_irq16) + { + pclog("sb: IRQ acknowledged\n"); + } dsp->sb_irq8 = dsp->sb_irq16 = 0; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ if (IS_AZTECH(dsp)) { @@ -1520,16 +1560,25 @@ sb_read(uint16_t a, void *priv) } break; case 0xF: /* 16-bit ack */ - dsp->sb_irq16 = 0; - if (!dsp->sb_irq8) - dsp->irq_update(dsp->irq_priv, 0); - sb_dsp_log("SB 16-bit ACK read 0xFF\n"); + if (!IS_ESS(dsp)) + { + if (dsp->sb_irq16) + { + pclog("sb: 16-bit IRQ acknowledged"); + } + dsp->sb_irq16 = 0; + if (!dsp->sb_irq8) + dsp->irq_update(dsp->irq_priv, 0); + sb_dsp_log("SB 16-bit ACK read 0xFF\n"); + } ret = 0xff; break; default: break; } + + //pclog("sb: port read %03x %02x\n", a, ret); return ret; } @@ -1634,6 +1683,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) dsp->sb_8051_ram[0x37] = 0x38; memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); + } void @@ -1692,6 +1742,7 @@ sb_ess_finish_dma(sb_dsp_t *dsp) return; ESSreg(0xB8) &= ~0x01; dma_set_drq(dsp->sb_8_dmanum, 0); + pclog("ess: DMA finished"); } void @@ -1886,6 +1937,7 @@ pollsb(void *priv) break; } + if (dsp->sb_8_length < 0) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; From 6d3f2c478b97299c41d0735367b2e33069410b5f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 9 Mar 2024 19:14:36 -0300 Subject: [PATCH 321/690] Fix port 388h being disabled erroneously; set filter freq on sample rate change --- src/sound/snd_ess.c | 30 +++++++++++++++--------------- src/sound/snd_sb_dsp.c | 5 +++++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 3de6615a3..f771ee6db 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -135,7 +135,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x01] = val; if (val == 0x40) { - pclog("ess: Mixer addr 0x40 selected, ID string offset reset\n"); mixer->ess_id_str_pos = 0; } } else { @@ -211,20 +210,21 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - /* This doesn't work yet. */ -#if 1 - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) + if (0) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); + /* Not on ES1688. */ + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) + { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } } -#endif switch ((mixer->regs[0x40] >> 5) & 0x7) { case 0: mpu401_change_addr(ess->mpu, 0x00); @@ -338,7 +338,7 @@ ess_mixer_read(uint16_t addr, void *priv) if (0) { - // not on ES1688 + /* not on ES1688 */ uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; @@ -475,6 +475,7 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); + /* DSP I/O handler is activated in sb_dsp_setaddr */ { io_sethandler(addr, 0x0004, @@ -502,7 +503,6 @@ ess_1688_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); - { ess->mixer_sbpro.ess_id_str[0] = 0x16; ess->mixer_sbpro.ess_id_str[1] = 0x88; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index fdcaf4587..3d150b9f9 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -716,6 +716,11 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); + // TODO: check if this command updates the filter or not + sb_ess_update_filter_freq(dsp); + ESSreg(reg) = data; /* HACK: sb_ess_update_filter_freq updates 0xA1. + * I'm not sure if that could cause an off by one + * error, so this is just to be safe. */ temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; From b59db332f0152b3271351fd2c4518137e902b457 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 9 Mar 2024 23:55:36 -0300 Subject: [PATCH 322/690] Implement registers 0xC2/0xC3; sound now works in Win3.1 --- src/sound/snd_sb_dsp.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 3d150b9f9..0b55953da 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -868,6 +868,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xB9: /* Audio 1 Transfer Type */ case 0xBA: /* Left Channel ADC Offset Adjust */ case 0xBB: /* Right Channel ADC Offset Adjust */ + case 0xC3: /* Internal state register */ ESSreg(reg) = data; break; @@ -909,9 +910,18 @@ sb_exec_command(sb_dsp_t *dsp) dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; } - if (dsp->sb_command == 0xC0) { + else if (dsp->sb_command == 0xC2) + { + sb_ess_write_reg(dsp, 0xC3, dsp->sb_data[0]); + } + else if (dsp->sb_command == 0xC3) + { + sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); + } + else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); - } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + } + else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); } return; @@ -1471,7 +1481,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = 2; } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0) { + if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { sb_commands[dsp->sb_command] = 1; } else { sb_commands[dsp->sb_command] = -1; From 34be04ab800321ce797cf1634ee5318e52f63c10 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 10 Mar 2024 15:32:57 -0300 Subject: [PATCH 323/690] Implementing command 0xF2 IRQ masking behavior --- src/include/86box/snd_sb_dsp.h | 2 ++ src/sound/snd_sb_dsp.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 2b39a0303..4c0aab113 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -130,6 +130,8 @@ typedef struct sb_dsp_t { pc_timer_t wb_timer; int wb_full; + pc_timer_t irq_timer; + int busy_count; int record_pos_read; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 0b55953da..30931f3d6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -209,6 +209,15 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) { int masked = 0; + if (dsp->sb_irq8 || dsp->sb_irq16) + return; + + if (!(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked"); + return; + } + switch (bit) { default: case 0: @@ -599,6 +608,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_irqnum) { + case 9: t |= 0x0; break; case 5: t |= 0x5; break; case 7: t |= 0xA; break; case 10: t |= 0xF; break; @@ -627,6 +637,8 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) dsp->sb_irqnum = irq; sb_ess_update_irq_drq_readback_regs(dsp, true); + + ESSreg(0xB1) = (ESSreg(0xB1) & 0xEF) | 0x10; } void @@ -1384,7 +1396,15 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 1); + if (IS_ESS(dsp)) { + if (timer_is_enabled(&dsp->irq_timer)) + pclog("F2 already written\n"); + else { + timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); + pclog("F2 written\n"); + } + } else + sb_irq(dsp, 1); break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); @@ -1483,6 +1503,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { sb_commands[dsp->sb_command] = 1; + } else if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { + sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; } @@ -1652,6 +1674,14 @@ sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) return 0; } +void +sb_dsp_irq_poll(void *priv) +{ + sb_dsp_t *dsp = (sb_dsp_t *) priv; + + sb_irq(dsp, 1); +} + void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { @@ -1680,6 +1710,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) timer_add(&dsp->output_timer, pollsb, dsp, 0); timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); timer_add(&dsp->wb_timer, NULL, dsp, 0); + timer_add(&dsp->irq_timer, sb_dsp_irq_poll, dsp, 0); /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent. */ From 7c998872935b4582df029b3e503a1dc0fa6b63b6 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Mon, 11 Mar 2024 18:49:10 -0300 Subject: [PATCH 324/690] Implementing ESS DMA counter; handling disable of auto-init while DMA is turned on --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 178 +++++++++++++++++++++++++++------ 2 files changed, 148 insertions(+), 31 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 4c0aab113..4833dea33 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -146,6 +146,7 @@ typedef struct sb_dsp_t { uint8_t ess_playback_mode; uint8_t ess_extended_mode; uint8_t ess_reload_len; + uint32_t ess_dma_counter; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 30931f3d6..ebda12652 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -212,9 +212,11 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->sb_irq8 || dsp->sb_irq16) return; - if (!(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire + /* NOTE: not on ES1688 or ES1868 */ + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 + && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked"); + pclog("ess: IRQ was masked\n"); return; } @@ -238,7 +240,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked"); + pclog("ess: IRQ was masked\n"); return; } } @@ -369,15 +371,19 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } +static unsigned int sb_ess_get_dma_counter(sb_dsp_t *dsp) +{ + unsigned int c; + + c = (unsigned int)ESSreg(0xA5) << 8U; + c |= (unsigned int)ESSreg(0xA4); + + return c; +} + static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) { - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; + return 0x10000U - sb_ess_get_dma_counter(dsp); } void @@ -385,11 +391,6 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { dsp->sb_pausetime = -1; - if (dsp->ess_reload_len) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } - if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -424,11 +425,6 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - if (dsp->ess_reload_len) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } - if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -460,12 +456,8 @@ void sb_start_dma_ess(sb_dsp_t* dsp) { uint8_t real_format = 0; - uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - - if (dsp->ess_reload_len || len <= 0) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + uint32_t len = sb_ess_get_dma_len(dsp); if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); @@ -748,7 +740,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - pclog("ess: DMA Transfer Count Reload length set to %d samples\n", sb_ess_get_dma_len(dsp)); + pclog("ess: DMA Transfer Count Reload length set to %d samples (0x%x)\n", sb_ess_get_dma_len(dsp), sb_ess_get_dma_counter(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -871,6 +863,18 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->ess_reload_len = 1; } + if (chg & 0x4) + { + if (dsp->sb_16_enable) + { + dsp->sb_16_autoinit = (ESSreg(0xB8) & 0x4) != 0; + } + if (dsp->sb_8_enable) + { + dsp->sb_8_autoinit = (ESSreg(0xB8) & 0x4) != 0; + } + } + if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); @@ -1060,8 +1064,12 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x17) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x1C: /* 8-bit autoinit DMA output */ if (dsp->sb_type >= SB15) @@ -1072,6 +1080,7 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x20: /* 8-bit direct input */ @@ -1177,8 +1186,12 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x75) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x77: /* 2.6-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); @@ -1188,14 +1201,19 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x77) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x7D: /* 4-bit ADPCM autoinit output */ if (dsp->sb_type >= SB15) { sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x7F: /* 2.6-bit ADPCM autoinit output */ @@ -1203,6 +1221,7 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x80: /* Pause DAC */ @@ -1822,6 +1841,7 @@ pollsb(void *priv) } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; + dsp->ess_dma_counter++; break; case 0x10: /* Mono signed */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1839,6 +1859,7 @@ pollsb(void *priv) } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; + dsp->ess_dma_counter++; break; case 0x20: /* Stereo unsigned */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1848,6 +1869,7 @@ pollsb(void *priv) dsp->sbdatl = (data[0] ^ 0x80) << 8; dsp->sbdatr = (data[1] ^ 0x80) << 8; dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; break; case 0x30: /* Stereo signed */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1857,6 +1879,7 @@ pollsb(void *priv) dsp->sbdatl = data[0] << 8; dsp->sbdatr = data[1] << 8; dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; break; case ADPCM_4: @@ -1886,6 +1909,7 @@ pollsb(void *priv) dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1929,6 +1953,7 @@ pollsb(void *priv) dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1965,6 +1990,8 @@ pollsb(void *priv) if (dsp->sbdacpos >= 4) { dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1984,7 +2011,7 @@ pollsb(void *priv) } - if (dsp->sb_8_length < 0) { + if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; else { @@ -1994,6 +2021,26 @@ pollsb(void *priv) } sb_irq(dsp, 1); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_8_autoinit) + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 1); + pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { sb_dsp_update(dsp); @@ -2005,6 +2052,7 @@ pollsb(void *priv) break; dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; break; case 0x10: /* Mono signed */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2012,6 +2060,7 @@ pollsb(void *priv) break; dsp->sbdatl = dsp->sbdatr = data[0]; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; break; case 0x20: /* Stereo unsigned */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2021,6 +2070,7 @@ pollsb(void *priv) dsp->sbdatl = data[0] ^ 0x8000; dsp->sbdatr = data[1] ^ 0x8000; dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; break; case 0x30: /* Stereo signed */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2030,13 +2080,14 @@ pollsb(void *priv) dsp->sbdatl = data[0]; dsp->sbdatr = data[1]; dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; break; default: break; } - if (dsp->sb_16_length < 0) { + if (dsp->sb_16_length < 0 && !dsp->ess_playback_mode) { sb_dsp_log("16DMA over %i\n", dsp->sb_16_autoinit); if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_origlength = dsp->sb_16_autolen; @@ -2047,6 +2098,25 @@ pollsb(void *priv) } sb_irq(dsp, 0); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_16_autoinit) + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 0); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } } if (dsp->sb_pausetime > -1) { dsp->sb_pausetime--; @@ -2072,12 +2142,14 @@ sb_poll_i(void *priv) case 0x00: /* Mono unsigned As the manual says, only the left channel is recorded */ dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); dsp->sb_8_length--; + dsp->ess_dma_counter++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; case 0x10: /* Mono signed As the manual says, only the left channel is recorded */ dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8)); dsp->sb_8_length--; + dsp->ess_dma_counter++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2085,6 +2157,7 @@ sb_poll_i(void *priv) dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8) ^ 0x80); dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2092,6 +2165,7 @@ sb_poll_i(void *priv) dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8)); dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8)); dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2100,7 +2174,7 @@ sb_poll_i(void *priv) break; } - if (dsp->sb_8_length < 0) { + if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; else { @@ -2110,6 +2184,25 @@ sb_poll_i(void *priv) } sb_irq(dsp, 1); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_8_autoinit) + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 1); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } processed = 1; } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) { @@ -2118,6 +2211,7 @@ sb_poll_i(void *priv) if (dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read] ^ 0x8000)) return; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2125,6 +2219,7 @@ sb_poll_i(void *priv) if (dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read])) return; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2133,6 +2228,7 @@ sb_poll_i(void *priv) return; dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read + 1] ^ 0x8000); dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2141,6 +2237,7 @@ sb_poll_i(void *priv) return; dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read + 1]); dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2149,7 +2246,7 @@ sb_poll_i(void *priv) break; } - if (dsp->sb_16_length < 0) { + if (dsp->sb_16_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_origlength = dsp->sb_16_autolen; else { @@ -2159,6 +2256,25 @@ sb_poll_i(void *priv) } sb_irq(dsp, 0); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_16_autoinit) + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 0); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } processed = 1; } /* Assume this is direct mode */ From 7ad48f8d2996b5ced373b19dbd4f80a0d9827647 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 12 Mar 2024 10:10:00 -0300 Subject: [PATCH 325/690] Switching filter implementation to use SB16 filters; fixing CD audio volume --- src/sound/snd_ess.c | 11 ++---- src/sound/snd_sb_dsp.c | 88 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f771ee6db..9996ad006 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -150,7 +150,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Initialize ESS regs. */ mixer->regs[0x14] = mixer->regs[0x32] = 0x88; mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x00; + mixer->regs[0x38] = 0x88; mixer->regs[0x3a] = 0x00; mixer->regs[0x3e] = 0x00; @@ -384,8 +384,8 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { - out_l += (sb_iir(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.9; - out_r += (sb_iir(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; + out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; } else { out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; @@ -446,10 +446,7 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; - if (mixer->output_filter) - c = (sb_iir(2, channel, *buffer) * cd) / 3.9; - else - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ebda12652..f179ce284 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -175,6 +175,37 @@ recalc_sb16_filter(int c, int playback_freq) low_fir_sb16_coef[c][n] /= gain; } +static void +recalc_opl_filter(int c, int playback_freq) +{ + /* Cutoff frequency = playback / 2 */ + int n; + double w; + double h; + double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); + double gain; + + for (n = 0; n < SB16_NCoef; n++) { + /* Blackman window */ + w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + /* Sinc filter */ + h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + + /* Create windowed-sinc filter */ + low_fir_sb16_coef[c][n] = w * h; + } + + low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) + gain += low_fir_sb16_coef[c][n]; + + /* Normalise filter, to produce unity gain */ + for (n = 0; n < SB16_NCoef; n++) + low_fir_sb16_coef[c][n] /= gain; +} + static void sb_irq_update_pic(void *priv, int set) { @@ -678,17 +709,29 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } +static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +{ + double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + int temp = (int) freq; + ESSreg(0xA2) = val; + + if (dsp->sb_freq != temp) + recalc_sb16_filter(0, temp); + dsp->sb_freq = temp; +} + /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { + double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; + if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); else ESSreg(0xA1) = 128 - (397700UL / dsp->sb_freq); - unsigned int freq = ((dsp->sb_freq * 4) / (5 * 2)); /* 80% of 1/2 the sample rate */ - ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); + sb_ess_update_reg_a2(dsp, (uint8_t) temp); } static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) @@ -720,20 +763,14 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); - // TODO: check if this command updates the filter or not - sb_ess_update_filter_freq(dsp); - ESSreg(reg) = data; /* HACK: sb_ess_update_filter_freq updates 0xA1. - * I'm not sure if that could cause an off by one - * error, so this is just to be safe. */ temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); - break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ - ESSreg(reg) = data; + sb_ess_update_reg_a2(dsp, data); break; case 0xA4: /* DMA Transfer Count Reload (low) */ @@ -1147,6 +1184,7 @@ sb_exec_command(sb_dsp_t *dsp) temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); + // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1165,7 +1203,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_timeo = 256LL + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; dsp->sb_timei = dsp->sb_timeo; - if (dsp->sb_freq != temp && dsp->sb_type >= SB16) + if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, dsp->sb_freq); dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; @@ -1731,14 +1769,30 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) timer_add(&dsp->wb_timer, NULL, dsp, 0); timer_add(&dsp->irq_timer, sb_dsp_irq_poll, dsp, 0); - /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when - a set frequency command is sent. */ - recalc_sb16_filter(0, 3200 * 2); - if (dsp->sb_has_real_opl) - recalc_sb16_filter(1, FREQ_49716); + if (IS_ESS(dsp)) + /* Initialize ESS filter to 8 kHz. This will be recalculated when a set frequency command is + sent. */ + recalc_sb16_filter(0, 8000 * 2); else - recalc_sb16_filter(1, FREQ_48000); - recalc_sb16_filter(2, FREQ_44100); + /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when + a set frequency command is sent. */ + recalc_sb16_filter(0, 3200 * 2); + if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { + /* OPL3 or dual OPL2 is stereo. */ + if (dsp->sb_has_real_opl) + recalc_opl_filter(1, FREQ_49716 * 2); + else + recalc_sb16_filter(1, FREQ_48000 * 2); + } else { + /* OPL2 is mono. */ + if (dsp->sb_has_real_opl) + recalc_opl_filter(1, FREQ_49716); + else + recalc_sb16_filter(1, FREQ_48000); + } + /* CD Audio is stereo. */ + recalc_sb16_filter(2, FREQ_44100 * 2); + /* PC speaker is mono. */ recalc_sb16_filter(3, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ From 0ed203cbd50dc697a453ffebdf8722db8420308f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 12 Mar 2024 18:12:57 -0300 Subject: [PATCH 326/690] Mixer functions; recording (incomplete/commented out); set default IRQ to 5 --- src/include/86box/snd_sb.h | 16 +-- src/sound/snd_ess.c | 211 +++++++++++++++++++++++++++++++------ 2 files changed, 188 insertions(+), 39 deletions(-) diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 621cb4ade..f236c284a 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -105,13 +105,15 @@ typedef struct sb_ct1745_mixer_t { int input_selector_left; int input_selector_right; -#define INPUT_MIC 1 -#define INPUT_CD_R 2 -#define INPUT_CD_L 4 -#define INPUT_LINE_R 8 -#define INPUT_LINE_L 16 -#define INPUT_MIDI_R 32 -#define INPUT_MIDI_L 64 +#define INPUT_MIC 1 +#define INPUT_CD_R 2 +#define INPUT_CD_L 4 +#define INPUT_LINE_R 8 +#define INPUT_LINE_L 16 +#define INPUT_MIDI_R 32 +#define INPUT_MIDI_L 64 +#define INPUT_MIXER_L 128 +#define INPUT_MIXER_R 256 int mic_agc; diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 9996ad006..0f57bca7d 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -21,6 +21,7 @@ * Copyright 2024 Cacodemon345 * Copyright 2024 Kagamiin~ */ + #include #include #include @@ -48,6 +49,8 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> + + static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 }; @@ -56,6 +59,11 @@ static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; +static const double sb_att_1p4dbstep_4bits[] = { + 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, + 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 +}; + /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -68,7 +76,10 @@ typedef struct ess_mixer_t { double cd_r; double line_l; double line_r; - double mic; + double mic_l; + double mic_r; + double auxb_l; + double auxb_r; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; @@ -84,6 +95,12 @@ typedef struct ess_mixer_t { uint8_t ess_id_str[256]; uint8_t ess_id_str_pos; + +#if 0 + int record_pos_write_cd; + double record_pos_write_cd_sigma; + int record_pos_write_music; +#endif } ess_mixer_t; typedef struct ess_t { @@ -166,11 +183,57 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x08: mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); break; - + + case 0x0A: + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2); + break; + } + + case 0x0C: + switch (mixer->regs[0x0C] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + break; + case 0x14: mixer->regs[0x4] = val & 0xee; break; + case 0x1A: + mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF]; + mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF]; + break; + + case 0x1C: + if ((mixer->regs[0x1C] & 0x07) == 0x07) + { + mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; + } + else if ((mixer->regs[0x1C] & 0x07) == 0x06) + { + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + } + else if ((mixer->regs[0x1C] & 0x06) == 0x02) + { + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + } + else if ((mixer->regs[0x1C] & 0x02) == 0) + { + mixer->input_selector = INPUT_MIC; + } + break; + case 0x22: case 0x26: case 0x28: @@ -192,10 +255,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[mixer->index - 0x10] = (val & 0xee); break; + case 0x3a: + break; + case 0x00: case 0x04: - case 0x0a: - case 0x0c: + break; + case 0x0e: break; @@ -268,18 +334,18 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } } - mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14]); - mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); - mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32]); - mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); - mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36]); - mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); - mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38]); - mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); - mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); - mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); - - mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); + mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14]); + mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); + mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32]); + mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); + mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36]); + mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); + mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38]); + mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); + mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); + mixer->auxb_l = ess_mixer_get_vol_4bit(mixer->regs[0x3a] >> 4); + mixer->auxb_r = ess_mixer_get_vol_4bit(mixer->regs[0x3a]); mixer->output_filter = !(mixer->regs[0xe] & 0x20); mixer->input_filter = !(mixer->regs[0xc] & 0x20); @@ -288,18 +354,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (mixer->index == 0xe) sb_dsp_set_stereo(&ess->dsp, val & 2); - switch (mixer->regs[0xc] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } - /* TODO: pcspeaker volume? Or is it not worth? */ } } @@ -406,7 +460,13 @@ void ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + const ess_mixer_t *mixer = &ess->mixer_sbpro; +#if 0 + int rec_pos = ess->mixer_sbpro.record_pos_write_music; + int c_record; + int32_t in_l; + int32_t in_r; +#endif double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; @@ -430,24 +490,106 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l *= mixer->master_l; out_r *= mixer->master_r; +#if 0 + // Pull input after applying mixer's master volume scaling + in_l = (mixer->input_selector & INPUT_MIXER_L) ? ((int32_t) out_l) : 0; + in_r = (mixer->input_selector & INPUT_MIXER_R) ? ((int32_t) out_l) : 0; + + if (ess->dsp.sb_enable_i) { + // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? + c_record = rec_pos + ((c * ess->dsp.sb_freq) / MUSIC_FREQ); + + ess->dsp.record_buffer[c_record & 0xfffe] += in_l; + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] += in_r; + + if (ess->dsp.record_buffer[c_record & 0xfffe] < -32768) + { + ess->dsp.record_buffer[c_record & 0xfffe] = -32768; + } + else if (ess->dsp.record_buffer[c_record & 0xfffe] > 32767) + { + ess->dsp.record_buffer[c_record & 0xfffe] = 32767; + } + + if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] < -32768) + { + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = -32768; + } + else if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] > 32767) + { + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; + } + } + buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; +#endif } +#if 0 + ess->mixer_sbpro.record_pos_write_music += ((len * 2 * ess->dsp.sb_freq) / MUSIC_FREQ); + ess->mixer_sbpro.record_pos_write_music &= 0xfffe; + + if (ess->mixer_sbpro.record_pos_write_music < ess->mixer_sbpro.record_pos_write_cd) + { + ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_music; + } +#endif + ess->opl.reset_buffer(ess->opl.priv); } void ess_filter_cd_audio(int channel, double *buffer, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; double c; +#if 0 + double rec_pos = ess->mixer_sbpro.record_pos_write_cd; + double rec_pos_sigma = ess->mixer_sbpro.record_pos_write_cd_sigma; + int c_record; + int selector = channel ? INPUT_MIXER_R : INPUT_MIXER_L; + int rec_buf_pos; + int32_t in; +#endif double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; c = (*buffer * cd) / 3.0; *buffer = c * master; +#if 0 + in = (mixer->input_selector & selector) ? (int32_t)(c * master) : 0; + + if (ess->dsp.sb_enable_i) + { + // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? + c_record = (int)(rec_pos + rec_pos_sigma); + rec_buf_pos = channel ? ((c_record & 0xfffe) + 1) : (c_record & 0xfffe); + + ess->dsp.record_buffer[rec_buf_pos] += in; + + if (ess->dsp.record_buffer[rec_buf_pos] < -32768) + { + ess->dsp.record_buffer[rec_buf_pos] = -32768; + } + else if (ess->dsp.record_buffer[rec_buf_pos] > 32767) + { + ess->dsp.record_buffer[rec_buf_pos] = 32767; + } + } + + ess->mixer_sbpro.record_pos_write_cd += ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma; + ess->mixer_sbpro.record_pos_write_cd &= ~1; + ess->mixer_sbpro.record_pos_write_cd_sigma = (double)rec_pos + ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma - ess->mixer_sbpro.record_pos_write_cd; + + ess->mixer_sbpro.record_pos_write_cd &= 0xfffe; + + if (ess->mixer_sbpro.record_pos_write_cd < ess->mixer_sbpro.record_pos_write_music) + { + ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_cd; + } +#endif } static void * @@ -507,6 +649,11 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } +#if 0 + ess->mixer_sbpro.record_pos_write_cd = ess->dsp.record_pos_write; + ess->mixer_sbpro.record_pos_write_music = ess->dsp.record_pos_write; +#endif + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); @@ -561,7 +708,7 @@ static const device_config_t ess_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 7, + .default_int = 5, .file_filter = "", .spinner = { 0 }, .selection = { From f4c75226efee7fc23267322f5a9ffd80fd139660 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 00:05:45 -0300 Subject: [PATCH 327/690] Implementing ESPCM decompression (incomplete) --- src/include/86box/snd_sb_dsp.h | 9 +- src/sound/snd_sb_dsp.c | 200 +++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 4833dea33..6e5266b43 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -9,7 +9,7 @@ #define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) +#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES688 || (dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -148,6 +148,13 @@ typedef struct sb_dsp_t { uint8_t ess_reload_len; uint32_t ess_dma_counter; + // ESPCM + uint8_t espcm_sample_idx; + uint8_t espcm_range; + uint8_t espcm_byte_buffer[4]; + uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ + uint8_t espcm_last_nibble; /* used for ESPCM_3 */ + mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index f179ce284..54c8bcc5e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -32,6 +32,9 @@ #define ADPCM_4 1 #define ADPCM_26 2 #define ADPCM_2 3 +#define ESPCM_4 4 +#define ESPCM_3 5 +#define ESPCM_1 6 // not ESPCM_2, unlike what the manuals say /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -116,6 +119,25 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; +uint8_t espcm_range_map[256] = { + -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, + -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, + -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, + -14, -12, -11, -9, -7, -5, -4, -2, 0, 2, 4, 5, 7, 9, 11, 13, + -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, + -21, -18, -16, -13, -11, -8, -6, -3, 0, 2, 5, 7, 10, 12, 15, 18, + -27, -24, -21, -17, -14, -11, -8, -4, 0, 3, 7, 10, 13, 17, 20, 24, + -35, -28, -24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24, 28, + -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, + -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 43, + -56, -49, -42, -35, -28, -21, -14, -7, 0, 7, 14, 21, 28, 35, 42, 49, + -72, -63, -54, -45, -36, -27, -18, -9, 0, 9, 18, 27, 36, 45, 54, 63, + -85, -74, -64, -53, -43, -32, -22, -11, 0, 11, 22, 33, 43, 54, 64, 75, + -102, -98, -85, -71, -58, -45, -31, -14, 0, 13, 26, 39, 52, 65, 78, 90, + -127,-112, -96, -80, -64, -48, -32, -16, 0, 16, 32, 48, 64, 80, 96, 112, + -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127 +}; + double low_fir_sb16_coef[4][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG @@ -1216,6 +1238,78 @@ sb_exec_command(sb_dsp_t *dsp) case 0x48: /* Set DSP block transfer size */ dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; + case 0x65: /* 4-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x64: /* 4-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x67: /* 3-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x66: /* 3-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x6B: /* 1-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x6A: /* 1-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x6F: /* 4-bit ESPCM input with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + fallthrough; + case 0x6E: /* 4-bit ESPCM input */ + if (IS_ESS(dsp)) + { + sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + } + break; case 0x75: /* 4-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; @@ -2060,6 +2154,112 @@ pollsb(void *priv) dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; + case ESPCM_4: + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; + } + else if (dsp->espcm_sample_idx & 1) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + tempi = dsp->espcm_byte_buffer[0] & 0x0F; + } + else + { + dsp->espcm_sample_idx++; + tempi = dsp->espcm_byte_buffer[0] >> 4; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } + break; + + case ESPCM_3: + // TODO + break; + + case ESPCM_1: + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + dsp->espcm_byte_buffer[0] >>= 5; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + else + { + dsp->espcm_sample_idx++; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } + break; + default: break; } From e2200f8d750d89543d5975d08e9895c0152f0c30 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 10:51:11 -0300 Subject: [PATCH 328/690] Add tables for ESPCM_3 mode --- src/include/86box/snd_sb_dsp.h | 2 +- src/sound/snd_sb_dsp.c | 101 ++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 6e5266b43..7b516a987 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -153,7 +153,7 @@ typedef struct sb_dsp_t { uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ - uint8_t espcm_last_nibble; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 54c8bcc5e..530d16015 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -119,7 +119,12 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -uint8_t espcm_range_map[256] = { +/* Upper half only used for ESPCM_3 mode. */ +/* TODO: Extract actual table (or exact ranges + range interpolation algo, whatever it is) from chip, someday, somehow. + * This current table is part software reverse engineering, part guesswork/extrapolation. + * It's close enough to what's in the chip to produce acceptable results, but not exact. + **/ +uint8_t espcm_range_map[512] = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, @@ -135,7 +140,99 @@ uint8_t espcm_range_map[256] = { -85, -74, -64, -53, -43, -32, -22, -11, 0, 11, 22, 33, 43, 54, 64, 75, -102, -98, -85, -71, -58, -45, -31, -14, 0, 13, 26, 39, 52, 65, 78, 90, -127,-112, -96, -80, -64, -48, -32, -16, 0, 16, 32, 48, 64, 80, 96, 112, - -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127 + -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127, + -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, + -10, -9, -8, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 6, 7, 8, + -13, -11, -9, -7, -6, -5, -3, -2, -1, 2, 3, 5, 6, 7, 9, 10, + -15, -13, -12, -10, -8, -6, -5, -3, -1, 2, 3, 5, 6, 8, 10, 12, + -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 3, 5, 7, 9, 11, 13, + -24, -20, -17, -15, -12, -10, -7, -5, -2, 2, 3, 6, 8, 11, 13, 16, + -29, -26, -23, -19, -16, -13, -10, -6, -2, 2, 5, 8, 11, 15, 18, 22, + -34, -30, -26, -22, -18, -14, -10, -6, -2, 2, 6, 10, 14, 18, 22, 26, + -43, -38, -33, -28, -23, -18, -13, -8, -3, 2, 7, 12, 17, 22, 27, 32, + -51, -45, -39, -33, -27, -21, -15, -9, -3, 3, 9, 15, 21, 27, 33, 39, + -60, -53, -46, -39, -32, -25, -18, -11, -4, 3, 10, 17, 24, 31, 38, 45, + -77, -68, -59, -50, -41, -32, -23, -14, -5, 4, 13, 22, 31, 40, 49, 58, + -90, -80, -69, -59, -48, -38, -27, -17, -6, 5, 16, 27, 38, 48, 59, 69, + -112,-104, -91, -78, -65, -52, -38, -23, -7, 6, 19, 32, 45, 58, 71, 84, + -128,-120,-104, -88, -72, -56, -40, -24, -8, 8, 24, 40, 56, 72, 88, 104, + -128,-128,-118,-100, -82, -64, -45, -27, -9, 9, 27, 45, 63, 82, 100, 118 +}; + +/* address = table_index(9:8) | dsp->espcm_last_value(7:3) | codeword(2:0) + * the value is a base index into espcm_range_map with bits at (8, 3:0), + * to be OR'ed with dsp->espcm_range at (7:4) + */ +uint16_t espcm3_dpcm_tables[1024] = +{ + /* Table 0 */ + 256, 257, 258, 259, 260, 263, 266, 269, 0, 257, 258, 259, 260, 263, 266, 269, + 0, 1, 258, 259, 260, 263, 266, 269, 1, 2, 259, 260, 261, 263, 266, 269, + 1, 3, 260, 261, 262, 264, 266, 269, 1, 3, 4, 261, 262, 264, 266, 269, + 2, 4, 5, 262, 263, 264, 266, 269, 2, 4, 6, 263, 264, 265, 267, 269, + 2, 4, 6, 7, 264, 265, 267, 269, 2, 5, 7, 8, 265, 266, 267, 269, + 2, 5, 7, 8, 9, 266, 268, 270, 2, 5, 7, 9, 10, 267, 268, 270, + 2, 5, 8, 10, 11, 268, 269, 270, 2, 5, 8, 11, 12, 269, 270, 271, + 2, 5, 8, 11, 12, 13, 270, 271, 2, 5, 8, 11, 12, 13, 14, 271, + 0, 257, 258, 259, 260, 263, 266, 269, 0, 1, 258, 259, 260, 263, 266, 269, + 0, 1, 2, 259, 260, 263, 266, 269, 1, 2, 3, 260, 261, 263, 266, 269, + 1, 3, 4, 261, 262, 264, 266, 269, 1, 3, 5, 262, 263, 264, 266, 269, + 2, 4, 5, 6, 263, 264, 266, 269, 2, 4, 6, 7, 264, 265, 267, 269, + 2, 4, 6, 7, 8, 265, 267, 269, 2, 5, 7, 8, 9, 266, 267, 269, + 2, 5, 7, 9, 10, 267, 268, 270, 2, 5, 7, 9, 10, 11, 268, 270, + 2, 5, 8, 10, 11, 12, 269, 270, 2, 5, 8, 11, 12, 13, 270, 271, + 2, 5, 8, 11, 12, 13, 14, 271, 2, 5, 8, 11, 12, 13, 14, 15, + /* Table 1 */ + 257, 260, 262, 263, 264, 265, 267, 270, 257, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 4, 262, 263, 264, 265, 267, 270, + 1, 4, 262, 263, 264, 265, 267, 270, 1, 4, 6, 263, 264, 265, 267, 270, + 1, 4, 6, 7, 264, 265, 267, 270, 1, 4, 6, 7, 8, 265, 267, 270, + 1, 4, 6, 7, 8, 9, 267, 270, 1, 4, 6, 7, 8, 9, 267, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 14, + 257, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 4, 262, 263, 264, 265, 267, 270, 1, 4, 262, 263, 264, 265, 267, 270, + 1, 4, 6, 263, 264, 265, 267, 270, 1, 4, 6, 7, 264, 265, 267, 270, + 1, 4, 6, 7, 8, 265, 267, 270, 1, 4, 6, 7, 8, 9, 267, 270, + 1, 4, 6, 7, 8, 9, 267, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 14, 1, 4, 6, 7, 8, 9, 11, 14, + /* Table 2 */ + 256, 257, 258, 259, 260, 262, 265, 268, 0, 257, 258, 259, 260, 262, 265, 268, + 0, 1, 258, 259, 260, 262, 265, 269, 1, 2, 259, 260, 261, 263, 265, 269, + 1, 3, 260, 261, 262, 263, 265, 269, 1, 3, 4, 261, 262, 263, 265, 269, + 1, 3, 5, 262, 263, 264, 266, 269, 1, 4, 5, 6, 263, 264, 266, 269, + 1, 4, 6, 7, 264, 265, 266, 269, 1, 4, 6, 7, 8, 265, 266, 269, + 2, 4, 6, 7, 8, 9, 267, 269, 2, 4, 6, 7, 8, 9, 267, 269, + 2, 5, 7, 8, 9, 10, 11, 270, 2, 5, 7, 8, 9, 10, 11, 270, + 2, 5, 8, 9, 10, 11, 12, 270, 2, 6, 8, 10, 11, 12, 13, 14, + 257, 258, 259, 260, 261, 263, 265, 269, 1, 259, 260, 261, 262, 263, 266, 269, + 1, 260, 261, 262, 263, 264, 266, 269, 1, 260, 261, 262, 263, 264, 266, 269, + 2, 4, 262, 263, 264, 265, 267, 269, 2, 4, 262, 263, 264, 265, 267, 269, + 2, 5, 6, 263, 264, 265, 267, 270, 2, 5, 6, 7, 264, 265, 267, 270, + 2, 5, 7, 8, 265, 266, 267, 270, 2, 5, 7, 8, 9, 266, 268, 270, + 2, 6, 8, 9, 10, 267, 268, 270, 2, 6, 8, 9, 10, 11, 268, 270, + 2, 6, 8, 10, 11, 12, 269, 270, 2, 6, 9, 11, 12, 13, 270, 271, + 3, 6, 9, 11, 12, 13, 14, 271, 3, 6, 9, 11, 12, 13, 14, 15, + /* Table 3 */ + 256, 258, 260, 261, 262, 263, 264, 265, 0, 258, 260, 261, 262, 263, 264, 265, + 1, 259, 260, 261, 262, 263, 264, 266, 1, 259, 260, 261, 262, 263, 264, 266, + 1, 3, 260, 261, 262, 263, 264, 266, 1, 3, 4, 261, 262, 263, 264, 267, + 1, 3, 4, 5, 262, 263, 264, 267, 1, 3, 4, 5, 6, 263, 264, 267, + 1, 3, 5, 6, 7, 264, 265, 268, 1, 3, 5, 6, 7, 8, 265, 268, + 1, 4, 6, 7, 8, 9, 266, 269, 1, 4, 6, 7, 8, 9, 10, 269, + 1, 4, 6, 7, 8, 9, 10, 269, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 14, + 257, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 2, 261, 262, 263, 264, 265, 267, 270, + 2, 261, 262, 263, 264, 265, 267, 270, 2, 5, 262, 263, 264, 265, 267, 270, + 3, 6, 263, 264, 265, 266, 268, 270, 3, 6, 7, 264, 265, 266, 268, 270, + 4, 7, 8, 265, 266, 267, 268, 270, 4, 7, 8, 9, 266, 267, 268, 270, + 4, 7, 8, 9, 10, 267, 268, 270, 5, 7, 8, 9, 10, 11, 268, 270, + 5, 7, 8, 9, 10, 11, 12, 270, 5, 7, 8, 9, 10, 11, 12, 270, + 6, 7, 8, 9, 10, 11, 13, 271, 6, 7, 8, 9, 10, 11, 13, 15 }; double low_fir_sb16_coef[4][SB16_NCoef]; From 9d54a78918cdae2d40b085be82bffd492105254a Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 11:39:56 -0300 Subject: [PATCH 329/690] Implement ESPCM_3 decoding --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 91 +++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 7b516a987..a9bd93ddc 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -153,6 +153,7 @@ typedef struct sb_dsp_t { uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 530d16015..018e2d380 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2301,7 +2301,96 @@ pollsb(void *priv) break; case ESPCM_3: - // TODO + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_sample_idx++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; + dsp->espcm_last_value = tempi; + } + else if (dsp->espcm_sample_idx == 1) + { + for (tempi = 0; tempi < 4; tempi++) + { + dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[0] >> 2) & 0x07; + dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[0] >> 5) & 0x07; + dsp->espcm_code_buffer[2] = (dsp->espcm_byte_buffer[1]) & 0x07; + dsp->espcm_code_buffer[3] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; + dsp->espcm_code_buffer[4] = ((dsp->espcm_byte_buffer[1] >> 6) & 0x03) | ((dsp->espcm_byte_buffer[2] & 0x01) << 2); + dsp->espcm_code_buffer[5] = (dsp->espcm_byte_buffer[2] >> 1) & 0x07; + dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[2] >> 4) & 0x07; + dsp->espcm_code_buffer[7] = ((dsp->espcm_byte_buffer[2] >> 7) & 0x01) | ((dsp->espcm_byte_buffer[3] & 0x03) << 1); + dsp->espcm_code_buffer[8] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; + dsp->espcm_code_buffer[9] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; + + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + else if (dsp->espcm_sample_idx == 11) + { + for (tempi = 1; tempi < 4; tempi++) + { + dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; + dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; + dsp->espcm_code_buffer[2] = ((dsp->espcm_byte_buffer[1] >> 6) & 0x03) | ((dsp->espcm_byte_buffer[2] & 0x01) << 2); + dsp->espcm_code_buffer[3] = (dsp->espcm_byte_buffer[2] >> 1) & 0x07; + dsp->espcm_code_buffer[4] = (dsp->espcm_byte_buffer[2] >> 4) & 0x07; + dsp->espcm_code_buffer[5] = ((dsp->espcm_byte_buffer[2] >> 7) & 0x01) | ((dsp->espcm_byte_buffer[3] & 0x03) << 1); + dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; + dsp->espcm_code_buffer[7] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; + + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + else + { + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ESPCM_1: From 416edcf1a5b93d70209ba7e6ee1a0fcdd58b5320 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 11:41:50 -0300 Subject: [PATCH 330/690] Fix: clear espcm_sample_idx upon starting ESPCM DMA --- src/sound/snd_sb_dsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 018e2d380..7972864a1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1348,6 +1348,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1366,6 +1367,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1384,6 +1386,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1402,6 +1405,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; From 6fc43a80828c44aba861832dc3fbe22a390ec243 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 19:28:12 -0300 Subject: [PATCH 331/690] Implement ESPCM_4 recording --- src/include/86box/snd_sb_dsp.h | 7 +-- src/sound/snd_sb_dsp.c | 87 +++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index a9bd93ddc..7a1873b9c 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -152,9 +152,10 @@ typedef struct sb_dsp_t { uint8_t espcm_sample_idx; uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; - uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ - uint8_t espcm_table_index; /* used for ESPCM_3 */ - uint8_t espcm_last_value; /* used for ESPCM_3 */ + uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ + int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7972864a1..0c1b789d1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -124,7 +124,7 @@ uint8_t adjustMap2[24] = { * This current table is part software reverse engineering, part guesswork/extrapolation. * It's close enough to what's in the chip to produce acceptable results, but not exact. **/ -uint8_t espcm_range_map[512] = { +int8_t espcm_range_map[512] = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, @@ -2331,6 +2331,7 @@ pollsb(void *priv) } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[0] >> 2) & 0x07; dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[0] >> 5) & 0x07; dsp->espcm_code_buffer[2] = (dsp->espcm_byte_buffer[1]) & 0x07; @@ -2613,6 +2614,90 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; + case ESPCM_4: + // I assume the real hardware double-buffers the blocks or something like that. + // We're not gonna do that here. + dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; + dsp->espcm_sample_idx++; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + if (dsp->espcm_sample_idx >= 19) + { + int i, bit, table_addr, sigma, last_sigma; + int8_t min_sample = 127, max_sample = -128, s; + uint8_t b; + + for (i = 0; i < 19; i++) + { + s = dsp->espcm_sample_buffer[i]; + if (s < min_sample) + { + min_sample = s; + } + if (s > max_sample) + { + max_sample = s; + } + } + if (min_sample < 0) + { + min_sample = -min_sample; + } + if (max_sample < 0) + { + max_sample = -max_sample; + } + if (min_sample > max_sample) + { + max_sample = min_sample; + } + + for (table_addr = 15; table_addr < 256; table_addr += 16) + { + if (max_sample <= espcm_range_map[table_addr]) + { + break; + } + } + dsp->espcm_range = table_addr >> 4; + + for (i = 0; i < 19; i++) + { + table_addr = dsp->espcm_range << 4; + last_sigma = 9999; + s = dsp->espcm_sample_buffer[i]; + for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) + { + sigma = espcm_range_map[table_addr] - s; + if (sigma < 0) + { + sigma = -sigma; + } + if (sigma > last_sigma) + { + break; + } + last_sigma = sigma; + } + table_addr--; + dsp->espcm_code_buffer[i] = table_addr & 0x0F; + } + + b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); + dsp->dma_writeb(dsp->dma_priv, b); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + for (i = 1; i < 10; i++) + { + b = dsp->espcm_code_buffer[i * 2 - 1] | (dsp->espcm_code_buffer[i * 2] << 4); + dsp->dma_writeb(dsp->dma_priv, b); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_sample_idx = 0; + } default: break; From 011b06441dac21fa9a598f4af13ec716ea559878 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 22:00:46 -0300 Subject: [PATCH 332/690] Removing extraneous DSP update from ess_get_music_buffer_sbpro --- src/sound/snd_ess.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0f57bca7d..55c6f9d60 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -473,8 +473,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) opl_buf = ess->opl.update(ess->opl.priv); - sb_dsp_update(&ess->dsp); - for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; From 40607b291dcfc909081d7128dd7374dc630bf953 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 19 Mar 2024 13:01:54 -0300 Subject: [PATCH 333/690] Fixing ESPCM 1/2 --- src/include/86box/fifo.h | 5 + src/include/86box/snd_sb_dsp.h | 29 ++-- src/sound/snd_sb_dsp.c | 274 +++++++++++++++++++++------------ 3 files changed, 201 insertions(+), 107 deletions(-) diff --git a/src/include/86box/fifo.h b/src/include/86box/fifo.h index e76189d8a..f87f932e0 100644 --- a/src/include/86box/fifo.h +++ b/src/include/86box/fifo.h @@ -1,3 +1,6 @@ +#ifndef FIFO_H +#define FIFO_H + /* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM @@ -71,3 +74,5 @@ 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); + +#endif /*FIFO_H*/ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 7a1873b9c..f5905ccc2 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -1,6 +1,8 @@ #ifndef SOUND_SND_SB_DSP_H #define SOUND_SND_SB_DSP_H +#include <86box/fifo.h> + /*Sound Blaster Clones, for quirks*/ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ @@ -142,20 +144,25 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ - uint8_t ess_regs[256]; /* ESS registers. */ - uint8_t ess_playback_mode; - uint8_t ess_extended_mode; - uint8_t ess_reload_len; + uint8_t ess_regs[256]; /* ESS registers. */ + uint8_t ess_playback_mode; + uint8_t ess_extended_mode; + uint8_t ess_reload_len; uint32_t ess_dma_counter; + int ess_irq_generic; + int ess_irq_dmactr; // ESPCM - uint8_t espcm_sample_idx; - uint8_t espcm_range; - uint8_t espcm_byte_buffer[4]; - uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ - int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ - uint8_t espcm_table_index; /* used for ESPCM_3 */ - uint8_t espcm_last_value; /* used for ESPCM_3 */ + fifo64_t *espcm_fifo; + int espcm_fifo_reset; + int espcm_mode; + uint8_t espcm_sample_idx; + uint8_t espcm_range; + uint8_t espcm_byte_buffer[4]; + uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ + int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 0c1b789d1..34ddb1a50 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -34,7 +34,8 @@ #define ADPCM_2 3 #define ESPCM_4 4 #define ESPCM_3 5 -#define ESPCM_1 6 // not ESPCM_2, unlike what the manuals say +#define ESPCM_1 7 +#define ESPCM_4E 8 // for encoding mode switching /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -386,12 +387,16 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) break; } - /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ - if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { - if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire - { - pclog("ess: IRQ was masked\n"); - return; + /* NOTE: not on ES1688, apparently; investigate on ES1868 */ + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) + { + /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ + if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { + if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked\n"); + return; + } } } @@ -945,6 +950,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_irqnum = 10; break; } + pclog("ess: IRQ set to %d\n", dsp->sb_irqnum); sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ @@ -965,6 +971,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_8_dmanum = 3; break; } + pclog("ess: DMA set to %d\n", dsp->sb_8_dmanum); sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; @@ -1041,6 +1048,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xBA: /* Left Channel ADC Offset Adjust */ case 0xBB: /* Right Channel ADC Offset Adjust */ case 0xC3: /* Internal state register */ + case 0xCF: /* GPO0/1 power management register */ ESSreg(reg) = data; break; @@ -1066,13 +1074,15 @@ sb_exec_command(sb_dsp_t *dsp) } { - int i; - char data_s[256]; + int i, l, s = 0; + char data_s[256], *dsptr = data_s; data_s[0] = '\0'; for (i = 0; i < sb_commands[dsp->sb_command]; i++) { - snprintf(data_s, 256, " 0x%02X", dsp->sb_data[i]); + l = snprintf(dsptr, 256 - s, " 0x%02X", dsp->sb_data[i]); + s += l; + dsptr += l; } pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); } @@ -1090,6 +1100,14 @@ sb_exec_command(sb_dsp_t *dsp) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); } + else if (dsp->sb_command == 0xCE) + { + sb_add_data(dsp, sb_ess_read_reg(dsp, 0xCF)); + } + else if (dsp->sb_command == 0xCF) + { + sb_ess_write_reg(dsp, 0xCF, dsp->sb_data[0]); + } else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); } @@ -1336,79 +1354,60 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; case 0x65: /* 4-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { + if (dsp->espcm_mode != ESPCM_4) + { + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_4; sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; case 0x67: /* 3-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { + pclog("ess: Starting espcm3 transfer\n"); + if (dsp->espcm_mode != ESPCM_3) + { + pclog("ess: ESPCM FIFO reset\n"); + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_3; sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; - case 0x6B: /* 1-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; - case 0x6A: /* 1-bit ESPCM output */ + case 0x6D: /* 1-bit ESPCM output with reference */ + case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { + pclog("ess: Starting espcm1 transfer\n"); + if (dsp->espcm_mode != ESPCM_1) + { + pclog("ess: ESPCM FIFO reset\n"); + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_1; sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; case 0x6F: /* 4-bit ESPCM input with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - fallthrough; case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + if (dsp->espcm_mode != ESPCM_4E) + { + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_4E; + sb_start_dma_i(dsp, 1, 0, ESPCM_4E, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->espcm_sample_idx = 0; - dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; } break; case 0x75: /* 4-bit ADPCM output with reference */ @@ -1655,12 +1654,15 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); pclog("F2 written\n"); } - } else + } else { sb_irq(dsp, 1); + dsp->ess_irq_generic = true; + } break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); sb_irq(dsp, 0); + dsp->ess_irq_generic = true; break; case 0xF8: if (dsp->sb_type < SB16) @@ -1722,6 +1724,12 @@ sb_write(uint16_t a, uint8_t v, void *priv) } dsp->sbreset = v; } + + if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) + { + fifo_reset(dsp->espcm_fifo); + } + dsp->espcm_fifo_reset = v; dsp->uart_midi = 0; dsp->uart_irq = 0; dsp->onebyte_midi = 0; @@ -1752,10 +1760,23 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } - if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { + if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) + { + if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) + { + sb_commands[dsp->sb_command] = 2; + } + else + { + sb_commands[dsp->sb_command] = 2; + } + } + else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 + || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; - } else if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { + } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 + || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1787,6 +1808,10 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if ((a & 0xF) == 0x9 || (a & 0xF) == 0xB) + { + pclog("ess: Read-Sequence-Key? port 0x%X", a); + } if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ @@ -1814,6 +1839,23 @@ sb_read(uint16_t a, void *priv) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; + if (IS_ESS(dsp)) + { + if (dsp->wb_full || (dsp->busy_count & 2)) { + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); + } + uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + uint8_t fifo_full = 0; // Unimplemented + uint8_t fifo_empty = 0; + uint8_t fifo_half = 0; + uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; + uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + + return busy_flag | data_rdy | fifo_full | fifo_empty + | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + } if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); if (IS_AZTECH(dsp)) { @@ -1839,6 +1881,7 @@ sb_read(uint16_t a, void *priv) pclog("sb: IRQ acknowledged\n"); } dsp->sb_irq8 = dsp->sb_irq16 = 0; + dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ if (IS_AZTECH(dsp)) { sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); @@ -1891,6 +1934,7 @@ sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len) for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } else if (dsp->midi_in_poll) { for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); @@ -1932,6 +1976,7 @@ sb_dsp_irq_poll(void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } void @@ -1998,6 +2043,8 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); + dsp->espcm_fifo = fifo64_init(); + fifo_set_trigger_len(dsp->espcm_fifo, 1); } void @@ -2059,6 +2106,25 @@ sb_ess_finish_dma(sb_dsp_t *dsp) pclog("ess: DMA finished"); } +void +sb_espcm_fifoctl_run(sb_dsp_t *dsp) +{ + if (fifo_get_empty(dsp->espcm_fifo)) + { + while (!fifo_get_full(dsp->espcm_fifo)) + { + int32_t val; + val = dsp->dma_readb(dsp->dma_priv); + dsp->ess_dma_counter++; + fifo_write(val & 0xff, dsp->espcm_fifo); + if (val & DMA_OVER) + { + break; + } + } + } +} + void pollsb(void *priv) { @@ -2262,29 +2328,32 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; tempi = dsp->espcm_byte_buffer[0] >> 4; } else if (dsp->espcm_sample_idx & 1) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; tempi = dsp->espcm_byte_buffer[0] & 0x0F; } else { - dsp->espcm_sample_idx++; tempi = dsp->espcm_byte_buffer[0] >> 4; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2311,11 +2380,8 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; tempi = dsp->espcm_byte_buffer[0] >> 4; @@ -2325,9 +2391,9 @@ pollsb(void *priv) { for (tempi = 0; tempi < 4; tempi++) { - dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; @@ -2346,15 +2412,14 @@ pollsb(void *priv) tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } else if (dsp->espcm_sample_idx == 11) { for (tempi = 1; tempi < 4; tempi++) { - dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; } dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; @@ -2369,16 +2434,21 @@ pollsb(void *priv) tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } else { tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2405,33 +2475,36 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; dsp->espcm_byte_buffer[0] >>= 5; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } else { - dsp->espcm_sample_idx++; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2465,6 +2538,7 @@ pollsb(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2479,6 +2553,7 @@ pollsb(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); + dsp->ess_irq_dmactr = true; pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); } } @@ -2542,6 +2617,7 @@ pollsb(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2556,6 +2632,7 @@ pollsb(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; @@ -2567,6 +2644,7 @@ pollsb(void *priv) dsp->sb_pausetime--; if (dsp->sb_pausetime < 0) { sb_irq(dsp, 1); + dsp->ess_irq_generic = true; if (!dsp->sb_8_enable) timer_disable(&dsp->output_timer); sb_dsp_log("SB pause over\n"); @@ -2614,7 +2692,7 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; - case ESPCM_4: + case ESPCM_4E: // I assume the real hardware double-buffers the blocks or something like that. // We're not gonna do that here. dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; @@ -2712,6 +2790,7 @@ sb_poll_i(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2726,6 +2805,7 @@ sb_poll_i(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; @@ -2784,6 +2864,7 @@ sb_poll_i(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2798,6 +2879,7 @@ sb_poll_i(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; From 56859a9173f4007c2316c87727c2d34ca93065ac Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 19 Mar 2024 18:48:51 -0300 Subject: [PATCH 334/690] Fixing ESPCM 2/2 --- src/sound/snd_sb_dsp.c | 399 ++++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 169 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 34ddb1a50..f94724e68 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1357,8 +1357,10 @@ sb_exec_command(sb_dsp_t *dsp) case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4) + if (dsp->espcm_mode != ESPCM_4 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { + pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1370,8 +1372,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { - pclog("ess: Starting espcm3 transfer\n"); - if (dsp->espcm_mode != ESPCM_3) + if (dsp->espcm_mode != ESPCM_3 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); @@ -1385,8 +1387,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { - pclog("ess: Starting espcm1 transfer\n"); - if (dsp->espcm_mode != ESPCM_1) + if (dsp->espcm_mode != ESPCM_1 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); @@ -1400,8 +1402,10 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4E) + if (dsp->espcm_mode != ESPCM_4E + || (dsp->sb_8_enable && dsp->sb_8_pause)) { + pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -2109,7 +2113,7 @@ sb_ess_finish_dma(sb_dsp_t *dsp) void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { - if (fifo_get_empty(dsp->espcm_fifo)) + if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) { while (!fifo_get_full(dsp->espcm_fifo)) { @@ -2134,191 +2138,212 @@ pollsb(void *priv) int data[2]; timer_advance_u64(&dsp->output_timer, dsp->sblatcho); - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { + if (dsp->sb_8_enable && dsp->sb_pausetime < 0 && dsp->sb_8_output) { sb_dsp_update(dsp); switch (dsp->sb_8_format) { case 0x00: /* Mono unsigned */ - data[0] = dsp->dma_readb(dsp->dma_priv); - /* Needed to prevent clicking in Worms, which programs the DSP to - auto-init DMA but programs the DMA controller to single cycle */ - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = (data[0] ^ 0x80) << 8; - if (dsp->stereo) { - sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + /* Needed to prevent clicking in Worms, which programs the DSP to + auto-init DMA but programs the DMA controller to single cycle */ + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = (data[0] ^ 0x80) << 8; + if (dsp->stereo) { + sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x10: /* Mono signed */ - data[0] = dsp->dma_readb(dsp->dma_priv); - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = data[0] << 8; - if (dsp->stereo) { - sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) { + sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x20: /* Stereo unsigned */ - data[0] = dsp->dma_readb(dsp->dma_priv); - data[1] = dsp->dma_readb(dsp->dma_priv); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; - dsp->sb_8_length -= 2; - dsp->ess_dma_counter += 2; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + data[1] = dsp->dma_readb(dsp->dma_priv); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = (data[0] ^ 0x80) << 8; + dsp->sbdatr = (data[1] ^ 0x80) << 8; + dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; + } break; case 0x30: /* Stereo signed */ - data[0] = dsp->dma_readb(dsp->dma_priv); - data[1] = dsp->dma_readb(dsp->dma_priv); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; - dsp->sb_8_length -= 2; - dsp->ess_dma_counter += 2; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + data[1] = dsp->dma_readb(dsp->dma_priv); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = data[0] << 8; + dsp->sbdatr = data[1] << 8; + dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; + } break; case ADPCM_4: - if (dsp->sbdacpos) - tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; - else - tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 63) - tempi = 63; - - ref = dsp->sbref + scaleMap4[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - - if (dsp->sbdacpos >= 2) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + if (!dsp->sb_8_pause) + { + if (dsp->sbdacpos) + tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 63) + tempi = 63; + + ref = dsp->sbref + scaleMap4[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + + dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + + if (dsp->sbdacpos >= 2) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ADPCM_26: - if (!dsp->sbdacpos) - tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; - else if (dsp->sbdacpos == 1) - tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; - else - tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; - - if (tempi < 0) - tempi = 0; - if (tempi > 39) - tempi = 39; - - ref = dsp->sbref + scaleMap26[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 3) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + if (!dsp->sb_8_pause) + { + if (!dsp->sbdacpos) + tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; + else if (dsp->sbdacpos == 1) + tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; + + if (tempi < 0) + tempi = 0; + if (tempi > 39) + tempi = 39; + + ref = dsp->sbref + scaleMap26[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; + + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + if (dsp->sbdacpos >= 3) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ADPCM_2: - tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 23) - tempi = 23; + if (!dsp->sb_8_pause) + { + tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 23) + tempi = 23; - ref = dsp->sbref + scaleMap2[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 4) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + ref = dsp->sbref + scaleMap2[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; + + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + if (dsp->sbdacpos >= 4) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ESPCM_4: @@ -2329,6 +2354,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2337,6 +2366,10 @@ pollsb(void *priv) else if (dsp->espcm_sample_idx & 1) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; @@ -2381,6 +2414,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2392,9 +2429,17 @@ pollsb(void *priv) for (tempi = 0; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } + if (tempi < 4) + { + break; + } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; @@ -2418,9 +2463,17 @@ pollsb(void *priv) for (tempi = 1; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } + if (tempi < 4) + { + break; + } dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; @@ -2476,6 +2529,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2486,6 +2543,10 @@ pollsb(void *priv) else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; From a776a54b55b6ad5fc25a1ff89c40f6e8c811f0a1 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:11:08 -0400 Subject: [PATCH 335/690] network: Modify the PCAP filter to allow multicast packets --- src/network/net_pcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 16caaec7e..852191c55 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -500,7 +500,7 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char * pcap_log("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", + "( ((ether broadcast) or (ether multicast) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); if (f_pcap_compile(pcap->pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { From 778cd2bc4686b40d75af3e46cb7f6f2c8e2b7ce2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Mar 2024 22:00:48 +0100 Subject: [PATCH 336/690] Refactor PAS16 code (Audio/MIDI/PIT) This should make it work once and for all after many years of being broken/not working. --- src/include/86box/pit.h | 3 +- src/pit.c | 40 ++-- src/sound/snd_pas16.c | 478 ++++++++++++++++++++-------------------- 3 files changed, 261 insertions(+), 260 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 078694633..d9bce667d 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -56,6 +56,8 @@ typedef struct ctr_t { }; uint32_t l; + uint32_t lback; + uint32_t lback2; void (*load_func)(uint8_t new_m, int new_count); void (*out_func)(int new_out, int old_out, void *priv); @@ -70,7 +72,6 @@ typedef struct PIT { uint8_t ctrl; void *dev_priv; - void (*dev_timer)(void *priv); } pit_t; extern pit_t *ext_pit; diff --git a/src/pit.c b/src/pit.c index 4f64d40c1..20baf3f66 100644 --- a/src/pit.c +++ b/src/pit.c @@ -103,6 +103,7 @@ ctr_set_out(ctr_t *ctr, int out, void *priv) if (ctr->out_func != NULL) ctr->out_func(out, ctr->out, pit); + ctr->out = out; } @@ -354,7 +355,7 @@ ctr_load(ctr_t *ctr) if (ctr->load_func != NULL) ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); - pclog("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); + pit_log("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } static __inline void @@ -393,7 +394,7 @@ ctr_latch_count(ctr_t *ctr) break; } - pclog("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); + pit_log("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); } uint16_t @@ -522,9 +523,6 @@ pit_timer_over(void *priv) for (uint8_t i = 0; i < 3; i++) pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); - if (dev->dev_timer != NULL) - dev->dev_timer(dev); - timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); } @@ -536,7 +534,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_t *ctr; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); switch (addr & 3) { case 3: /* control */ @@ -553,7 +551,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (val & 8) ctr_latch_count(&dev->counters[2]); if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Initiated readback command\n", t); + pit_log("PIT %i: Initiated readback command\n", t); } if (!(val & 0x10)) { if (val & 2) @@ -571,7 +569,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Initiated latched read, %i bytes latched\n", + pit_log("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); } else { ctr->ctrl = val; @@ -585,12 +583,12 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->state = 0; if (ctr->latched) { if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Reload while counter is latched\n", t); + pit_log("PIT %i: Reload while counter is latched\n", t); ctr->rl--; } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); } } break; @@ -606,12 +604,20 @@ pit_write(uint16_t addr, uint8_t val, void *priv) break; case 1: ctr->l = val; + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pit_log("PIT %i (1): Written byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 2: ctr->l = (val << 8); + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pit_log("PIT %i (2): Written byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -620,13 +626,17 @@ pit_write(uint16_t addr, uint8_t val, void *priv) case 0x83: if (ctr->wm & 0x80) { ctr->l = (ctr->l & 0x00ff) | (val << 8); + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); + pit_log("PIT %i (0x83): Written high byte %02X, latch now %04X\n", t, val, ctr->l); ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); + pit_log("PIT %i (3): Written low byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) { ctr->state = 0; ctr_set_out(ctr, 0, dev); @@ -763,7 +773,7 @@ pit_read(uint16_t addr, void *priv) } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); return ret; } @@ -890,15 +900,13 @@ pit_init(const device_t *info) } dev->flags = info->local; + dev->dev_priv = NULL; if (!(dev->flags & PIT_EXT_IO)) { io_sethandler((dev->flags & PIT_SECONDARY) ? 0x0048 : 0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, dev); } - dev->dev_priv = NULL; - dev->dev_timer = NULL; - return dev; } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 32879cd1e..d8187cf0f 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -137,25 +137,29 @@ typedef struct pas16_t { uint8_t midi_ctrl; uint8_t midi_stat; uint8_t midi_data; - uint8_t midi_fifo[16]; + uint8_t fifo_stat; + int midi_r; + int midi_w; + int midi_uart_out; + int midi_uart_in; + uint8_t midi_queue[256]; + int sysex; fm_drv_t opl; sb_dsp_t dsp; mpu_t *mpu; + pc_timer_t timer; int16_t pcm_buffer[2][SOUNDBUFLEN]; int pos; - int midi_uart_out; - pit_t *pit; } pas16_t; static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; -static int pas16_irqs[16] = { 0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0 }; static int pas16_sb_irqs[8] = { 0, 2, 3, 5, 7, 10, 11, 12 }; static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; @@ -167,7 +171,8 @@ enum { enum { PAS16_PCM_MONO = 0x20, - PAS16_PCM_ENA = 0x40 + PAS16_PCM_ENA = 0x40, + PAS16_PCM_DMA_ENA = 0x80 }; enum { @@ -197,124 +202,51 @@ pas16_log(const char *fmt, ...) # define pas16_log(fmt, ...) #endif +static uint8_t +pas16_in(uint16_t port, void *priv); static void -pas16_update_midi_irqs(pas16_t *pas16) +pas16_out(uint16_t port, uint8_t val, void *priv); + +static void +pas16_update_irq(pas16_t *pas16) { - int irq = 0; - - pas16->irq_stat &= ~PAS16_INT_MIDI; - - if ((pas16->uart_status & 0x18) || (dev->uart_status & 0x04)) { + if (pas16->midi_uart_out && (pas16->midi_stat & 0x18)) { pas16->irq_stat |= PAS16_INT_MIDI; - irq = 1; + if (pas16->irq_ena & PAS16_INT_MIDI) + picint(1 << pas16->irq); } - - if (irq) - picint(1 << pas16->irq); - else - picintc(1 << pas16->irq); -} - -static void -pas16_update_tx_irq(pas16_t *pas16) -{ - pas16->uart_status &= ~0x18; - - if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x18)) - pas16->uart_status |= 0x18; - - pas16_update_midi_irqs(pas16); -} - -static void -pas16_update_rx_irq(pas16_t *pas16) -{ - pas16->uart_status &= ~0x04; - - if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x04)) - pas16->uart_status |= 0x04; - - pas16_update_midi_irqs(pas16); -} - -static void -pas16_scan_fifo(pas16_t *pas16) -{ - if (pas16->read_fifo_pos != pas16->write_fifo_pos) { - pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; - pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 0x0f; - - es1371_set_rx_irq(pas16, 1); - } else - es1371_set_rx_irq(pas16, 0); -} - -static void -es1371_write_fifo(es1371_t *dev, uint8_t val) -{ - if (dev->write_fifo_pos < 16) { - dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; - dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 0x0f; + if (pas16->midi_uart_in && (pas16->midi_stat & 0x04)) { + pas16->irq_stat |= PAS16_INT_MIDI; + if (pas16->irq_ena & PAS16_INT_MIDI) + picint(1 << pas16->irq); } } -static void -es1371_reset_fifo(es1371_t *dev) -{ - for (uint8_t i = 0; i < 16; i++) - dev->uart_fifo[i] = 0x00000000; - - dev->read_fifo_pos = dev->write_fifo_pos = 0; - - es1371_set_rx_irq(dev, 0); -} - -static void -pas16_reset(void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - - pas16->uart_status = 0xff; - pas16->uart_ctrl = 0x00; - - for (uint8_t i = 0; i < 16; i++) - pas16->uart_fifo[i] = 0x00; - - pas16_set_tx_irq(pas16, 0); - - pas16_reset_fifo(pas16); - - pas16_update_midi_irqs(pas16); -} - static uint8_t pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t temp = 0xff; - switch ((port - pas16->base) + 0x388) { + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - temp = pas16->opl.read((port - pas16->base) + 0x388, pas16->opl.priv); + temp = pas16->opl.read(port, pas16->opl.priv); break; case 0xb88: temp = pas16->audio_mixer; break; - case 0xb89: temp = pas16->irq_stat; break; - case 0xb8a: temp = pas16->audiofilt; break; - case 0xb8b: - temp = pas16->irq_ena & ~0xe0; - temp |= 0x01; + temp = pas16->irq_ena | 0x20; + pas16_log("IRQ Mask read=%02x.\n", temp); break; case 0xf8a: @@ -322,19 +254,36 @@ pas16_in(uint16_t port, void *priv) break; case 0x1789: - temp = 0; + case 0x178b: + temp = pas16->midi_ctrl; break; case 0x178a: - temp = pas16->uart_data; - pas16_set_rx_irq(pas16, 0); + case 0x1b8a: + temp = 0; + if (pas16->midi_uart_in) { + if ((pas16->midi_data == 0xaa) && (pas16->midi_ctrl & 0x04)) + temp = pas16->midi_data; + else { + temp = pas16->midi_queue[pas16->midi_r]; + if (pas16->midi_r != pas16->midi_w) { + pas16->midi_r++; + pas16->midi_r &= 0xff; + } + } + pas16->midi_stat &= ~0x04; + pas16_update_irq(pas16); + } break; case 0x1b88: - temp = pas16->uart_status; + temp = pas16->midi_stat; + break; + case 0x1b89: + temp = pas16->fifo_stat; break; case 0x2789: /*Board revision*/ - temp = 0; + temp = 0x00; break; case 0x7f89: @@ -347,19 +296,18 @@ pas16_in(uint16_t port, void *priv) case 0x8389: temp = pas16->sys_conf_2; break; - case 0x838b: + case 0x838a: temp = pas16->sys_conf_3; break; - case 0x838c: + case 0x838b: temp = pas16->sys_conf_4; break; case 0xbf88: temp = pas16->waitstates; break; - case 0xef8b: - temp = 0x0c; + temp = 0x00; break; case 0xf388: @@ -367,9 +315,11 @@ pas16_in(uint16_t port, void *priv) break; case 0xf389: temp = pas16->io_conf_2; + pas16_log("pas16_in : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: temp = pas16->io_conf_3; + pas16_log("pas16_in : set PAS IRQ %i\n", pas16->irq); break; case 0xf38b: temp = pas16->io_conf_4; @@ -396,7 +346,7 @@ pas16_in(uint16_t port, void *priv) default: break; } - pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); + pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); return temp; } @@ -405,30 +355,27 @@ pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; pit_t *pit = (pit_t *) pas16->pit; - pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); - switch ((port - pas16->base) + 0x388) { + pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - pas16->opl.write((port - pas16->base) + 0x388, val, pas16->opl.priv); + pas16->opl.write(port, val, pas16->opl.priv); break; case 0xb88: pas16->audio_mixer = val; break; - case 0xb89: pas16->irq_stat &= ~val; break; - case 0xb8a: pas16_update(pas16); pas16->audiofilt = val; break; - case 0xb8b: - pas16->irq_ena = val; + pas16->irq_ena = val & 0x1f; break; case 0xf88: @@ -448,29 +395,33 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1789: case 0x178b: - pas16->uart_ctrl = val; - + pas16->midi_ctrl = val; if ((val & 0x60) == 0x60) { - /* Reset TX */ - pas16_set_tx_irq(pas16, 1); + pas16->midi_uart_out = 0; + pas16->midi_uart_in = 0; + } else if (val & 0x18) { + pas16->midi_uart_out = 1; + } else if (val & 0x04) + pas16->midi_uart_in = 1; + else + pas16->midi_uart_out = 1; - /* Software reset */ - pas16_reset_fifo(pas16); - } else { - pas16_set_tx_irq(pas16, 1); - - pas16_update_tx_irq(pas16); - pas16_update_rx_irq(pas16); - } + pas16_update_irq(pas16); break; - case 0x178a: - midi_raw_out_byte(val); - pas16_set_tx_irq(pas16, 1); + case 0x1b8a: + pas16->midi_data = val; + pas16_log("UART OUT=%d.\n", pas16->midi_uart_out); + if (pas16->midi_uart_out) + midi_raw_out_byte(val); break; case 0x1b88: - pas16->uart_status = val; + pas16->midi_stat = val; + pas16_update_irq(pas16); + break; + case 0x1b89: + pas16->fifo_stat = val; break; case 0x7f89: @@ -478,9 +429,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8388: - if ((val & 0x80) && !(pas16->sys_conf_1 & 0x80)) { - pclog("Reset.\n"); - pas16_reset(pas16); + if ((val & 0xc0) && !(pas16->sys_conf_1 & 0xc0)) { + pas16_log("Reset.\n"); + picintc(1 << pas16->irq); + val = 0x00; } pas16->sys_conf_1 = val; break; @@ -504,12 +456,19 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0xf389: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; - pclog("pas16_out : set PAS DMA %i\n", pas16->dma); + pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); + pas16->irq = val & 0x0f; + if (pas16->irq <= 6) { + pas16->irq++; + } else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) + pas16->irq += 3; + else + pas16->irq += 4; + + pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; case 0xf38b: pas16->io_conf_4 = val; @@ -538,32 +497,12 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->sb_irqdma = val; sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); break; default: - pclog("pas16_out : unknown %04X\n", port); + pas16_log("pas16_out : unknown %04X\n", port); } -#if 0 - if (cpu_state.pc == 0x80048CF3) { - if (output) - fatal("here\n"); - output = 3; - } -#endif -} - - -static void -pas16_scan_fifo(pas16_t *pas16) -{ - if (pas16->read_fifo_pos != pas16->write_fifo_pos) { - pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; - pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 7; - - pas16_set_rx_irq(pas16, 1); - } else - pas16_set_rx_irq(pas16, 0); } static uint8_t @@ -572,39 +511,49 @@ pas16_readdma(pas16_t *pas16) return dma_channel_read(pas16->dma); } - static void pas16_pcm_poll(void *priv) { - pit_t *pit = (pit_t *)priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; + pas16_t *pas16 = (pas16_t *) priv; + pit_t *pit = (pit_t *) pas16->pit; + int data; uint16_t temp = 0x0000; - pas16_update(pas16); - if (pit->counters[0].m & 2) { - if (pit->counters[0].l) - timer_advance_u64(&pit->callback_timer, pit->counters[0].l * (PITCONST << 1ULL)); - else { - timer_advance_u64(&pit->callback_timer, 0x10000 * (PITCONST << 1ULL)); + if (pit->counters[0].m & 0x02) { + if (pit->counters[0].l & 0xff) { + if (pas16->dma >= 5) + timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); + else + timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + } else { + if (pas16->dma >= 5) + timer_advance_u64(&pas16->timer, 0x100 * (PITCONST << 1ULL)); + else + timer_advance_u64(&pas16->timer, 0x100 * PITCONST); } } + pas16_update_irq(pas16); + pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) + if (pas16->irq_ena & PAS16_INT_SAMP) { + pas16_log("INT SAMP.\n"); picint(1 << pas16->irq); - else - picintc(1 << pas16->irq); + } /*Update sample rate counter*/ - pas16_log("Enable (t1) = %d.\n", pit->counters[1].enable); + pas16_log("T1=%d, master bit 1=%x, counter0=%d, counter1=%d, pcm dma ena=%02x 16bit?=%02x.\n", pit->counters[1].enable, pit->counters[0].m & 0x02, pit->counters[0].l, pit->counters[1].l, pas16->pcm_ctrl & 0xc0, pas16->sys_conf_2 & PAS16_SC2_16BIT); if (pit->counters[1].enable) { - if (pas16->pcm_ctrl & PAS16_PCM_ENA) { + if ((pas16->pcm_ctrl & (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA))) { if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - temp = pas16_readdma(pas16) << 8; - temp |= pas16_readdma(pas16); - } else - temp = (pas16_readdma(pas16) ^ 0x80) << 8; + data = pas16_readdma(pas16) << 8; + data |= pas16_readdma(pas16); + temp = data; + } else { + data = pas16_readdma(pas16); + temp = (data ^ 0x80) << 8; + } if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) temp ^= 0x8000; @@ -619,41 +568,63 @@ pas16_pcm_poll(void *priv) pas16->stereo_lr = !pas16->stereo_lr; } } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pit->counters[1].rl -= 2; - else - pit->counters[1].rl--; - - pas16_log("RL=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); - if (pit->counters[1].rl == 0xffff) { - if (pit->counters[1].m & 2) { - if (pit->counters[1].l & 0xffff) - pit->counters[1].rl = pit->counters[1].l & 0xffff; - else - pit->counters[1].rl = 0; - } else { - pit->counters[1].enable = 0; - pit->counters[1].rl = 0; + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { + pit->counters[1].lback -= 2; + if (!pit->counters[1].lback) { + if (pit->counters[1].m & 0x02) { + if (pit->counters[1].lback2 & 0xfffe) + pit->counters[1].lback = pit->counters[1].lback2 & 0xfffe; + else + pit->counters[1].lback = 0; + } else { + pit->counters[1].lback = 0; + pit->counters[1].enable = 0; + } + pas16_log("16-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16_log("16-bit: INT PCM.\n"); + picint(1 << pas16->irq); + } + } + } else { + pit->counters[1].lback--; + if (!pit->counters[1].lback) { + if (pit->counters[1].m & 0x02) { + if (pit->counters[1].lback2 & 0xffff) + pit->counters[1].lback = pit->counters[1].lback2 & 0xffff; + else + pit->counters[1].lback = 0; + } else { + pit->counters[1].lback = 0; + pit->counters[1].enable = 0; + } + pas16_log("8-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16_log("8-bit: INT PCM.\n"); + picint(1 << pas16->irq); + } } - - pas16_log("New counter=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pclog("pas16_pcm_poll : cause IRQ %i %02X, enable timer 1 = %x\n", pas16->irq, 1 << pas16->irq, pit->counters[1].enable); - picint(1 << pas16->irq); - } else - picintc(1 << pas16->irq); } } } static void -pas16_pit_timer0(int new_out, int old_out, void *priv) +pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) { pit_t *pit = (pit_t *)priv; - pclog("NewOut=%d, OldOut=%d.\n", new_out, old_out); - pit->counters[1].enable = new_out; + pas16_t *pas16 = (pas16_t *)pit->dev_priv; + + pas16_log("PAS16 pit timer0 out=%x, cnt0=%d, cnt1=%d.\n", new_out, pit->counters[0].l, pit->counters[1].l); pit_ctr_set_clock(&pit->counters[0], new_out, pit); + pit->counters[1].enable = new_out; + if (!timer_is_enabled(&pas16->timer)) { + if (pas16->dma >= 5) + timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); + else + timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + } } static void @@ -661,48 +632,56 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - pit_handler(0, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); - io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + for (uint32_t addr = 0x000; addr < 0x10000; addr += 0x400) { + if (addr != 0x1000) { + io_removehandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + } + } + pit_handler(0, pas16->base + 0x1000, 0x0004, pas16->pit); + pit_handler(1, pas16->base + 0x1000, 0x0004, pas16->pit); pas16->base = val << 2; - pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); +} - io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - pit_handler(1, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); - io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); +static void +pas16_input_msg(void *priv, uint8_t *msg, uint32_t len) +{ + pas16_t *pas16 = (pas16_t *) priv; + + if (pas16->sysex) + return; + + if (pas16->midi_uart_in) { + pas16->midi_stat |= 0x04; + + for (uint32_t i = 0; i < len; i++) { + pas16->midi_queue[pas16->midi_w++] = msg[i]; + pas16->midi_w &= 0xff; + } + + pas16_update_irq(pas16); + } +} + +static int +pas16_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) +{ + pas16_t *pas16 = (pas16_t *) priv; + + if (abort) { + pas16->sysex = 0; + return 0; + } + pas16->sysex = 1; + for (uint32_t i = 0; i < len; i++) { + if (pas16->midi_r == pas16->midi_w) + return (len - i); + pas16->midi_queue[pas16->midi_w++] = buffer[i]; + pas16->midi_w &= 0xff; + } + pas16->sysex = 0; + return 0; } static void @@ -756,6 +735,7 @@ pas16_init(UNUSED(const device_t *info)) memset(pas16, 0, sizeof(pas16_t)); fm_driver_get(FM_YMF262, &pas16->opl); + sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); @@ -763,20 +743,25 @@ pas16_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->pit = device_add(&i8254_ext_io_device); - - pas16->midi_uart_out = 1; + pas16->pit->dev_priv = pas16; + pas16->irq = 10; + pas16->dma = 3; + pas16->base = 0x0388; io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); pit_ctr_set_using_timer(pas16->pit, 0, 1); pit_ctr_set_using_timer(pas16->pit, 1, 0); pit_ctr_set_using_timer(pas16->pit, 2, 0); - pas16->pit->dev_priv = pas16; - pas16->pit->dev_timer = pas16_pcm_poll; + + timer_add(&pas16->timer, pas16_pcm_poll, pas16, 0); sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); + if (device_get_config_int("receive_input")) + midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + return pas16; } @@ -796,6 +781,13 @@ static const device_config_t pas16_config[] = { .default_string = "", .default_int = 0 }, + { + .name = "receive_input", + .description = "Receive input (PAS16 MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, { .name = "", .description = "", .type = CONFIG_END } }; From c176a116fb0237c49b1f2fc349f75dce9a3af954 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Mar 2024 22:13:37 +0100 Subject: [PATCH 337/690] Remove deskpro386 and PAS16 from the dev branch. From the main CMakeLists.txt. --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1dfed3fb9..11265d09a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,6 @@ endif() cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF) cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF) -cmake_dependent_option(DESKPRO386 "Compaq Deskpro 386" ON "DEV_BRANCH" OFF) cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) @@ -160,7 +159,6 @@ cmake_dependent_option(LASERXT "VTech Laser XT" cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) -cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) From 882b65de48deb50af17fe70de5162268c772f1b9 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Thu, 21 Mar 2024 23:32:26 -0300 Subject: [PATCH 338/690] Implementing ESFM timer interface using 86Box's timers; dropping ESFMu's internal timer emulation Co-authored-by: OBattler --- src/sound/snd_opl_esfm.c | 216 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index cbd9a93a3..d7523da8b 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -38,11 +38,6 @@ #define RSM_FRAC 10 -enum { - FLAG_CYCLES = 0x02, - FLAG_OPL3 = 0x01 -}; - typedef struct { esfm_chip opl; int8_t flags; @@ -54,12 +49,53 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; + pc_timer_t timers[2]; + int16_t samples[2]; int pos; int32_t buffer[MUSICBUFLEN * 2]; } esfm_drv_t; +enum { + FLAG_CYCLES = 0x02, + FLAG_OPL3 = 0x01 +}; + +enum { + STAT_TMR_OVER = 0x60, + STAT_TMR1_OVER = 0x40, + STAT_TMR2_OVER = 0x20, + STAT_TMR_ANY = 0x80 +}; + +enum { + CTRL_RESET = 0x80, + CTRL_TMR_MASK = 0x60, + CTRL_TMR1_MASK = 0x40, + CTRL_TMR2_MASK = 0x20, + CTRL_TMR2_START = 0x02, + CTRL_TMR1_START = 0x01 +}; + +#ifdef ENABLE_OPL_LOG +int esfm_do_log = ENABLE_OPL_LOG; + +static void +esfm_log(const char *fmt, ...) +{ + va_list ap; + + if (esfm_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define esfm_log(fmt, ...) +#endif + void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { @@ -78,6 +114,60 @@ esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) } } +static void +esfm_timer_tick(esfm_drv_t *dev, int tmr) +{ + dev->timer_cur_count[tmr] = (dev->timer_cur_count[tmr] + 1) & 0xff; + + esfm_log("Ticking timer %i, count now %02X...\n", tmr, dev->timer_cur_count[tmr]); + + if (dev->timer_cur_count[tmr] == 0x00) { + dev->status |= ((STAT_TMR1_OVER >> tmr) & ~dev->timer_ctrl); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + + esfm_log("Count wrapped around to zero, reloading timer %i (%02X), status = %02X...\n", tmr, (STAT_TMR1_OVER >> tmr), dev->status); + } + + timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); +} + +static void +esfm_timer_control(esfm_drv_t *dev, int tmr, int start) +{ + timer_on_auto(&dev->timers[tmr], 0.0); + + if (start) { + esfm_log("Loading timer %i count: %02X = %02X\n", tmr, dev->timer_cur_count[tmr], dev->timer_count[tmr]); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + if (dev->flags & FLAG_OPL3) + esfm_timer_tick(dev, tmr); /* Per the YMF 262 datasheet, OPL3 starts counting immediately, unlike OPL2. */ + else + timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); + } else { + esfm_log("Timer %i stopped\n", tmr); + if (tmr == 1) { + dev->status &= ~STAT_TMR2_OVER; + } else + dev->status &= ~STAT_TMR1_OVER; + } +} + +static void +esfm_timer_1(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + esfm_timer_tick(dev, 0); +} + +static void +esfm_timer_2(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + esfm_timer_tick(dev, 1); +} + static void esfm_drv_set_do_cycles(void *priv, int8_t do_cycles) { @@ -98,6 +188,9 @@ esfm_drv_init(const device_t *info) /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); + timer_add(&dev->timers[0], esfm_timer_1, dev, 0); + timer_add(&dev->timers[1], esfm_timer_2, dev, 0); + return dev; } @@ -149,32 +242,131 @@ esfm_drv_read(uint16_t port, void *priv) uint8_t ret = 0xff; - ret = ESFM_read_port(&dev->opl, port & 3); + switch (port & 0x0003) + { + case 0x0000: + ret = dev->status; + if (dev->status & STAT_TMR_OVER) + ret |= STAT_TMR_ANY; + break; + case 0x0001: + ret = ESFM_read_port(&dev->opl, port & 3); + switch (dev->opl.addr_latch & 0x5ff) + { + case 0x402: + ret = dev->timer_count[0]; + break; + case 0x403: + ret = dev->timer_count[1]; + break; + case 0x404: + ret = dev->timer_ctrl; + break; + } + break; + case 0x0002: + case 0x0003: + ret = 0xff; + break; + } + + pclog("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); return ret; } +static void +esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) +{ + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + + if (dev->opl.native_mode) + { + switch (dev->port & 0x5ff) + { + case 0x402: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; + + case 0x403: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; + + case 0x404: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; + + default: + break; + } + } + else + { + switch (dev->port & 0x1ff) + { + case 0x002: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; + + case 0x003: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; + + case 0x004: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; + + default: + break; + } + } +} + static void esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; + pclog("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); esfm_drv_update(dev); if (dev->opl.native_mode) { - if ((port & 3) == 1) { - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - } else { + if ((port & 0x0003) == 0x0001) + esfm_drv_write_buffered(dev, val); + else { ESFM_write_port(&dev->opl, port & 3, val); + dev->port = dev->opl.addr_latch & 0x07ff; } } else { - if ((port & 3) == 1 || (port & 3) == 3) { - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - } else { + if ((port & 0x0001) == 0x0001) + esfm_drv_write_buffered(dev, val); + else { ESFM_write_port(&dev->opl, port & 3, val); + dev->port = dev->opl.addr_latch & 0x01ff; } } } From c835a4d1560548051285dce9cca8616da1cbf7b1 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 00:32:57 -0300 Subject: [PATCH 339/690] Uncluttering logs; making ESFM output work again (oops) --- src/sound/snd_ess.c | 2 +- src/sound/snd_opl_esfm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 55c6f9d60..6ba5a9db8 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -518,10 +518,10 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; } } +#endif buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; -#endif } #if 0 diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index d7523da8b..cf4e94cb1 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -270,7 +270,7 @@ esfm_drv_read(uint16_t port, void *priv) break; } - pclog("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + esfm_log("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); return ret; } @@ -347,7 +347,7 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - pclog("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + esfm_log("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); From 3e539c630b36e3c13fd5be620ed6ee615d97c659 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 01:31:13 -0300 Subject: [PATCH 340/690] Mixer code cleanup: fixing ESS volume calculation --- src/sound/snd_ess.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 6ba5a9db8..b2a67419a 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -50,7 +50,7 @@ #include <86box/plat_unused.h> - +// clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 }; @@ -64,6 +64,13 @@ static const double sb_att_1p4dbstep_4bits[] = { 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; +static const double sb_att_2dbstep_4bits[] = { + 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; +// clang-format on + + /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -118,27 +125,9 @@ typedef struct ess_t { void (*opl_mix)(void*, double*, double*); } ess_t; -static inline uint8_t expand16to32(const uint8_t t) { - /* 4-bit -> 5-bit expansion. - * - * 0 -> 0 - * 1 -> 2 - * 2 -> 4 - * 3 -> 6 - * .... - * 7 -> 14 - * 8 -> 17 - * 9 -> 19 - * 10 -> 21 - * 11 -> 23 - * .... - * 15 -> 31 */ - return (t << 1) | (t >> 3); -} - static double ess_mixer_get_vol_4bit(uint8_t vol) { - return (48.0 + (20.0 * log((vol & 0xF) / 15.0))) / 48.0; + return sb_att_2dbstep_4bits[vol] / 32767.0; } void From d41e791aecfe622b81bc020a9dc8e00bb59ef2cb Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 01:35:31 -0300 Subject: [PATCH 341/690] Fix bug introduced by last commit --- src/sound/snd_ess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b2a67419a..f70e508ed 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -127,7 +127,7 @@ typedef struct ess_t { static double ess_mixer_get_vol_4bit(uint8_t vol) { - return sb_att_2dbstep_4bits[vol] / 32767.0; + return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; } void From 937537f78ead2243b71d7c60480b02d955acb3c1 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 11:17:34 -0300 Subject: [PATCH 342/690] Legacy microphone volume mapping --- src/sound/snd_ess.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f70e508ed..3f544ec4f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -59,11 +59,15 @@ static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; +/* Attenuation table for 4-bit microphone volume. + * The last step is a jump to -48 dB. */ static const double sb_att_1p4dbstep_4bits[] = { 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; +/* Attenuation table for 4-bit mixer avolume. + * The last step is a jump to -48 dB. */ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 @@ -177,7 +181,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2); + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); break; } From d46e2ef7c8a3d3fc0bc87598bf25efa5b1624160 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 11:56:01 -0300 Subject: [PATCH 343/690] Refactored ESFM timers; removed 16-bit clipping from ESFMu Co-authored-by: OBattler --- src/sound/esfmu/esfm.c | 15 +++++-- src/sound/esfmu/esfm.h | 2 +- src/sound/snd_opl_esfm.c | 88 +++++++++++++--------------------------- 3 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 08beadb5a..274afd277 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -1741,6 +1741,10 @@ ESFM_slot_generate_emu(esfm_slot *slot) } /* ------------------------------------------------------------------------- */ +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" static void ESFM_process_feedback(esfm_chip *chip) { @@ -2226,7 +2230,7 @@ ESFM_update_write_buffer(esfm_chip *chip) /* ------------------------------------------------------------------------- */ void -ESFM_generate(esfm_chip *chip, int16_t *buf) +ESFM_generate(esfm_chip *chip, int32_t *buf) { int channel_idx; @@ -2259,8 +2263,8 @@ ESFM_generate(esfm_chip *chip, int16_t *buf) chip->output_accm[1] += channel->output[1]; } - buf[0] = ESFM_clip_sample(chip->output_accm[0]); - buf[1] = ESFM_clip_sample(chip->output_accm[1]); + buf[0] = chip->output_accm[0]; + buf[1] = chip->output_accm[1]; ESFM_update_timers(chip); ESFM_update_write_buffer(chip); @@ -2308,10 +2312,13 @@ void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples) { uint32_t i; + int32_t buf[2] = { 0 }; for (i = 0; i < num_samples; i++) { - ESFM_generate(chip, sndptr); + ESFM_generate(chip, buf); + sndptr[0] = ESFM_clip_sample(buf[0]); + sndptr[1] = ESFM_clip_sample(buf[1]); sndptr += 2; } } diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h index 41ac6983f..eda8bcbb3 100644 --- a/src/sound/esfmu/esfm.h +++ b/src/sound/esfmu/esfm.h @@ -67,7 +67,7 @@ void ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t da void ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data); uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); -void ESFM_generate(esfm_chip *chip, int16_t *buf); +void ESFM_generate(esfm_chip *chip, int32_t *buf); void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index cf4e94cb1..174830523 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -99,10 +99,7 @@ esfm_log(const char *fmt, ...) void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - ESFM_generate(&dev->opl, &dev->samples[0]); - - bufp[0] = dev->samples[0]; - bufp[1] = dev->samples[1]; + ESFM_generate(&dev->opl, bufp); } void @@ -270,75 +267,48 @@ esfm_drv_read(uint16_t port, void *priv) break; } - esfm_log("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); - return ret; } static void esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) { + uint16_t p = dev->port; + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); if (dev->opl.native_mode) { - switch (dev->port & 0x5ff) - { - case 0x402: /* Timer 1 */ - dev->timer_count[0] = val; - esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); - break; - - case 0x403: /* Timer 2 */ - dev->timer_count[1] = val; - esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); - break; - - case 0x404: /* Timer control */ - if (val & CTRL_RESET) { - esfm_log("Resetting timer status...\n"); - dev->status &= ~STAT_TMR_OVER; - } else { - dev->timer_ctrl = val; - esfm_timer_control(dev, 0, val & CTRL_TMR1_START); - esfm_timer_control(dev, 1, val & CTRL_TMR2_START); - esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); - } - break; - - default: - break; - } + p -= 0x400; + p &= 0x1ff; } - else + + switch (p) { - switch (dev->port & 0x1ff) - { - case 0x002: /* Timer 1 */ - dev->timer_count[0] = val; - esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); - break; + case 0x002: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; - case 0x003: /* Timer 2 */ - dev->timer_count[1] = val; - esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); - break; + case 0x003: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; - case 0x004: /* Timer control */ - if (val & CTRL_RESET) { - esfm_log("Resetting timer status...\n"); - dev->status &= ~STAT_TMR_OVER; - } else { - dev->timer_ctrl = val; - esfm_timer_control(dev, 0, val & CTRL_TMR1_START); - esfm_timer_control(dev, 1, val & CTRL_TMR2_START); - esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); - } - break; + case 0x004: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; - default: - break; - } + default: + break; } } @@ -347,8 +317,6 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - esfm_log("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); - if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); From 5e318dfce9420f264f44ea4b0a1f165c4d2c2256 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 12:13:57 -0300 Subject: [PATCH 344/690] Updating ESFMu to version v1.2.6 --- src/sound/esfmu/esfm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 274afd277..89fa82d4f 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -1783,7 +1783,7 @@ ESFM_process_feedback(esfm_chip *chip) eg_output = slot->in.eg_output; // ASM optimizaions! -#if defined(__GNUC__) && defined(__x86_64__) +#if defined(__GNUC__) && defined(__x86_64__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) asm ( "movzbq %[wave], %%r8 \n\t" "shll $11, %%r8d \n\t" @@ -1848,11 +1848,14 @@ ESFM_process_feedback(esfm_chip *chip) [exprom] "m" (exprom) : "cc", "ax", "bx", "cx", "dx", "r8", "r9", "r10", "r11" ); -#elif defined(__GNUC__) && defined(__i386__) +#elif defined(__GNUC__) && defined(__i386__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) + size_t logsinrom_addr = (size_t)logsinrom; + size_t exprom_addr = (size_t)exprom; + asm ( "movzbl %b[wave], %%eax \n\t" "shll $11, %%eax \n\t" - "leal %[sinrom], %%edi \n\t" + "movl %[sinrom], %%edi \n\t" "addl %%eax, %%edi \n\t" "shlw $3, %[eg_out] \n\t" "xorl %[out], %[out] \n\t" @@ -1887,7 +1890,7 @@ ESFM_process_feedback(esfm_chip *chip) // wave_out = exprom[level & 0xff] >> (level >> 8); "movb %%ah, %%cl \n\t" "movzbl %%al, %%eax \n\t" - "leal %[exprom], %[out] \n\t" + "movl %[exprom], %[out] \n\t" "movzwl (%[out], %%eax, 2), %[out] \n\t" "shrl %%cl, %[out] \n\t" // if (lookup & 0x8000) wave_out = -wave_out; @@ -1909,12 +1912,12 @@ ESFM_process_feedback(esfm_chip *chip) : [p_off] "m" (phase_offset), [mod_in] "m" (mod_in_shift), [wave] "m" (waveform), - [sinrom] "m" (logsinrom), - [exprom] "m" (exprom), + [sinrom] "m" (logsinrom_addr), + [exprom] "m" (exprom_addr), [i] "m" (iter_counter) : "cc", "ax", "bx", "cx", "di" ); -#elif defined(__GNUC__) && defined(__arm__) +#elif defined(__GNUC__) && defined(__arm__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) asm ( "movs r3, #0 \n\t" "movs %[out], #0 \n\t" From 36ecc175513b910d683da5d5520d18e160faef36 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Mar 2024 23:24:58 +0100 Subject: [PATCH 345/690] Fix incompatible pointers of the generic PIT and PCjr's So that the build compiles fine. --- src/machine/m_pcjr.c | 2 +- src/machine/machine.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 80a0ffbc1..804da8e30 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -772,7 +772,7 @@ speed_changed(void *priv) } void -pit_irq0_timer_pcjr(int new_out, int old_out) +pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) { picint(1); diff --git a/src/machine/machine.c b/src/machine/machine.c index 9e530eb3b..b171dd505 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -156,7 +156,7 @@ machine_available(int m) } void -pit_irq0_timer(int new_out, int old_out) +pit_irq0_timer(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) picint(1); From 309786bc7aeb159600b21735fdc35a4ec1c9f6c2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Mar 2024 23:51:25 +0100 Subject: [PATCH 346/690] Add the Tandy 4000 AT compatible and SCAT-286-003 machines And a proper Compaq Portable III 386 BIOS. Note: The SCAT 286 003 machine is a SCAT-based AMI 286 machine. --- src/include/86box/machine.h | 2 + src/machine/m_at_286_386sx.c | 19 +++++++++ src/machine/m_at_386dx_486.c | 20 +++++++++ src/machine/m_at_compaq.c | 9 ++-- src/machine/machine_table.c | 81 +++++++++++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ee18a89b1..f97d1a37c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -451,6 +451,7 @@ extern int machine_at_quadt386sx_init(const machine_t *); extern int machine_at_award286_init(const machine_t *); extern int machine_at_gdc212m_init(const machine_t *); extern int machine_at_gw286ct_init(const machine_t *); +extern int machine_at_senor_scat286_init(const machine_t *); extern int machine_at_super286c_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); @@ -492,6 +493,7 @@ extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_ecs386v_init(const machine_t *); +extern int machine_at_tandy4000_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index a688181b4..53df7f628 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -350,6 +350,25 @@ machine_at_gw286ct_init(const machine_t *model) return ret; } +int +machine_at_senor_scat286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/senor286/AMI-DSC2-1115-061390-K8.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_super286c_init(const machine_t *model) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3376e7b25..b89f77b18 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -90,6 +90,26 @@ machine_at_asus386_init(const machine_t *model) return ret; } +int +machine_at_tandy4000_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tandy4000/BIOS Tandy 4000 v1.03.01.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + static void machine_at_sis401_common_init(const machine_t *model) { diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index cd8c68764..7f31d4ecd 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -633,7 +633,10 @@ compaq_plasma_init(UNUSED(const device_t *info)) memset(self, 0, sizeof(compaq_plasma_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); - loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); + if (compaq_machine_type == COMPAQ_PORTABLEIII) + loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); + else + loadfont_ex("roms/machines/portableiii/P.2 Combined.bin", 11, 0x4b49); self->cga.composite = 0; self->cga.revision = 0; @@ -863,8 +866,8 @@ machine_at_portableiii386_init(const machine_t *model) { int ret; - ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/P.2 Combined.bin", + 0x000f0000, 131072, 0); if (bios_only || !ret) return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5dad8b431..23c05bdf8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3726,6 +3726,45 @@ const machine_t machines[] = { .net_device = NULL }, + { + .name = "[SCAT] Senor Science Co. SCAT-286-003", + .internal_name = "senorscat286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_senor_scat286_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 4096, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 286 machines that utilize the MCA bus */ /* Has IBM PS/2 Type 2 KBC firmware. */ { @@ -5013,7 +5052,7 @@ const machine_t machines[] = { .max = 14336, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 63, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -5065,6 +5104,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Tandy 4000", + .internal_name = "tandy4000", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_tandy4000_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ { .name = "[ALi M1429] ECS Panda 386V", From 4b93999790191540bf0c274c2137dedcb79903b8 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:30:23 -0300 Subject: [PATCH 347/690] Cleanup: removing a bunch of logging statements --- src/sound/snd_ess.c | 12 +++------- src/sound/snd_sb_dsp.c | 52 +++--------------------------------------- 2 files changed, 6 insertions(+), 58 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 3f544ec4f..44106fa83 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -167,7 +167,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; - pclog("ess: Mixer Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -322,7 +321,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + //pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -378,30 +377,25 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: - if (0) + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - /* not on ES1688 */ uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; - pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } else { - pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; } default: - pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + //pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index f94724e68..03a6ba4ba 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -367,7 +367,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked\n"); return; } @@ -394,7 +393,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked\n"); return; } } @@ -409,7 +407,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) void sb_irq(sb_dsp_t *dsp, int irq8) { - pclog("sb: IRQ raised\n"); sb_update_status(dsp, !irq8, 1); } @@ -862,7 +859,6 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: - pclog("ESS register read reg=%02xh val=%02xh\n",reg, ESSreg(reg)); return ESSreg(reg); } @@ -876,7 +872,6 @@ static void sb_ess_update_autolen(sb_dsp_t *dsp) { static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; - pclog("ESS register write reg=%02xh val=%02xh\n",reg,data); switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ @@ -890,7 +885,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; - pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -901,7 +895,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - pclog("ess: DMA Transfer Count Reload length set to %d samples (0x%x)\n", sb_ess_get_dma_len(dsp), sb_ess_get_dma_counter(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -950,7 +943,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_irqnum = 10; break; } - pclog("ess: IRQ set to %d\n", dsp->sb_irqnum); sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ @@ -971,7 +963,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_8_dmanum = 3; break; } - pclog("ess: DMA set to %d\n", dsp->sb_8_dmanum); sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; @@ -1053,7 +1044,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: - pclog("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); + sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); break; } } @@ -1072,20 +1063,6 @@ sb_exec_command(sb_dsp_t *dsp) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } - - { - int i, l, s = 0; - char data_s[256], *dsptr = data_s; - data_s[0] = '\0'; - - for (i = 0; i < sb_commands[dsp->sb_command]; i++) - { - l = snprintf(dsptr, 256 - s, " 0x%02X", dsp->sb_data[i]); - s += l; - dsptr += l; - } - pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); - } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { @@ -1320,7 +1297,6 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); @@ -1334,7 +1310,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) { dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); - pclog("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256LL + dsp->sb_freq; @@ -1360,7 +1335,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_4 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1375,7 +1349,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_3 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1390,7 +1363,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_1 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1405,7 +1377,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_4E || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1652,11 +1623,9 @@ sb_exec_command(sb_dsp_t *dsp) case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); if (IS_ESS(dsp)) { - if (timer_is_enabled(&dsp->irq_timer)) - pclog("F2 already written\n"); - else { + if (!timer_is_enabled(&dsp->irq_timer)) + { timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); - pclog("F2 written\n"); } } else { sb_irq(dsp, 1); @@ -1665,7 +1634,6 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 0); dsp->ess_irq_generic = true; break; case 0xF8: @@ -1812,10 +1780,6 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((a & 0xF) == 0x9 || (a & 0xF) == 0xB) - { - pclog("ess: Read-Sequence-Key? port 0x%X", a); - } if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ @@ -1880,10 +1844,6 @@ sb_read(uint16_t a, void *priv) break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); - if (dsp->sb_irq8 || dsp->sb_irq16) - { - pclog("sb: IRQ acknowledged\n"); - } dsp->sb_irq8 = dsp->sb_irq16 = 0; dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ @@ -1898,10 +1858,6 @@ sb_read(uint16_t a, void *priv) case 0xF: /* 16-bit ack */ if (!IS_ESS(dsp)) { - if (dsp->sb_irq16) - { - pclog("sb: 16-bit IRQ acknowledged"); - } dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -2107,7 +2063,6 @@ sb_ess_finish_dma(sb_dsp_t *dsp) return; ESSreg(0xB8) &= ~0x01; dma_set_drq(dsp->sb_8_dmanum, 0); - pclog("ess: DMA finished"); } void @@ -2615,7 +2570,6 @@ pollsb(void *priv) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; - pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); } } uint32_t temp = dsp->ess_dma_counter & 0xffff; From f2091e349006ecc0118ce89557d3a1186f83f2b0 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:36:41 -0300 Subject: [PATCH 348/690] Cleanup: removing broken recording functionality --- src/sound/snd_ess.c | 103 +------------------------------------------- 1 file changed, 2 insertions(+), 101 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 44106fa83..b07c2d18f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -66,7 +66,7 @@ static const double sb_att_1p4dbstep_4bits[] = { 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; -/* Attenuation table for 4-bit mixer avolume. +/* Attenuation table for 4-bit mixer volume. * The last step is a jump to -48 dB. */ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, @@ -104,14 +104,8 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; - uint8_t ess_id_str[256]; + uint8_t ess_id_str[4]; uint8_t ess_id_str_pos; - -#if 0 - int record_pos_write_cd; - double record_pos_write_cd_sigma; - int record_pos_write_music; -#endif } ess_mixer_t; typedef struct ess_t { @@ -448,12 +442,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { ess_t *ess = (ess_t *) priv; const ess_mixer_t *mixer = &ess->mixer_sbpro; -#if 0 - int rec_pos = ess->mixer_sbpro.record_pos_write_music; - int c_record; - int32_t in_l; - int32_t in_r; -#endif double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; @@ -475,52 +463,10 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l *= mixer->master_l; out_r *= mixer->master_r; -#if 0 - // Pull input after applying mixer's master volume scaling - in_l = (mixer->input_selector & INPUT_MIXER_L) ? ((int32_t) out_l) : 0; - in_r = (mixer->input_selector & INPUT_MIXER_R) ? ((int32_t) out_l) : 0; - - if (ess->dsp.sb_enable_i) { - // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? - c_record = rec_pos + ((c * ess->dsp.sb_freq) / MUSIC_FREQ); - - ess->dsp.record_buffer[c_record & 0xfffe] += in_l; - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] += in_r; - - if (ess->dsp.record_buffer[c_record & 0xfffe] < -32768) - { - ess->dsp.record_buffer[c_record & 0xfffe] = -32768; - } - else if (ess->dsp.record_buffer[c_record & 0xfffe] > 32767) - { - ess->dsp.record_buffer[c_record & 0xfffe] = 32767; - } - - if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] < -32768) - { - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = -32768; - } - else if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] > 32767) - { - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; - } - } -#endif - buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; } -#if 0 - ess->mixer_sbpro.record_pos_write_music += ((len * 2 * ess->dsp.sb_freq) / MUSIC_FREQ); - ess->mixer_sbpro.record_pos_write_music &= 0xfffe; - - if (ess->mixer_sbpro.record_pos_write_music < ess->mixer_sbpro.record_pos_write_cd) - { - ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_music; - } -#endif - ess->opl.reset_buffer(ess->opl.priv); } @@ -530,51 +476,11 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) const ess_t *ess = (ess_t *) priv; const ess_mixer_t *mixer = &ess->mixer_sbpro; double c; -#if 0 - double rec_pos = ess->mixer_sbpro.record_pos_write_cd; - double rec_pos_sigma = ess->mixer_sbpro.record_pos_write_cd_sigma; - int c_record; - int selector = channel ? INPUT_MIXER_R : INPUT_MIXER_L; - int rec_buf_pos; - int32_t in; -#endif double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; c = (*buffer * cd) / 3.0; *buffer = c * master; -#if 0 - in = (mixer->input_selector & selector) ? (int32_t)(c * master) : 0; - - if (ess->dsp.sb_enable_i) - { - // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? - c_record = (int)(rec_pos + rec_pos_sigma); - rec_buf_pos = channel ? ((c_record & 0xfffe) + 1) : (c_record & 0xfffe); - - ess->dsp.record_buffer[rec_buf_pos] += in; - - if (ess->dsp.record_buffer[rec_buf_pos] < -32768) - { - ess->dsp.record_buffer[rec_buf_pos] = -32768; - } - else if (ess->dsp.record_buffer[rec_buf_pos] > 32767) - { - ess->dsp.record_buffer[rec_buf_pos] = 32767; - } - } - - ess->mixer_sbpro.record_pos_write_cd += ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma; - ess->mixer_sbpro.record_pos_write_cd &= ~1; - ess->mixer_sbpro.record_pos_write_cd_sigma = (double)rec_pos + ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma - ess->mixer_sbpro.record_pos_write_cd; - - ess->mixer_sbpro.record_pos_write_cd &= 0xfffe; - - if (ess->mixer_sbpro.record_pos_write_cd < ess->mixer_sbpro.record_pos_write_music) - { - ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_cd; - } -#endif } static void * @@ -634,11 +540,6 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } -#if 0 - ess->mixer_sbpro.record_pos_write_cd = ess->dsp.record_pos_write; - ess->mixer_sbpro.record_pos_write_music = ess->dsp.record_pos_write; -#endif - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); From 81029da95024678d7378d1fda1401cda2f063b8b Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:46:27 -0300 Subject: [PATCH 349/690] Cleanup: rolling back extraneous change in cpu.h --- src/cpu/cpu.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index f2e1242df..16a9eba10 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,14 +21,7 @@ #ifndef EMU_CPU_H #define EMU_CPU_H -#ifndef NO_SOFTFLOAT_INCLUDE #include "softfloat/softfloat.h" -#else -typedef struct floatx80 { // leave alignment to compiler - uint64_t exp; - uint16_t fraction; -} floatx80; -#endif enum { FPU_NONE, From ad616723859a1e4824fae0687958bc52a5fef943 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 22:21:27 -0300 Subject: [PATCH 350/690] Rename ESFMu flag type to ebit --- src/sound/esfmu/esfm.h | 96 +++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h index eda8bcbb3..766c7312d 100644 --- a/src/sound/esfmu/esfm.h +++ b/src/sound/esfmu/esfm.h @@ -74,7 +74,7 @@ int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); // These are fake types just for syntax sugar. // Beware of their underlying types when reading/writing to them. -typedef uint8_t flag; +typedef uint8_t ebit; typedef uint8_t uint2; typedef uint8_t uint3; typedef uint8_t uint4; @@ -110,7 +110,7 @@ typedef struct _esfm_write_buf uint64_t timestamp; uint16_t address; uint8_t data; - flag valid; + ebit valid; } esfm_write_buf; @@ -137,16 +137,16 @@ typedef struct _esfm_slot_internal uint19 phase_acc; uint10 phase_out; - flag phase_reset; - flag *key_on; - flag key_on_gate; + ebit phase_reset; + ebit *key_on; + ebit key_on_gate; uint2 eg_state; - flag eg_delay_run; - flag eg_delay_transitioned_10; - flag eg_delay_transitioned_10_gate; - flag eg_delay_transitioned_01; - flag eg_delay_transitioned_01_gate; + ebit eg_delay_run; + ebit eg_delay_transitioned_10; + ebit eg_delay_transitioned_10_gate; + ebit eg_delay_transitioned_01; + ebit eg_delay_transitioned_01_gate; uint16 eg_delay_counter; uint16 eg_delay_counter_compare; @@ -178,18 +178,18 @@ struct _esfm_slot uint4 sustain_lvl; uint4 release_rate; - flag tremolo_en; - flag tremolo_deep; - flag vibrato_en; - flag vibrato_deep; - flag emu_connection_typ; - flag env_sustaining; - flag ksr; + ebit tremolo_en; + ebit tremolo_deep; + ebit vibrato_en; + ebit vibrato_deep; + ebit emu_connection_typ; + ebit env_sustaining; + ebit ksr; uint2 ksl; uint3 env_delay; // overlaps with env_delay bit 0 // TODO: check if emu mode only uses this, or if it actually overwrites the channel field used by native mode - flag emu_key_on; + ebit emu_key_on; // Internal state esfm_slot_internal in; @@ -201,11 +201,11 @@ struct _esfm_channel esfm_slot slots[4]; uint5 channel_idx; int16 output[2]; - flag key_on; - flag emu_mode_4op_enable; + ebit key_on; + ebit emu_mode_4op_enable; // Only for 17th and 18th channels - flag key_on_2; - flag emu_mode_4op_enable_2; + ebit key_on_2; + ebit emu_mode_4op_enable_2; }; #define ESFM_WRITEBUF_SIZE 1024 @@ -217,66 +217,66 @@ struct _esfm_chip int32 output_accm[2]; uint16 addr_latch; - flag emu_wavesel_enable; - flag emu_newmode; - flag native_mode; + ebit emu_wavesel_enable; + ebit emu_newmode; + ebit native_mode; - flag keyscale_mode; + ebit keyscale_mode; // Global state uint36 eg_timer; uint10 global_timer; uint8 eg_clocks; - flag eg_tick; - flag eg_timer_overflow; + ebit eg_tick; + ebit eg_timer_overflow; uint8 tremolo; uint8 tremolo_pos; uint8 vibrato_pos; uint23 lfsr; - flag rm_hh_bit2; - flag rm_hh_bit3; - flag rm_hh_bit7; - flag rm_hh_bit8; - flag rm_tc_bit3; - flag rm_tc_bit5; + ebit rm_hh_bit2; + ebit rm_hh_bit3; + ebit rm_hh_bit7; + ebit rm_hh_bit8; + ebit rm_tc_bit3; + ebit rm_tc_bit5; // 0xbd register in emulation mode, exposed in 0x4bd in native mode // ("bass drum" register) uint8 emu_rhy_mode_flags; - flag emu_vibrato_deep; - flag emu_tremolo_deep; + ebit emu_vibrato_deep; + ebit emu_tremolo_deep; double timer_accumulator[2]; uint8 timer_reload[2]; uint8 timer_counter[2]; - flag timer_enable[2]; - flag timer_mask[2]; - flag timer_overflow[2]; - flag irq_bit; + ebit timer_enable[2]; + ebit timer_mask[2]; + ebit timer_overflow[2]; + ebit irq_bit; // -- Test bits (NOT IMPLEMENTED) -- // Halts the envelope generators from advancing. Written on bit 0, read back from bit 5. - flag test_bit_w0_r5_eg_halt; + ebit test_bit_w0_r5_eg_halt; /* * Activates some sort of waveform test mode that amplifies the output volume greatly * and continuously shifts the waveform table downwards, possibly also outputting the * waveform's derivative? (it's so weird!) */ - flag test_bit_1_distort; + ebit test_bit_1_distort; // Seems to do nothing. - flag test_bit_2; + ebit test_bit_2; // Seems to do nothing. - flag test_bit_3; + ebit test_bit_3; // Appears to attenuate the output by about 3 dB. - flag test_bit_4_attenuate; + ebit test_bit_4_attenuate; // Written on bit 5, read back from bit 0. Seems to do nothing. - flag test_bit_w5_r0; + ebit test_bit_w5_r0; // Resets all phase generators and holds them in the reset state while this bit is set. - flag test_bit_6_phase_stop_reset; + ebit test_bit_6_phase_stop_reset; // Seems to do nothing. - flag test_bit_7; + ebit test_bit_7; esfm_write_buf write_buf[ESFM_WRITEBUF_SIZE]; size_t write_buf_start; From 8bfcfec280c3c531bfded21e59733616acf193ac Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:07:12 -0300 Subject: [PATCH 351/690] Cleanup: clang-format --- src/sound/snd_ess.c | 226 +++++++------- src/sound/snd_opl_esfm.c | 30 +- src/sound/snd_sb_dsp.c | 645 +++++++++++++++++---------------------- 3 files changed, 392 insertions(+), 509 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b07c2d18f..38610c6ee 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -13,7 +13,7 @@ * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, - * Cacodemon345, + * Cacodemon345, * Kagamiin~, * * Copyright 2008-2020 Sarah Walker. @@ -49,7 +49,6 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> - // clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 @@ -74,7 +73,6 @@ static const double sb_att_2dbstep_4bits[] = { }; // clang-format on - /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -109,21 +107,22 @@ typedef struct ess_mixer_t { } ess_mixer_t; typedef struct ess_t { - uint8_t mixer_enabled; - fm_drv_t opl; - sb_dsp_t dsp; + uint8_t mixer_enabled; + fm_drv_t opl; + sb_dsp_t dsp; ess_mixer_t mixer_sbpro; - mpu_t *mpu; - void *gameport; + mpu_t *mpu; + void *gameport; uint16_t gameport_addr; - void *opl_mixer; - void (*opl_mix)(void*, double*, double*); + void *opl_mixer; + void (*opl_mix)(void *, double *, double *); } ess_t; -static double ess_mixer_get_vol_4bit(uint8_t vol) +static double +ess_mixer_get_vol_4bit(uint8_t vol) { return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; } @@ -137,8 +136,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (!(addr & 1)) { mixer->index = val; mixer->regs[0x01] = val; - if (val == 0x40) - { + if (val == 0x40) { mixer->ess_id_str_pos = 0; } } else { @@ -153,10 +151,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Initialize ESS regs. */ mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; - mixer->regs[0x3a] = 0x00; - mixer->regs[0x3e] = 0x00; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x88; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { @@ -171,24 +169,24 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x0A: - { - uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; - mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); - break; - } + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); + break; + } case 0x0C: switch (mixer->regs[0x0C] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; } break; @@ -202,20 +200,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x1C: - if ((mixer->regs[0x1C] & 0x07) == 0x07) - { + if ((mixer->regs[0x1C] & 0x07) == 0x07) { mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; - } - else if ((mixer->regs[0x1C] & 0x07) == 0x06) - { + } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - } - else if ((mixer->regs[0x1C] & 0x06) == 0x02) - { + } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - } - else if ((mixer->regs[0x1C] & 0x02) == 0) - { + } else if ((mixer->regs[0x1C] & 0x02) == 0) { mixer->input_selector = INPUT_MIC; } break; @@ -255,26 +246,22 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[mixer->index] &= ~0x8; break; - case 0x40: { - /* TODO: Implement "Read-Sequence-Key" method of software address selection - * (needed for ESSCFG.EXE to work properly) */ - + case 0x40: + { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - if (0) - { + if (0) { /* Not on ES1688. */ io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) - { + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) { io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); } } switch ((mixer->regs[0x40] >> 5) & 0x7) { @@ -315,7 +302,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - //pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + // pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -375,21 +362,18 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x40: - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) - { + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; return val; - } - else - { + } else { return mixer->regs[mixer->index]; } default: - //pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + // pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } @@ -406,10 +390,10 @@ ess_mixer_reset(ess_t *ess) void ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) { - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; sb_dsp_update(&ess->dsp); @@ -440,11 +424,11 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) void ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; opl_buf = ess->opl.update(ess->opl.priv); @@ -473,13 +457,13 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) void ess_filter_cd_audio(int channel, double *buffer, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } @@ -492,8 +476,8 @@ ess_1688_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = calloc(sizeof(ess_t), 1); - uint16_t addr = device_get_config_hex16("base"); + ess_t *ess = calloc(sizeof(ess_t), 1); + uint16_t addr = device_get_config_hex16("base"); fm_driver_get(FM_ESFM, &ess->opl); @@ -544,7 +528,7 @@ ess_1688_init(UNUSED(const device_t *info)) mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); - ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport = gameport_add(&gameport_pnp_device); ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); @@ -568,95 +552,97 @@ ess_speed_changed(void *priv) sb_dsp_speed_changed(&ess->dsp); } +// clang-format off static const device_config_t ess_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "0x220", - .value = 0x220 + .value = 0x220 }, { .description = "0x240", - .value = 0x240 + .value = 0x240 }, { .description = "" } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", - .value = 2 + .value = 2 }, { .description = "IRQ 5", - .value = 5 + .value = 5 }, { .description = "IRQ 7", - .value = 7 + .value = 7 }, { .description = "IRQ 10", - .value = 10 + .value = 10 }, { .description = "" } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "DMA 0", - .value = 0 + .value = 0 }, { .description = "DMA 1", - .value = 1 + .value = 1 }, { .description = "DMA 3", - .value = 3 + .value = 3 }, { .description = "" } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 1 }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t ess_1688_device = { .name = "ESS Technology ES1688", diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 174830523..c36ec4160 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -7,8 +7,8 @@ * This file is part of the 86Box distribution. * * ESFMu ESFM emulator. - * - * + * + * * Authors: Fred N. van Kempen, * Miran Grca, * Alexey Khokholov (Nuke.YKT) @@ -29,19 +29,18 @@ #include "esfmu/esfm.h" #define HAVE_STDARG_H -#define NO_SOFTFLOAT_INCLUDE #include <86box/86box.h> #include <86box/sound.h> #include <86box/device.h> #include <86box/timer.h> #include <86box/snd_opl.h> -#define RSM_FRAC 10 +#define RSM_FRAC 10 typedef struct { esfm_chip opl; - int8_t flags; - int8_t pad; + int8_t flags; + int8_t pad; uint16_t port; uint8_t status; @@ -180,7 +179,7 @@ static void * esfm_drv_init(const device_t *info) { esfm_drv_t *dev = (esfm_drv_t *) calloc(1, sizeof(esfm_drv_t)); - dev->flags = FLAG_CYCLES | FLAG_OPL3; + dev->flags = FLAG_CYCLES | FLAG_OPL3; /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); @@ -207,8 +206,8 @@ esfm_drv_update(void *priv) return dev->buffer; esfm_drv_generate_stream(dev, - &dev->buffer[dev->pos * 2], - music_pos_global - dev->pos); + &dev->buffer[dev->pos * 2], + music_pos_global - dev->pos); for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; @@ -218,7 +217,6 @@ esfm_drv_update(void *priv) return dev->buffer; } - static void esfm_drv_reset_buffer(void *priv) { @@ -239,8 +237,7 @@ esfm_drv_read(uint16_t port, void *priv) uint8_t ret = 0xff; - switch (port & 0x0003) - { + switch (port & 0x0003) { case 0x0000: ret = dev->status; if (dev->status & STAT_TMR_OVER) @@ -248,8 +245,7 @@ esfm_drv_read(uint16_t port, void *priv) break; case 0x0001: ret = ESFM_read_port(&dev->opl, port & 3); - switch (dev->opl.addr_latch & 0x5ff) - { + switch (dev->opl.addr_latch & 0x5ff) { case 0x402: ret = dev->timer_count[0]; break; @@ -277,14 +273,12 @@ esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - if (dev->opl.native_mode) - { + if (dev->opl.native_mode) { p -= 0x400; p &= 0x1ff; } - switch (p) - { + switch (p) { case 0x002: /* Timer 1 */ dev->timer_count[0] = val; esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 03a6ba4ba..5290d6bc5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -120,6 +120,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; +// clang-format off /* Upper half only used for ESPCM_3 mode. */ /* TODO: Extract actual table (or exact ranges + range interpolation algo, whatever it is) from chip, someday, somehow. * This current table is part software reverse engineering, part guesswork/extrapolation. @@ -235,6 +236,7 @@ uint16_t espcm3_dpcm_tables[1024] = 5, 7, 8, 9, 10, 11, 12, 270, 5, 7, 8, 9, 10, 11, 12, 270, 6, 7, 8, 9, 10, 11, 13, 271, 6, 7, 8, 9, 10, 11, 13, 15 }; +// clang-format on double low_fir_sb16_coef[4][SB16_NCoef]; @@ -387,8 +389,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) } /* NOTE: not on ES1688, apparently; investigate on ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) - { + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) { /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire @@ -523,17 +524,19 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } -static unsigned int sb_ess_get_dma_counter(sb_dsp_t *dsp) +static unsigned int +sb_ess_get_dma_counter(sb_dsp_t *dsp) { unsigned int c; - c = (unsigned int)ESSreg(0xA5) << 8U; - c |= (unsigned int)ESSreg(0xA4); + c = (unsigned int) ESSreg(0xA5) << 8U; + c |= (unsigned int) ESSreg(0xA4); return c; } -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +static unsigned int +sb_ess_get_dma_len(sb_dsp_t *dsp) { return 0x10000U - sb_ess_get_dma_counter(dsp); } @@ -605,11 +608,11 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) } void -sb_start_dma_ess(sb_dsp_t* dsp) +sb_start_dma_ess(sb_dsp_t *dsp) { - uint8_t real_format = 0; + uint8_t real_format = 0; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); - uint32_t len = sb_ess_get_dma_len(dsp); + uint32_t len = sb_ess_get_dma_len(dsp); if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); @@ -627,26 +630,28 @@ sb_start_dma_ess(sb_dsp_t* dsp) } void -sb_stop_dma_ess(sb_dsp_t* dsp) +sb_stop_dma_ess(sb_dsp_t *dsp) { dsp->sb_8_enable = dsp->sb_16_enable = 0; dma_set_drq(dsp->sb_16_8_dmanum, 0); dma_set_drq(dsp->sb_8_dmanum, 0); } -static void sb_ess_update_dma_status(sb_dsp_t* dsp) +static void +sb_ess_update_dma_status(sb_dsp_t *dsp) { - bool dma_en = (ESSreg(0xB8) & 1)?true:false; + bool dma_en = (ESSreg(0xB8) & 1) ? true : false; // if the DRQ is disabled, do not start if (!(ESSreg(0xB2) & 0x40)) dma_en = false; if (dma_en) { - if (!dsp->sb_8_enable && !dsp->sb_16_enable) sb_start_dma_ess(dsp); - } - else { - if (dsp->sb_8_enable || dsp->sb_16_enable) sb_stop_dma_ess(dsp); + if (!dsp->sb_8_enable && !dsp->sb_16_enable) + sb_start_dma_ess(dsp); + } else { + if (dsp->sb_8_enable || dsp->sb_16_enable) + sb_stop_dma_ess(dsp); } } @@ -682,8 +687,8 @@ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -697,7 +702,7 @@ sb_16_read_dma(void *priv) /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_read(dma_ch); - ret = temp; + ret = temp; if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { temp = dma_channel_read(dma_ch); if (temp == DMA_NODATA) @@ -706,7 +711,7 @@ sb_16_read_dma(void *priv) dma_flags = temp & DMA_OVER; temp &= ~DMA_OVER; ret |= (temp << 8) | dma_flags; - } + } } } @@ -717,9 +722,9 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_ch = dsp->sb_16_dmanum; - + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; else { @@ -732,10 +737,10 @@ sb_16_write_dma(void *priv, uint16_t val) /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_write(dma_ch, val & 0xff); - ret = temp; + ret = temp; if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { temp = dma_channel_write(dma_ch, val >> 8); - ret = temp; + ret = temp; } } @@ -747,28 +752,40 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) { uint8_t t = 0x00; /* IRQ control */ - if (legacy) - { + if (legacy) { t |= 0x80; } switch (dsp->sb_irqnum) { - case 9: t |= 0x0; break; - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; + case 9: + t |= 0x0; + break; + case 5: + t |= 0x5; + break; + case 7: + t |= 0xA; + break; + case 10: + t |= 0xF; + break; } ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; /* DRQ control */ t = 0x00; - if (legacy) - { + if (legacy) { t |= 0x80; } switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; + case 0: + t |= 0x5; + break; + case 1: + t |= 0xA; + break; + case 3: + t |= 0xF; + break; } ESSreg(0xB2) = (ESSreg(0xB2) & 0xF0) | t; } @@ -830,10 +847,11 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } -static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +static void +sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) { - double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; - int temp = (int) freq; + double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + int temp = (int) freq; ESSreg(0xA2) = val; if (dsp->sb_freq != temp) @@ -843,7 +861,8 @@ static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ -static void sb_ess_update_filter_freq(sb_dsp_t *dsp) +static void +sb_ess_update_filter_freq(sb_dsp_t *dsp) { double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; @@ -855,7 +874,8 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) sb_ess_update_reg_a2(dsp, (uint8_t) temp); } -static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +static uint8_t +sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: @@ -865,28 +885,31 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } -static void sb_ess_update_autolen(sb_dsp_t *dsp) { +static void +sb_ess_update_autolen(sb_dsp_t *dsp) +{ dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); } -static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +static void +sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ - { - double temp; - ESSreg(reg) = data; - if (data & 0x80) - dsp->sb_freq = 795500UL / (256ul - data); - else - dsp->sb_freq = 397700UL / (128ul - data); - temp = 1000000.0 / dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; - dsp->sb_timei = dsp->sb_timeo; - break; - } + { + double temp; + ESSreg(reg) = data; + if (data & 0x80) + dsp->sb_freq = 795500UL / (256ul - data); + else + dsp->sb_freq = 397700UL / (128ul - data); + temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_timei = dsp->sb_timeo; + break; + } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ sb_ess_update_reg_a2(dsp, data); break; @@ -909,7 +932,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * 01=Stereo * 10=Mono * 11=Reserved */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 0x3) { if (dsp->sb_16_enable || dsp->sb_8_enable) { @@ -926,45 +949,44 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) } break; - case 0xB1: /* Legacy Audio Interrupt Control */ + case 0xB1: /* Legacy Audio Interrupt Control */ ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable - switch (data & 0x0C) - { - case 0x00: - dsp->sb_irqnum = 2; - break; - case 0x04: - dsp->sb_irqnum = 5; - break; - case 0x08: - dsp->sb_irqnum = 7; - break; - case 0x0C: - dsp->sb_irqnum = 10; - break; + switch (data & 0x0C) { + case 0x00: + dsp->sb_irqnum = 2; + break; + case 0x04: + dsp->sb_irqnum = 5; + break; + case 0x08: + dsp->sb_irqnum = 7; + break; + case 0x0C: + dsp->sb_irqnum = 10; + break; } sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable - switch (data & 0x0C) - { - case 0x00: - dsp->sb_8_dmanum = -1; - break; - case 0x04: - dsp->sb_8_dmanum = 0; - break; - case 0x08: - dsp->sb_8_dmanum = 1; - break; - case 0x0C: - dsp->sb_8_dmanum = 3; - break; + switch (data & 0x0C) { + case 0x00: + dsp->sb_8_dmanum = -1; + break; + case 0x04: + dsp->sb_8_dmanum = 0; + break; + case 0x08: + dsp->sb_8_dmanum = 1; + break; + case 0x0C: + dsp->sb_8_dmanum = 3; + break; } sb_ess_update_irq_drq_readback_regs(dsp, false); - if (chg & 0x40) sb_ess_update_dma_status(dsp); + if (chg & 0x40) + sb_ess_update_dma_status(dsp); break; case 0xB5: /* DAC Direct Access Holding (low) */ case 0xB6: /* DAC Direct Access Holding (high) */ @@ -980,7 +1002,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * bit 2 FIFO 16-bit mode 1=Data is 16-bit * bit 1 Reserved Always write 0 * bit 0 Generate load signal */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 4) @@ -1004,7 +1026,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * 0=first DMA is write (for DAC) * bit 0 DMA xfer enable 1=DMA is allowed to proceed */ data &= 0xF; - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 1) { @@ -1017,20 +1039,18 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->ess_reload_len = 1; } - if (chg & 0x4) - { - if (dsp->sb_16_enable) - { + if (chg & 0x4) { + if (dsp->sb_16_enable) { dsp->sb_16_autoinit = (ESSreg(0xB8) & 0x4) != 0; } - if (dsp->sb_8_enable) - { + if (dsp->sb_8_enable) { dsp->sb_8_autoinit = (ESSreg(0xB8) & 0x4) != 0; } } if (chg & 0xB) { - if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ + if (chg & 0xA) + sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); } break; @@ -1044,7 +1064,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: - sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); + sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n", reg, data); break; } } @@ -1059,8 +1079,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) - { + if (dsp->sb_type >= SB16) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } @@ -1068,27 +1087,17 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; - } - else if (dsp->sb_command == 0xC2) - { + } else if (dsp->sb_command == 0xC2) { sb_ess_write_reg(dsp, 0xC3, dsp->sb_data[0]); - } - else if (dsp->sb_command == 0xC3) - { + } else if (dsp->sb_command == 0xC3) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); - } - else if (dsp->sb_command == 0xCE) - { + } else if (dsp->sb_command == 0xCE) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xCF)); - } - else if (dsp->sb_command == 0xCF) - { + } else if (dsp->sb_command == 0xCF) { sb_ess_write_reg(dsp, 0xCF, dsp->sb_data[0]); - } - else if (dsp->sb_command == 0xC0) { + } else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); - } - else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); } return; @@ -1216,8 +1225,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x17) - { + if (dsp->sb_command == 0x17) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1330,11 +1338,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_4 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1344,11 +1350,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x67: /* 3-bit ESPCM output with reference */ case 0x66: /* 3-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_3 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1358,11 +1362,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x6D: /* 1-bit ESPCM output with reference */ case 0x6C: /* 1-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_1 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1372,11 +1374,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x6F: /* 4-bit ESPCM input with reference */ case 0x6E: /* 4-bit ESPCM input */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_4E - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1394,8 +1394,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x75) - { + if (dsp->sb_command == 0x75) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1409,8 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x77) - { + if (dsp->sb_command == 0x77) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1561,9 +1559,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xE1: /* Get DSP version */ if (IS_ESS(dsp)) { - sb_add_data(dsp, 0x3); - sb_add_data(dsp, 0x1); - break; + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + break; } if (IS_AZTECH(dsp)) { if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { @@ -1603,17 +1601,17 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ if (IS_ESS(dsp)) { switch (dsp->sb_subtype) { - default: - break; - case SB_SUBTYPE_ESS_ES688: - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); - break; - case SB_SUBTYPE_ESS_ES1688: - // Determined via Windows driver debugging. - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x09); - break; + default: + break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; + case SB_SUBTYPE_ESS_ES1688: + // Determined via Windows driver debugging. + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x09); + break; } } break; @@ -1623,8 +1621,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); if (IS_ESS(dsp)) { - if (!timer_is_enabled(&dsp->irq_timer)) - { + if (!timer_is_enabled(&dsp->irq_timer)) { timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); } } else { @@ -1685,7 +1682,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; - //pclog("sb: port write %03x %02x\n", a, v); + // pclog("sb: port write %03x %02x\n", a, v); switch (a & 0xF) { case 6: /* Reset */ @@ -1697,14 +1694,13 @@ sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; } - if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) - { + if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); } dsp->espcm_fifo_reset = v; - dsp->uart_midi = 0; - dsp->uart_irq = 0; - dsp->onebyte_midi = 0; + dsp->uart_midi = 0; + dsp->uart_irq = 0; + dsp->onebyte_midi = 0; return; case 0xC: /* Command/data write */ if (dsp->uart_midi || dsp->onebyte_midi) { @@ -1732,23 +1728,18 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } - if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) - { - if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) - { + if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) { + if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) { + sb_commands[dsp->sb_command] = 2; + } else { sb_commands[dsp->sb_command] = 2; } - else - { - sb_commands[dsp->sb_command] = 2; - } - } - else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + } else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 - || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { + || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1780,11 +1771,9 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) - { + if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ - if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) - { + if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) { a &= 0xfffe; } } @@ -1807,19 +1796,18 @@ sb_read(uint16_t a, void *priv) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); } - uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; - uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; // Unimplemented - uint8_t fifo_empty = 0; - uint8_t fifo_half = 0; + uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + uint8_t fifo_full = 0; // Unimplemented + uint8_t fifo_empty = 0; + uint8_t fifo_half = 0; uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; // Unimplemented - uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; @@ -1856,8 +1844,7 @@ sb_read(uint16_t a, void *priv) } break; case 0xF: /* 16-bit ack */ - if (!IS_ESS(dsp)) - { + if (!IS_ESS(dsp)) { dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -1869,8 +1856,8 @@ sb_read(uint16_t a, void *priv) default: break; } - - //pclog("sb: port read %03x %02x\n", a, ret); + + // pclog("sb: port read %03x %02x\n", a, ret); return ret; } @@ -2068,16 +2055,13 @@ sb_ess_finish_dma(sb_dsp_t *dsp) void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { - if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) - { - while (!fifo_get_full(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) { + while (!fifo_get_full(dsp->espcm_fifo)) { int32_t val; val = dsp->dma_readb(dsp->dma_priv); dsp->ess_dma_counter++; fifo_write(val & 0xff, dsp->espcm_fifo); - if (val & DMA_OVER) - { + if (val & DMA_OVER) { break; } } @@ -2098,8 +2082,7 @@ pollsb(void *priv) switch (dsp->sb_8_format) { case 0x00: /* Mono unsigned */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); /* Needed to prevent clicking in Worms, which programs the DSP to auto-init DMA but programs the DMA controller to single cycle */ @@ -2108,7 +2091,7 @@ pollsb(void *priv) dsp->sbdat = (data[0] ^ 0x80) << 8; if (dsp->stereo) { sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2121,15 +2104,14 @@ pollsb(void *priv) } break; case 0x10: /* Mono signed */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); if (data[0] == DMA_NODATA) break; dsp->sbdat = data[0] << 8; if (dsp->stereo) { sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); + dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2142,8 +2124,7 @@ pollsb(void *priv) } break; case 0x20: /* Stereo unsigned */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) @@ -2155,8 +2136,7 @@ pollsb(void *priv) } break; case 0x30: /* Stereo signed */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) @@ -2169,8 +2149,7 @@ pollsb(void *priv) break; case ADPCM_4: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { if (dsp->sbdacpos) tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; else @@ -2202,7 +2181,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2214,8 +2193,7 @@ pollsb(void *priv) break; case ADPCM_26: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { if (!dsp->sbdacpos) tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; else if (dsp->sbdacpos == 1) @@ -2249,7 +2227,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2261,8 +2239,7 @@ pollsb(void *priv) break; case ADPCM_2: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; if (tempi < 0) tempi = 0; @@ -2290,7 +2267,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2302,97 +2279,77 @@ pollsb(void *priv) break; case ESPCM_4: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; - tempi = dsp->espcm_byte_buffer[0] >> 4; - } - else if (dsp->espcm_sample_idx & 1) - { + tempi = dsp->espcm_byte_buffer[0] >> 4; + } else if (dsp->espcm_sample_idx & 1) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; tempi = dsp->espcm_byte_buffer[0] & 0x0F; - } - else - { + } else { tempi = dsp->espcm_byte_buffer[0] >> 4; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; case ESPCM_3: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); - dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; - tempi = dsp->espcm_byte_buffer[0] >> 4; + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; dsp->espcm_last_value = tempi; - } - else if (dsp->espcm_sample_idx == 1) - { - for (tempi = 0; tempi < 4; tempi++) - { + } else if (dsp->espcm_sample_idx == 1) { + for (tempi = 0; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) - { + if (tempi < 4) { break; } @@ -2409,24 +2366,19 @@ pollsb(void *priv) dsp->espcm_code_buffer[8] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; dsp->espcm_code_buffer[9] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; - tempi = espcm3_dpcm_tables[tempi]; + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - } - else if (dsp->espcm_sample_idx == 11) - { - for (tempi = 1; tempi < 4; tempi++) - { + } else if (dsp->espcm_sample_idx == 11) { + for (tempi = 1; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) - { + if (tempi < 4) { break; } @@ -2439,53 +2391,44 @@ pollsb(void *priv) dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; dsp->espcm_code_buffer[7] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; - tempi = espcm3_dpcm_tables[tempi]; + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - } - else - { - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; - tempi = espcm3_dpcm_tables[tempi]; + } else { + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; case ESPCM_1: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); @@ -2494,12 +2437,9 @@ pollsb(void *priv) dsp->espcm_byte_buffer[0] >>= 5; tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } - else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) - { + } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); @@ -2507,35 +2447,29 @@ pollsb(void *priv) tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } - else - { + } else { tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; @@ -2544,7 +2478,6 @@ pollsb(void *priv) break; } - if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; @@ -2556,23 +2489,19 @@ pollsb(void *priv) sb_irq(dsp, 1); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_8_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2634,23 +2563,19 @@ pollsb(void *priv) sb_irq(dsp, 0); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_16_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2714,60 +2639,47 @@ sb_poll_i(void *priv) dsp->espcm_sample_idx++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; - if (dsp->espcm_sample_idx >= 19) - { - int i, bit, table_addr, sigma, last_sigma; - int8_t min_sample = 127, max_sample = -128, s; + if (dsp->espcm_sample_idx >= 19) { + int i, bit, table_addr, sigma, last_sigma; + int8_t min_sample = 127, max_sample = -128, s; uint8_t b; - for (i = 0; i < 19; i++) - { + for (i = 0; i < 19; i++) { s = dsp->espcm_sample_buffer[i]; - if (s < min_sample) - { + if (s < min_sample) { min_sample = s; } - if (s > max_sample) - { + if (s > max_sample) { max_sample = s; } } - if (min_sample < 0) - { + if (min_sample < 0) { min_sample = -min_sample; } - if (max_sample < 0) - { + if (max_sample < 0) { max_sample = -max_sample; } - if (min_sample > max_sample) - { + if (min_sample > max_sample) { max_sample = min_sample; } - for (table_addr = 15; table_addr < 256; table_addr += 16) - { - if (max_sample <= espcm_range_map[table_addr]) - { + for (table_addr = 15; table_addr < 256; table_addr += 16) { + if (max_sample <= espcm_range_map[table_addr]) { break; } } dsp->espcm_range = table_addr >> 4; - for (i = 0; i < 19; i++) - { + for (i = 0; i < 19; i++) { table_addr = dsp->espcm_range << 4; last_sigma = 9999; - s = dsp->espcm_sample_buffer[i]; - for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) - { + s = dsp->espcm_sample_buffer[i]; + for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) { sigma = espcm_range_map[table_addr] - s; - if (sigma < 0) - { + if (sigma < 0) { sigma = -sigma; } - if (sigma > last_sigma) - { + if (sigma > last_sigma) { break; } last_sigma = sigma; @@ -2781,8 +2693,7 @@ sb_poll_i(void *priv) dsp->sb_8_length--; dsp->ess_dma_counter++; - for (i = 1; i < 10; i++) - { + for (i = 1; i < 10; i++) { b = dsp->espcm_code_buffer[i * 2 - 1] | (dsp->espcm_code_buffer[i * 2] << 4); dsp->dma_writeb(dsp->dma_priv, b); dsp->sb_8_length--; @@ -2807,23 +2718,19 @@ sb_poll_i(void *priv) sb_irq(dsp, 1); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_8_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2881,23 +2788,19 @@ sb_poll_i(void *priv) sb_irq(dsp, 0); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_16_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } From d846a168260ef0b55e2450b7612d244753a43751 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:36:56 -0300 Subject: [PATCH 352/690] Cleanup: some touch-ups here and there --- src/sound/snd_ess.c | 6 +++-- src/sound/snd_sb_dsp.c | 57 ++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 38610c6ee..0239506bd 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -49,6 +49,8 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +# define sb_log(fmt, ...) + // clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 @@ -302,7 +304,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - // pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -373,7 +375,7 @@ ess_mixer_read(uint16_t addr, void *priv) } default: - // pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 5290d6bc5..aae7dd458 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -35,7 +35,7 @@ #define ESPCM_4 4 #define ESPCM_3 5 #define ESPCM_1 7 -#define ESPCM_4E 8 // for encoding mode switching +#define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -687,8 +687,9 @@ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -722,8 +723,9 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_ch = dsp->sb_16_dmanum; + + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; @@ -793,7 +795,6 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { - uint8_t t = 0x00; sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; @@ -805,7 +806,6 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { - uint8_t t = 0x00; sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; @@ -881,8 +881,6 @@ sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) default: return ESSreg(reg); } - - return 0xFF; } static void @@ -907,7 +905,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 397700UL / (128ul - data); temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; - dsp->sb_timei = dsp->sb_timeo; + + dsp->sb_timei = dsp->sb_timeo; break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -1305,7 +1304,6 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1339,8 +1337,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_4 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1351,8 +1348,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x67: /* 3-bit ESPCM output with reference */ case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_3 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_3 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1363,8 +1359,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6D: /* 1-bit ESPCM output with reference */ case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_1 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_1 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1375,14 +1370,12 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6F: /* 4-bit ESPCM input with reference */ case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4E - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_4E || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } dsp->espcm_mode = ESPCM_4E; sb_start_dma_i(dsp, 1, 0, ESPCM_4E, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; } break; case 0x75: /* 4-bit ADPCM output with reference */ @@ -1598,7 +1591,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; - case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ + case 0xE7: /* ESS detect/read config on ESS cards */ if (IS_ESS(dsp)) { switch (dsp->sb_subtype) { default: @@ -1682,8 +1675,6 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; - // pclog("sb: port write %03x %02x\n", a, v); - switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -1729,17 +1720,16 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = 2; } if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) { - if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) { - sb_commands[dsp->sb_command] = 2; - } else { - sb_commands[dsp->sb_command] = 2; - } + sb_commands[dsp->sb_command] = 2; } else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 + if (dsp->sb_command <= 0xC0 + || dsp->sb_command == 0xC2 || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; - } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 - || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { + } else if (dsp->sb_command == 0xC3 + || dsp->sb_command == 0xC6 + || dsp->sb_command == 0xC7 + || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1809,8 +1799,7 @@ sb_read(uint16_t a, void *priv) uint8_t irq_fifohe = 0; // Unimplemented uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; - return busy_flag | data_rdy | fifo_full | fifo_empty - | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; } if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); @@ -1857,8 +1846,6 @@ sb_read(uint16_t a, void *priv) break; } - // pclog("sb: port read %03x %02x\n", a, ret); - return ret; } From eb6f4c1118191b232da802dac98a9984bb6a4093 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:49:02 -0300 Subject: [PATCH 353/690] Fixing compiler warning about parentheses --- src/sound/snd_sb_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index aae7dd458..ad6209fb5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2424,7 +2424,7 @@ pollsb(void *priv) dsp->espcm_byte_buffer[0] >>= 5; tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { + } else if ((dsp->espcm_sample_idx == 3) | (dsp->espcm_sample_idx == 11)) { sb_espcm_fifoctl_run(dsp); if (fifo_get_empty(dsp->espcm_fifo)) { break; From 922a403eb33a580010aee091f93788d4a4a5f388 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 00:52:05 -0300 Subject: [PATCH 354/690] Cleanup: get rid of snd_ess.c; move ess to snd_sb.c/.h --- src/include/86box/snd_sb.h | 57 +++- src/sound/CMakeLists.txt | 2 +- src/sound/snd_ess.c | 661 ------------------------------------- src/sound/snd_sb.c | 536 ++++++++++++++++++++++++++++++ 4 files changed, 585 insertions(+), 671 deletions(-) delete mode 100644 src/sound/snd_ess.c diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index f236c284a..1ab94c9e1 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -105,15 +105,13 @@ typedef struct sb_ct1745_mixer_t { int input_selector_left; int input_selector_right; -#define INPUT_MIC 1 -#define INPUT_CD_R 2 -#define INPUT_CD_L 4 -#define INPUT_LINE_R 8 -#define INPUT_LINE_L 16 -#define INPUT_MIDI_R 32 -#define INPUT_MIDI_L 64 -#define INPUT_MIXER_L 128 -#define INPUT_MIXER_R 256 +#define INPUT_MIC 1 +#define INPUT_CD_R 2 +#define INPUT_CD_L 4 +#define INPUT_LINE_R 8 +#define INPUT_LINE_L 16 +#define INPUT_MIDI_R 32 +#define INPUT_MIDI_L 64 int mic_agc; @@ -128,6 +126,42 @@ typedef struct sb_ct1745_mixer_t { int output_filter; /* for clones */ } sb_ct1745_mixer_t; +/* ESS AudioDrive */ +typedef struct ess_mixer_t { + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; + double mic_l; + double mic_r; + double auxb_l; + double auxb_r; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + /* extra values for input selector */ + #define INPUT_MIXER_L 128 + #define INPUT_MIXER_R 256 + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; + + uint8_t ess_id_str[4]; + uint8_t ess_id_str_pos; +} ess_mixer_t; + typedef struct sb_t { uint8_t cms_enabled; uint8_t opl_enabled; @@ -140,6 +174,7 @@ typedef struct sb_t { sb_ct1335_mixer_t mixer_sb2; sb_ct1345_mixer_t mixer_sbpro; sb_ct1745_mixer_t mixer_sb16; + ess_mixer_t mixer_ess; }; mpu_t *mpu; emu8k_t emu8k; @@ -165,6 +200,10 @@ extern void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv); extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv); extern void sb_ct1745_mixer_reset(sb_t *sb); +extern void sb_ess_mixer_write(uint16_t addr, uint8_t val, void *priv); +extern uint8_t sb_ess_mixer_read(uint16_t addr, void *priv); +extern void sb_ess_mixer_reset(sb_t *sb); + extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv); diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 9206f6be9..9b2cc1416 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c snd_ess.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c deleted file mode 100644 index 0239506bd..000000000 --- a/src/sound/snd_ess.c +++ /dev/null @@ -1,661 +0,0 @@ -/* - * 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. - * - * ESS AudioDrive emulation. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * Cacodemon345, - * Kagamiin~, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2024 Cacodemon345 - * Copyright 2024 Kagamiin~ - */ - -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H - -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/filters.h> -#include <86box/gameport.h> -#include <86box/hdc.h> -#include <86box/isapnp.h> -#include <86box/hdc_ide.h> -#include <86box/io.h> -#include <86box/mca.h> -#include <86box/mem.h> -#include <86box/midi.h> -#include <86box/pic.h> -#include <86box/rom.h> -#include <86box/sound.h> -#include <86box/timer.h> -#include <86box/snd_sb.h> -#include <86box/plat_unused.h> - -# define sb_log(fmt, ...) - -// clang-format off -static const double sb_att_4dbstep_3bits[] = { - 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 -}; - -static const double sb_att_7dbstep_2bits[] = { - 164.0, 6537.0, 14637.0, 32767.0 -}; - -/* Attenuation table for 4-bit microphone volume. - * The last step is a jump to -48 dB. */ -static const double sb_att_1p4dbstep_4bits[] = { - 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, - 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 -}; - -/* Attenuation table for 4-bit mixer volume. - * The last step is a jump to -48 dB. */ -static const double sb_att_2dbstep_4bits[] = { - 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, - 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 -}; -// clang-format on - -/* SB PRO */ -typedef struct ess_mixer_t { - double master_l; - double master_r; - double voice_l; - double voice_r; - double fm_l; - double fm_r; - double cd_l; - double cd_r; - double line_l; - double line_r; - double mic_l; - double mic_r; - double auxb_l; - double auxb_r; - /*see sb_ct1745_mixer for values for input selector*/ - int32_t input_selector; - - int input_filter; - int in_filter_freq; - int output_filter; - - int stereo; - int stereo_isleft; - - uint8_t index; - uint8_t regs[256]; - - uint8_t ess_id_str[4]; - uint8_t ess_id_str_pos; -} ess_mixer_t; - -typedef struct ess_t { - uint8_t mixer_enabled; - fm_drv_t opl; - sb_dsp_t dsp; - ess_mixer_t mixer_sbpro; - - mpu_t *mpu; - void *gameport; - - uint16_t gameport_addr; - - void *opl_mixer; - void (*opl_mix)(void *, double *, double *); -} ess_t; - -static double -ess_mixer_get_vol_4bit(uint8_t vol) -{ - return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; -} - -void -ess_mixer_write(uint16_t addr, uint8_t val, void *priv) -{ - ess_t *ess = (ess_t *) priv; - ess_mixer_t *mixer = &ess->mixer_sbpro; - - if (!(addr & 1)) { - mixer->index = val; - mixer->regs[0x01] = val; - if (val == 0x40) { - mixer->ess_id_str_pos = 0; - } - } else { - if (mixer->index == 0) { - /* Reset */ - mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; - mixer->regs[0x0e] = 0x00; - /* Changed default from -11dB to 0dB */ - mixer->regs[0x04] = mixer->regs[0x22] = 0xee; - mixer->regs[0x26] = mixer->regs[0x28] = 0xee; - mixer->regs[0x2e] = 0x00; - - /* Initialize ESS regs. */ - mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; - mixer->regs[0x3a] = 0x00; - mixer->regs[0x3e] = 0x00; - - sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); - } else { - mixer->regs[mixer->index] = val; - - switch (mixer->index) { - /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ - case 0x02: - case 0x06: - case 0x08: - mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); - break; - - case 0x0A: - { - uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; - mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); - break; - } - - case 0x0C: - switch (mixer->regs[0x0C] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } - break; - - case 0x14: - mixer->regs[0x4] = val & 0xee; - break; - - case 0x1A: - mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF]; - mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF]; - break; - - case 0x1C: - if ((mixer->regs[0x1C] & 0x07) == 0x07) { - mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; - } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - } else if ((mixer->regs[0x1C] & 0x02) == 0) { - mixer->input_selector = INPUT_MIC; - } - break; - - case 0x22: - case 0x26: - case 0x28: - case 0x2E: - mixer->regs[mixer->index - 0x20] = (val & 0xe); - mixer->regs[mixer->index + 0x10] = val; - break; - - /* More compatibility: - SoundBlaster Pro selects register 020h for 030h, 022h for 032h, - 026h for 036h, and 028h for 038h. */ - case 0x30: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; - - case 0x3a: - break; - - case 0x00: - case 0x04: - break; - - case 0x0e: - break; - - case 0x64: - mixer->regs[mixer->index] &= ~0x8; - break; - - case 0x40: - { - uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - - if (0) { - /* Not on ES1688. */ - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - } - } - switch ((mixer->regs[0x40] >> 5) & 0x7) { - case 0: - mpu401_change_addr(ess->mpu, 0x00); - mpu401_setirq(ess->mpu, -1); - break; - case 1: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, -1); - break; - case 2: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); - break; - case 3: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 11); - break; - case 4: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 9); - break; - case 5: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 5); - break; - case 6: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 7); - break; - case 7: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 10); - break; - } - break; - } - - default: - sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } - - mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); - mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14]); - mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); - mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32]); - mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); - mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36]); - mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); - mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38]); - mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); - mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); - mixer->auxb_l = ess_mixer_get_vol_4bit(mixer->regs[0x3a] >> 4); - mixer->auxb_r = ess_mixer_get_vol_4bit(mixer->regs[0x3a]); - - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&ess->dsp, val & 2); - - /* TODO: pcspeaker volume? Or is it not worth? */ - } -} - -uint8_t -ess_mixer_read(uint16_t addr, void *priv) -{ - ess_t *ess = (ess_t *) priv; - ess_mixer_t *mixer = &ess->mixer_sbpro; - - if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) { - case 0x00: - case 0x04: - case 0x0a: - case 0x0c: - case 0x0e: - case 0x14: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: - case 0x02: - case 0x06: - case 0x30: - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - return mixer->regs[mixer->index]; - - case 0x40: - - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - mixer->ess_id_str_pos++; - if (mixer->ess_id_str_pos >= 4) - mixer->ess_id_str_pos = 0; - return val; - } else { - return mixer->regs[mixer->index]; - } - - default: - sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0x0a; -} - -void -ess_mixer_reset(ess_t *ess) -{ - ess_mixer_write(4, 0, ess); - ess_mixer_write(5, 0, ess); -} - -void -ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) -{ - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - - sb_dsp_update(&ess->dsp); - - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ - if (mixer->output_filter) { - out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; - out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; - } else { - out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; - out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; - } - - /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ - out_l *= mixer->master_l; - out_r *= mixer->master_r; - - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; - } - - ess->dsp.pos = 0; -} - -void -ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) -{ - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; - - opl_buf = ess->opl.update(ess->opl.priv); - - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (ess->opl_mix && ess->opl_mixer) - ess->opl_mix(ess->opl_mixer, &out_l, &out_r); - } - - /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ - out_l *= mixer->master_l; - out_r *= mixer->master_r; - - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; - } - - ess->opl.reset_buffer(ess->opl.priv); -} - -void -ess_filter_cd_audio(int channel, double *buffer, void *priv) -{ - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; - - c = (*buffer * cd) / 3.0; - *buffer = c * master; -} - -static void * -ess_1688_init(UNUSED(const device_t *info)) -{ - /* SB Pro 2 port mappings, 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = calloc(sizeof(ess_t), 1); - uint16_t addr = device_get_config_hex16("base"); - - fm_driver_get(FM_ESFM, &ess->opl); - - sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); - sb_dsp_setaddr(&ess->dsp, addr); - sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); - sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); - sb_dsp_setdma16_supported(&ess->dsp, 0); - ess_mixer_reset(ess); - - /* DSP I/O handler is activated in sb_dsp_setaddr */ - { - io_sethandler(addr, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - io_sethandler(addr + 8, 0x0002, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - } - - ess->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, - ess_mixer_read, NULL, NULL, - ess_mixer_write, NULL, NULL, - ess); - sound_add_handler(ess_get_buffer_sbpro, ess); - music_add_handler(ess_get_music_buffer_sbpro, ess); - sound_set_cd_audio_filter(ess_filter_cd_audio, ess); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); - { - ess->mixer_sbpro.ess_id_str[0] = 0x16; - ess->mixer_sbpro.ess_id_str[1] = 0x88; - ess->mixer_sbpro.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; - } - - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - mpu401_init(ess->mpu, 0, -1, M_UART, 1); - sb_dsp_set_mpu(&ess->dsp, ess->mpu); - - ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x200; - gameport_remap(ess->gameport, ess->gameport_addr); - - return ess; -} - -void -ess_close(void *priv) -{ - ess_t *ess = (ess_t *) priv; - sb_dsp_close(&ess->dsp); - - free(ess); -} - -void -ess_speed_changed(void *priv) -{ - ess_t *ess = (ess_t *) priv; - - sb_dsp_speed_changed(&ess->dsp); -} - -// clang-format off -static const device_config_t ess_config[] = { - { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { .description = "" } - } - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } - }, - { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t ess_1688_device = { - .name = "ESS Technology ES1688", - .internal_name = "ess_es1688", - .flags = DEVICE_ISA, - .local = 0, - .init = ess_1688_init, - .close = ess_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = ess_speed_changed, - .force_redraw = NULL, - .config = ess_config -}; diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2365419b1..1489cb769 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -75,6 +75,20 @@ static const double sb_att_4dbstep_3bits[] = { static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; + +/* Attenuation table for ESS 4-bit microphone volume. + * The last step is a jump to -48 dB. */ +static const double sb_att_1p4dbstep_4bits[] = { + 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, + 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 +}; + +/* Attenuation table for ESS 4-bit mixer volume. + * The last step is a jump to -48 dB. */ +static const double sb_att_2dbstep_4bits[] = { + 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; // clang-format on static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; @@ -667,6 +681,87 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) *buffer = c * output_gain; } +void +ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double out_l = 0.0; + double out_r = 0.0; + + sb_dsp_update(&ess->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_filter) { + out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; + out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; + } else { + out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + } + + /* TODO: recording from the mixer. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->dsp.pos = 0; +} + +void +ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + + opl_buf = ess->opl.update(ess->opl.priv); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording from the mixer. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->opl.reset_buffer(ess->opl.priv); +} + +void +ess_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; + + /* TODO: recording from the mixer. */ + c = (*buffer * cd) / 3.0; + *buffer = c * master; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -1304,6 +1399,265 @@ sb_ct1745_mixer_reset(sb_t *sb) sb_ct1745_mixer_write(5, 0, sb); } +void +ess_mixer_write(uint16_t addr, uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + ess_mixer_t *mixer = &ess->mixer_ess; + + if (!(addr & 1)) { + mixer->index = val; + mixer->regs[0x01] = val; + if (val == 0x40) { + mixer->ess_id_str_pos = 0; + } + } else { + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; + mixer->regs[0x0e] = 0x00; + /* Changed default from -11dB to 0dB */ + mixer->regs[0x04] = mixer->regs[0x22] = 0xee; + mixer->regs[0x26] = mixer->regs[0x28] = 0xee; + mixer->regs[0x2e] = 0x00; + + /* Initialize ESS regs. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0x88; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x88; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; + + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); + } else { + mixer->regs[mixer->index] = val; + + switch (mixer->index) { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: + case 0x06: + case 0x08: + mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); + break; + + case 0x0A: + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32767.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); + break; + } + + case 0x0C: + switch (mixer->regs[0x0C] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + break; + + case 0x14: + mixer->regs[0x4] = val & 0xee; + break; + + case 0x1A: + mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF] / 32767.0; + mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF] / 32767.0; + break; + + case 0x1C: + if ((mixer->regs[0x1C] & 0x07) == 0x07) { + mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; + } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + } else if ((mixer->regs[0x1C] & 0x02) == 0) { + mixer->input_selector = INPUT_MIC; + } + break; + + case 0x22: + case 0x26: + case 0x28: + case 0x2E: + mixer->regs[mixer->index - 0x20] = (val & 0xe); + mixer->regs[mixer->index + 0x10] = val; + break; + + /* More compatibility: + SoundBlaster Pro selects register 020h for 030h, 022h for 032h, + 026h for 036h, and 028h for 038h. */ + case 0x30: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + case 0x32: + case 0x36: + case 0x38: + case 0x3e: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + + case 0x3a: + break; + + case 0x00: + case 0x04: + break; + + case 0x0e: + break; + + case 0x64: + mixer->regs[mixer->index] &= ~0x8; + break; + + case 0x40: + { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + + if (0) { + /* Not on ES1688. */ + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + } + switch ((mixer->regs[0x40] >> 5) & 0x7) { + case 0: + mpu401_change_addr(ess->mpu, 0x00); + mpu401_setirq(ess->mpu, -1); + break; + case 1: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 2: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); + break; + case 3: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 11); + break; + case 4: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 9); + break; + case 5: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 5); + break; + case 6: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 7); + break; + case 7: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 10); + break; + } + break; + } + + default: + sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + + mixer->voice_l = sb_att_2dbstep_4bits[(mixer->regs[0x14] >> 4) & 0x0F] / 32767.0; + mixer->voice_r = sb_att_2dbstep_4bits[mixer->regs[0x14] & 0x0F] / 32767.0; + mixer->master_l = sb_att_2dbstep_4bits[(mixer->regs[0x32] >> 4) & 0x0F] / 32767.0; + mixer->master_r = sb_att_2dbstep_4bits[mixer->regs[0x32] & 0x0F] / 32767.0; + mixer->fm_l = sb_att_2dbstep_4bits[(mixer->regs[0x36] >> 4) & 0x0F] / 32767.0; + mixer->fm_r = sb_att_2dbstep_4bits[mixer->regs[0x36] & 0x0F] / 32767.0; + mixer->cd_l = sb_att_2dbstep_4bits[(mixer->regs[0x38] >> 4) & 0x0F] / 32767.0; + mixer->cd_r = sb_att_2dbstep_4bits[mixer->regs[0x38] & 0x0F] / 32767.0; + mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; + mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; + mixer->auxb_l = sb_att_2dbstep_4bits[(mixer->regs[0x3a] >> 4) & 0x0F] / 32767.0; + mixer->auxb_r = sb_att_2dbstep_4bits[mixer->regs[0x3a] & 0x0F] / 32767.0; + + mixer->output_filter = !(mixer->regs[0xe] & 0x20); + mixer->input_filter = !(mixer->regs[0xc] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xe] & 2; + if (mixer->index == 0xe) + sb_dsp_set_stereo(&ess->dsp, val & 2); + + /* TODO: pcspeaker volume? Or is it not worth? */ + } +} + +uint8_t +ess_mixer_read(uint16_t addr, void *priv) +{ + sb_t *ess = (sb_t *) priv; + ess_mixer_t *mixer = &ess->mixer_ess; + + if (!(addr & 1)) + return mixer->index; + + switch (mixer->index) { + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x14: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + case 0x3e: + return mixer->regs[mixer->index]; + + case 0x40: + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { + uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + mixer->ess_id_str_pos++; + if (mixer->ess_id_str_pos >= 4) + mixer->ess_id_str_pos = 0; + return val; + } else { + return mixer->regs[mixer->index]; + } + + default: + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + return 0x0a; +} + +void +ess_mixer_reset(sb_t *ess) +{ + ess_mixer_write(4, 0, ess); + ess_mixer_write(5, 0, ess); +} + uint8_t sb_mcv_read(int port, void *priv) { @@ -2755,6 +3109,76 @@ sb_awe32_pnp_init(const device_t *info) return sb; } +static void * +ess_1688_init(UNUSED(const device_t *info)) +{ + /* SB Pro 2 port mappings, 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface. */ + sb_t *ess = calloc(sizeof(sb_t), 1); + uint16_t addr = device_get_config_hex16("base"); + + fm_driver_get(FM_ESFM, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_setaddr(&ess->dsp, addr); + sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + ess->mixer_enabled = 1; + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + sound_add_handler(ess_get_buffer_sbpro, ess); + music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + + if (device_get_config_int("receive_input")) { + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + } + + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, 1); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport_addr = 0x200; + gameport_remap(ess->gameport, ess->gameport_addr); + + return ess; +} + void sb_close(void *priv) { @@ -4023,6 +4447,104 @@ static const device_config_t sb_awe64_gold_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; + +static const device_config_t ess_1688_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; // clang-format on const device_t sb_1_device = { @@ -4360,3 +4882,17 @@ const device_t sb_awe64_gold_device = { .force_redraw = NULL, .config = sb_awe64_gold_config }; + +const device_t ess_1688_device = { + .name = "ESS Technology ES1688", + .internal_name = "ess_es1688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_1688_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_config +}; From eee63d7312f821631a27d88a655bef21de4fbbb8 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 00:58:31 -0300 Subject: [PATCH 355/690] Better function naming --- src/sound/snd_sb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 1489cb769..fc6b9c6e9 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -682,7 +682,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) } void -ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; @@ -716,7 +716,7 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) } void -ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_music_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; @@ -3153,8 +3153,8 @@ ess_1688_init(UNUSED(const device_t *info)) ess_mixer_read, NULL, NULL, ess_mixer_write, NULL, NULL, ess); - sound_add_handler(ess_get_buffer_sbpro, ess); - music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); if (device_get_config_int("receive_input")) { From 639f05d07c26e5724741eff879f1144201f49c73 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 01:09:49 -0300 Subject: [PATCH 356/690] Small fixes --- src/sound/snd_sb.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fc6b9c6e9..61dbc8c7a 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1523,7 +1523,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - if (0) { + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { /* Not on ES1688. */ io_removehandler(0x0388, 0x0004, ess->opl.read, NULL, NULL, @@ -3112,12 +3112,6 @@ sb_awe32_pnp_init(const device_t *info) static void * ess_1688_init(UNUSED(const device_t *info)) { - /* SB Pro 2 port mappings, 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface. */ sb_t *ess = calloc(sizeof(sb_t), 1); uint16_t addr = device_get_config_hex16("base"); @@ -4462,17 +4456,17 @@ static const device_config_t ess_1688_config[] = { .description = "0x220", .value = 0x220 }, + { + .description = "0x230", + .value = 0x230 + }, { .description = "0x240", .value = 0x240 }, { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 + .description = "0x250", + .value = 0x250 }, { .description = "" } } From 2466da21618ee44cd0b9f4ccf35afe1e1ae18727 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:15:34 +0100 Subject: [PATCH 357/690] Prepared the API to set the PIT constant. --- src/include/86box/pit.h | 9 ++++++ src/include/86box/pit_fast.h | 5 +++ src/pit.c | 38 ++++++++++++++++++---- src/pit_fast.c | 63 +++++++++++++++++++++++------------- src/sound/snd_pas16.c | 28 ++++++++++++++-- 5 files changed, 112 insertions(+), 31 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index d9bce667d..ed60cfa29 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -71,6 +71,9 @@ typedef struct PIT { ctr_t counters[3]; uint8_t ctrl; + + uint64_t pit_const; + void *dev_priv; } pit_t; @@ -97,6 +100,7 @@ typedef struct pit_intf_t { /* Sets a counter's load count handler. */ void (*set_load_func)(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)); void (*ctr_clock)(void *data, int counter_id); + void (*set_pit_const)(void *data, uint64_t pit_const); void *data; } pit_intf_t; @@ -108,6 +112,7 @@ extern double PCICLK; extern double AGPCLK; extern uint64_t PITCONST; +extern uint64_t PAS16CONST; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; @@ -118,6 +123,10 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; +extern void pit_change_pas16_const(double prescale); + +extern void pit_set_pit_const(void *data, uint64_t pit_const); + /* Sets a counter's CLOCK input. */ extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 845105185..2a8181a94 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -56,6 +56,9 @@ typedef struct ctrf_t { }; uint32_t l; + + uint64_t pit_const; + pc_timer_t timer; void (*load_func)(uint8_t new_m, int new_count); @@ -70,6 +73,8 @@ typedef struct pitf_t { uint8_t ctrl; } pitf_t; +extern void pitf_set_pit_const(void *data, uint64_t pit_const); + extern uint8_t pitf_read_reg(void *priv, uint8_t reg); extern const pit_intf_t pit_fast_intf; diff --git a/src/pit.c b/src/pit.c index 20baf3f66..7ab48bbd8 100644 --- a/src/pit.c +++ b/src/pit.c @@ -47,6 +47,7 @@ pit_intf_t pit_devs[2]; double cpuclock; double PITCONSTD; +double PAS16CONSTD; double SYSCLK; double isa_timing; double bus_timing; @@ -56,6 +57,7 @@ double PCICLK; double AGPCLK; uint64_t PITCONST; +uint64_t PAS16CONST; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -523,7 +525,7 @@ pit_timer_over(void *priv) for (uint8_t i = 0; i < 3; i++) pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); - timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); + timer_advance_u64(&dev->callback_timer, dev->pit_const >> 1ULL); } static void @@ -873,6 +875,20 @@ pit_handler(int set, uint16_t base, int size, void *priv) io_handler(set, base, size, pit_read, NULL, NULL, pit_write, NULL, NULL, priv); } +void +pit_set_pit_const(void *data, uint64_t pit_const) +{ + pit_t *pit = (pit_t *) data; + + pit->pit_const = pit_const; +} + +static void +pit_speed_changed(void *priv) +{ + pit_set_pit_const(priv, PITCONST); +} + static void pit_close(void *priv) { @@ -896,7 +912,7 @@ pit_init(const device_t *info) if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { timer_add(&dev->callback_timer, pit_timer_over, (void *) dev, 0); - timer_set_delay_u64(&dev->callback_timer, PITCONST >> 1ULL); + timer_set_delay_u64(&dev->callback_timer, dev->pit_const >> 1ULL); } dev->flags = info->local; @@ -919,7 +935,7 @@ const device_t i8253_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -947,7 +963,7 @@ const device_t i8254_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -961,7 +977,7 @@ const device_t i8254_sec_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -989,7 +1005,7 @@ const device_t i8254_ps2_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -1074,6 +1090,12 @@ pit_ps2_init(int type) return pit; } +void +pit_change_pas16_const(double prescale) +{ + PAS16CONST = (uint64_t) ((PITCONSTD / prescale) * (double) (1ULL << 32)); +} + void pit_set_clock(uint32_t clock) { @@ -1169,6 +1191,9 @@ pit_set_clock(uint32_t clock) TIMER_USEC = (uint64_t) ((cpuclock / 1000000.0) * (double) (1ULL << 32)); + PAS16CONSTD = (cpuclock / 441000.0); + PAS16CONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); + isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) bus_timing = (cpuclock / (cpu_busspeed / 2)); @@ -1200,5 +1225,6 @@ const pit_intf_t pit_classic_intf = { &pit_ctr_set_out_func, &pit_ctr_set_load_func, &ctr_clock, + &pit_set_pit_const, NULL, }; diff --git a/src/pit_fast.c b/src/pit_fast.c index 9c5d622ec..0a7e1db09 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -126,7 +126,7 @@ static int pitf_read_timer(ctrf_t *ctr) { if (ctr->using_timer && !(ctr->m == 3 && !ctr->gate) && timer_is_enabled(&ctr->timer)) { - int read = (int) ((timer_get_remaining_u64(&ctr->timer)) / PITCONST); + int read = (int) ((timer_get_remaining_u64(&ctr->timer)) / ctr->pit_const); if (ctr->m == 2) read++; if (read < 0) @@ -168,7 +168,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) case 0: /*Interrupt on terminal count*/ ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = ctr->gate; @@ -180,7 +180,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) if (ctr->initial) { ctr->count = l - 1; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -190,7 +190,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) if (ctr->initial) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -202,7 +202,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) else { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; } @@ -240,7 +240,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) case 0: /*Interrupt on terminal count*/ case 4: /*Software triggered stobe*/ if (ctr->using_timer && !ctr->running) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); ctr->enabled = gate; break; case 1: /*Hardware retriggerable one-shot*/ @@ -248,7 +248,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = 1; @@ -258,7 +258,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l - 1; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -268,7 +268,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -306,7 +306,7 @@ pitf_over(ctrf_t *ctr, void *priv) if (ctr->disabled) { ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); return; } @@ -318,12 +318,12 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); break; case 2: /*Rate generator*/ ctr->count += l; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); pitf_ctr_set_out(ctr, 1, pit); break; @@ -332,16 +332,16 @@ pitf_over(ctrf_t *ctr, void *priv) pitf_ctr_set_out(ctr, 0, pit); ctr->count += (l >> 1); if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * ctr->pit_const)); } else { pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); } #if 0 if (!t) - pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); + pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, ctr->pit_const); #endif break; case 4: /*Software triggered strove*/ @@ -353,12 +353,12 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->newcount = 0; ctr->count += l; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); } else { ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); } break; case 5: /*Hardware triggered strove*/ @@ -369,7 +369,7 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); break; default: @@ -659,6 +659,24 @@ pitf_reset(pitf_t *dev) dev->counters[2].gate = 0; } +void +pitf_set_pit_const(void *data, uint64_t pit_const) +{ + pitf_t *pit = (pitf_t *) data; + ctrf_t *ctr; + + for (uint8_t i = 0; i < 3; i++) { + ctr = &pit->counters[i]; + ctr->pit_const = pit_const; + } +} + +static void +pitf_speed_changed(void *priv) +{ + pitf_set_pit_const(priv, PITCONST); +} + static void pitf_close(void *priv) { @@ -707,7 +725,7 @@ const device_t i8253_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -721,7 +739,7 @@ const device_t i8254_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -735,7 +753,7 @@ const device_t i8254_sec_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -763,7 +781,7 @@ const device_t i8254_ps2_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -777,5 +795,6 @@ const pit_intf_t pit_fast_intf = { &pitf_ctr_set_out_func, &pitf_ctr_set_load_func, &pitf_ctr_clock, + &pitf_set_pit_const, NULL, }; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index d8187cf0f..45a18ff73 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -354,7 +354,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pit_t *pit = (pit_t *) pas16->pit; pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); switch (port) { case 0x388: @@ -728,6 +727,28 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) pas16->opl.reset_buffer(pas16->opl.priv); } +static void +pas16_speed_changed(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + /* TODO: In PAS16 mode: + pit_change_pas16_const(prescale); + pit_set_pit_const(pas16->pit, PAS16CONST); + */ + + pit_set_pit_const(pas16->pit, PITCONST); +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + /* TODO: Reset the entire PAS16 state here. */ + pit_set_pit_const(pas16->pit, PITCONST); +} + static void * pas16_init(UNUSED(const device_t *info)) { @@ -743,6 +764,7 @@ pas16_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->pit = device_add(&i8254_ext_io_device); + pit_set_pit_const(pas16->pit, PITCONST); pas16->pit->dev_priv = pas16; pas16->irq = 10; pas16->dma = 3; @@ -798,9 +820,9 @@ const device_t pas16_device = { .local = 0, .init = pas16_init, .close = pas16_close, - .reset = NULL, + .reset = pas16_reset, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pas16_speed_changed, .force_redraw = NULL, .config = pas16_config }; From 4884f8664cfe2c88605f6a5ed365cc4798eea898 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:18:11 +0100 Subject: [PATCH 358/690] Set PIT constant on PIT init. --- src/pit.c | 2 ++ src/pit_fast.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/pit.c b/src/pit.c index 7ab48bbd8..b41f2acc9 100644 --- a/src/pit.c +++ b/src/pit.c @@ -910,6 +910,8 @@ pit_init(const device_t *info) pit_t *dev = (pit_t *) malloc(sizeof(pit_t)); pit_reset(dev); + pit_set_pit_const(dev, PITCONST); + if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { timer_add(&dev->callback_timer, pit_timer_over, (void *) dev, 0); timer_set_delay_u64(&dev->callback_timer, dev->pit_const >> 1ULL); diff --git a/src/pit_fast.c b/src/pit_fast.c index 0a7e1db09..fa643af8a 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -696,6 +696,9 @@ static void * pitf_init(const device_t *info) { pitf_t *dev = (pitf_t *) malloc(sizeof(pitf_t)); + + pitf_set_pit_const(dev, PITCONST); + pitf_reset(dev); dev->flags = info->local; From 1d2a7e3bca1ebf519a765fcaa997a905a48e2ba9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:48:53 +0100 Subject: [PATCH 359/690] Set pit constant after PIT reset. --- src/pit.c | 1 + src/pit_fast.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pit.c b/src/pit.c index b41f2acc9..b5d402bb3 100644 --- a/src/pit.c +++ b/src/pit.c @@ -908,6 +908,7 @@ static void * pit_init(const device_t *info) { pit_t *dev = (pit_t *) malloc(sizeof(pit_t)); + pit_reset(dev); pit_set_pit_const(dev, PITCONST); diff --git a/src/pit_fast.c b/src/pit_fast.c index fa643af8a..acaa6c271 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -697,10 +697,10 @@ pitf_init(const device_t *info) { pitf_t *dev = (pitf_t *) malloc(sizeof(pitf_t)); - pitf_set_pit_const(dev, PITCONST); - pitf_reset(dev); + pitf_set_pit_const(dev, PITCONST); + dev->flags = info->local; if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { From 6c519904fd43130a3e1e53fcafa5165cfe44b9c2 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 12:22:11 -0300 Subject: [PATCH 360/690] Cleanup: miscellaneous --- src/include/86box/snd_sb.h | 1 + src/include/86box/snd_sb_dsp.h | 17 +++++------ src/sound/snd_opl_esfm.c | 11 +++---- src/sound/snd_sb.c | 52 ++++++++++++++++++---------------- src/sound/snd_sb_dsp.c | 14 ++++----- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 1ab94c9e1..b26c5f06e 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -142,6 +142,7 @@ typedef struct ess_mixer_t { double mic_r; double auxb_l; double auxb_r; + double speaker; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; /* extra values for input selector */ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f5905ccc2..a00f512a3 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -7,11 +7,10 @@ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ -#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ +#define SB_SUBTYPE_ESS_ES1688 3 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES688 || (dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ +#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -149,13 +148,15 @@ typedef struct sb_dsp_t { uint8_t ess_extended_mode; uint8_t ess_reload_len; uint32_t ess_dma_counter; - int ess_irq_generic; - int ess_irq_dmactr; - // ESPCM + /* IRQ status flags (0x22C) */ + uint8_t ess_irq_generic; + uint8_t ess_irq_dmactr; + + /* ESPCM */ fifo64_t *espcm_fifo; - int espcm_fifo_reset; - int espcm_mode; + uint8_t espcm_fifo_reset; + uint8_t espcm_mode; /* see ESPCM in "NON-PCM SAMPLE FORMATS" deflist in snd_sb_dsp.c */ uint8_t espcm_sample_idx; uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index c36ec4160..78cbec11d 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -42,7 +42,6 @@ typedef struct { int8_t flags; int8_t pad; - uint16_t port; uint8_t status; uint8_t timer_ctrl; uint16_t timer_count[2]; @@ -269,14 +268,12 @@ esfm_drv_read(uint16_t port, void *priv) static void esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) { - uint16_t p = dev->port; - - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + uint16_t p = dev->opl.addr_latch & 0x07ff; if (dev->opl.native_mode) { p -= 0x400; - p &= 0x1ff; } + p &= 0x1ff; switch (p) { case 0x002: /* Timer 1 */ @@ -304,6 +301,8 @@ esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) default: break; } + + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); } static void @@ -321,14 +320,12 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x07ff; } } else { if ((port & 0x0001) == 0x0001) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x01ff; } } } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 61dbc8c7a..f26fba1eb 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -89,6 +89,11 @@ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 }; + +/* Attenuation table for ESS 3-bit PC speaker volume. */ +static const double sb_att_3dbstep_3bits[] = { + 0.0, 4125.0, 5826.0, 8230.0, 11626.0, 16422.0, 23197.0, 32767.0 +}; // clang-format on static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; @@ -730,12 +735,10 @@ sb_get_music_buffer_ess(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (ess->opl_mix && ess->opl_mixer) - ess->opl_mix(ess->opl_mixer, &out_l, &out_r); - } + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); /* TODO: recording from the mixer. */ out_l *= mixer->master_l; @@ -1421,11 +1424,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x26] = mixer->regs[0x28] = 0xee; mixer->regs[0x2e] = 0x00; - /* Initialize ESS regs. */ - mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; + /* Initialize ESS regs + * Defaulting to 0dB instead of the standard -11dB. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0xff; + mixer->regs[0x36] = mixer->regs[0x38] = 0xff; mixer->regs[0x3a] = 0x00; + mixer->regs[0x3c] = 0x05; mixer->regs[0x3e] = 0x00; sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); @@ -1460,6 +1464,14 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->input_selector = INPUT_MIC; break; } + mixer->input_filter = !(mixer->regs[0xC] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xC] & 0x8) == 0) ? 3200 : 8800; + break; + + case 0x0E: + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->stereo = mixer->regs[0xE] & 2; + sb_dsp_set_stereo(&ess->dsp, val & 2); break; case 0x14: @@ -1495,8 +1507,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ case 0x30: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; case 0x32: case 0x36: case 0x38: @@ -1505,15 +1515,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x3a: + case 0x3c: break; case 0x00: case 0x04: break; - case 0x0e: - break; - case 0x64: mixer->regs[mixer->index] &= ~0x8; break; @@ -1587,19 +1595,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->fm_r = sb_att_2dbstep_4bits[mixer->regs[0x36] & 0x0F] / 32767.0; mixer->cd_l = sb_att_2dbstep_4bits[(mixer->regs[0x38] >> 4) & 0x0F] / 32767.0; mixer->cd_r = sb_att_2dbstep_4bits[mixer->regs[0x38] & 0x0F] / 32767.0; - mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; - mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; mixer->auxb_l = sb_att_2dbstep_4bits[(mixer->regs[0x3a] >> 4) & 0x0F] / 32767.0; mixer->auxb_r = sb_att_2dbstep_4bits[mixer->regs[0x3a] & 0x0F] / 32767.0; + mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; + mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; + mixer->speaker = sb_att_3dbstep_3bits[mixer->regs[0x3c] & 0x07] / 32767.0; - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&ess->dsp, val & 2); - - /* TODO: pcspeaker volume? Or is it not worth? */ + /* TODO: PC Speaker volume */ } } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ad6209fb5..332299c4f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -29,11 +29,13 @@ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +/* NON-PCM SAMPLE FORMATS */ #define ADPCM_4 1 #define ADPCM_26 2 #define ADPCM_2 3 #define ESPCM_4 4 #define ESPCM_3 5 +/* ESPCM_2? */ #define ESPCM_1 7 #define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes @@ -1596,10 +1598,6 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; - case SB_SUBTYPE_ESS_ES688: - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); - break; case SB_SUBTYPE_ESS_ES1688: // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); @@ -1792,11 +1790,11 @@ sb_read(uint16_t a, void *priv) } uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; // Unimplemented - uint8_t fifo_empty = 0; - uint8_t fifo_half = 0; + uint8_t fifo_full = 0; /* Unimplemented */ + uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ + uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; From 0af83efb8f5e7f6c919d2f9b7a4dc7c02e074b16 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 12:47:41 -0300 Subject: [PATCH 361/690] Correcting device name --- src/sound/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index f26fba1eb..13baa3621 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -4880,7 +4880,7 @@ const device_t sb_awe64_gold_device = { }; const device_t ess_1688_device = { - .name = "ESS Technology ES1688", + .name = "ESS AudioDrive ES1688", .internal_name = "ess_es1688", .flags = DEVICE_ISA, .local = 0, From f45fe7b1212a421da808d8bbc7d705cea6cbc8ab Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 17:19:33 +0100 Subject: [PATCH 362/690] Bump version to 4.2. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11265d09a..5bafadcc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.1.1 + VERSION 4.2 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 00179d466..fe8aa6821 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.1.1) UNRELEASED; urgency=medium +86box (4.2) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Fri, 23 Feb 2024 07:23:12 +0100 + -- Jasmine Iwanek Sat, 23 Mar 2024 17:19:08 +0100 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 99d01c594..fdd7bbf55 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 4.1.1 +Version: 4.2 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Fri Feb 23 2024 Robert de Rooy 4.1.1-1 +* Sat Mar 23 2024 Robert de Rooy 4.2-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 1f15f39a5..18df49703 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/vcpkg.json b/vcpkg.json index d7d7ffd82..d9ea83dba 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.1.1", + "version-string": "4.2", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From f63cc093e12482136a2b3eeb2416ceeaef05a050 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 17:22:36 +0100 Subject: [PATCH 363/690] net_modem and sb_dsp: Warning fixes. --- src/network/net_modem.c | 4 ---- src/sound/snd_sb_dsp.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b1b6a2eca..082874f54 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -141,8 +141,6 @@ typedef struct modem_t netcard_t *card; } modem_t; -static modem_t *instance; - #define MREG_AUTOANSWER_COUNT 0 #define MREG_RING_COUNT 1 #define MREG_ESCAPE_CHAR 2 @@ -576,7 +574,6 @@ modem_dial(modem_t* modem, const char* str) else { char buf[128] = ""; - const char *destination = buf; strcpy(buf, str); // Scan host for port uint16_t port; @@ -1106,7 +1103,6 @@ modem_rx(void *priv, uint8_t *buf, int io_len) { #if 1 modem_t* modem = (modem_t*)priv; - uint8_t c = 0; uint32_t i = 0; if (modem->tcpIpMode) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 332299c4f..927a06d8c 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2625,7 +2625,7 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; if (dsp->espcm_sample_idx >= 19) { - int i, bit, table_addr, sigma, last_sigma; + int i, table_addr, sigma, last_sigma; int8_t min_sample = 127, max_sample = -128, s; uint8_t b; From 50a2a479c158c85575b2e93513e5d1c33193db1f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sat, 23 Mar 2024 16:15:35 -0400 Subject: [PATCH 364/690] Revert earlier change to zip_load to fix an image load crash --- src/disk/zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index d4b644865..7045b1e41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -531,7 +531,7 @@ zip_load(zip_t *dev, char *fn) if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("zip_load(): Error seeking to the beginning of the file\n"); - strncpy(dev->drv->image_path, fn, strlen(dev->drv->image_path) + 1); + strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); return 1; } From e5fe2dd1fa017c99a68624a9fa3cca7849123717 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 24 Mar 2024 01:50:39 +0500 Subject: [PATCH 365/690] CI, workflows: Add vulkan-headers for MSYS2 --- .ci/dependencies_msys.txt | 1 + .github/workflows/cmake_windows_msys2.yml | 3 +-- .github/workflows/codeql_windows_msys2.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index 22601b643..694fe3e28 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -12,3 +12,4 @@ libslirp fluidsynth qt5-static qt5-translations +vulkan-headers diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index c7d77307c..c4cebaee3 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -63,8 +63,7 @@ jobs: slug: -Qt packages: >- qt5-static:p -# qt5-base:p -# qt5-tools:p + vulkan-headers:p environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index dda14a182..da368cd68 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -68,6 +68,7 @@ jobs: packages: >- qt5-base:p qt5-tools:p + vulkan-headers:p environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake From f267a2f12a8ca62a28025980e397afac7a1c2dcc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 24 Mar 2024 02:20:53 +0500 Subject: [PATCH 366/690] workflows: Remove the defunct legacy Makefile workflow --- .github/workflows/c-cpp.yml | 115 ------------------------------------ 1 file changed, 115 deletions(-) delete mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml deleted file mode 100644 index fd81701a7..000000000 --- a/.github/workflows/c-cpp.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: MSYS2 Makefile (Windows, Legacy) - -on: - - push: - paths: - - src/** - - .github/workflows/c-cpp.yml - - "!**/CMakeLists.txt" - - pull_request: - paths: - - src/** - - .github/workflows/c-cpp.yml - - "!**/CMakeLists.txt" - -jobs: - msys2: - # Negative condition disables the job - if: false - name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" - - runs-on: windows-2022 - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# debug: n -# dev: n - - name: Debug - debug: y - dev: n - slug: -Debug - - name: Dev - debug: y - dev: y - slug: -Dev - dynarec: - - name: ODR - new: n - slug: -ODR - - name: NDR - new: y - slug: -NDR - environment: -# - msystem: MSYS -# clang: n -# x64: y - - msystem: MINGW32 - prefix: mingw-w64-i686 - clang: n - x64: n - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - clang: n - x64: y -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# clang: y -# x64: n -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# clang: y -# x64: y - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - clang: n - x64: y - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - install: >- - make - pacboy: >- - gcc:p - clang:p - pkg-config:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: make - run: >- - make -fwin/Makefile.mingw -j - DEV_BUILD=${{ matrix.build.dev }} - DEBUG=${{ matrix.build.debug }} - NEW_DYNAREC=${{ matrix.dynarec.new }} - CLANG=${{ matrix.environment.clang }} - X64=${{ matrix.environment.x64 }} - working-directory: ./src - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: src/86Box.exe From fb53ed47b06211c16878370da86610eafe46446c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Mar 2024 16:21:25 +0100 Subject: [PATCH 367/690] cdrom_image_backend: Fix sector header generation for non-raw sectors. --- src/cdrom/cdrom_image_backend.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 151ddfe9f..1bc0fcf2d 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -422,11 +422,11 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) buffer += 12; FRAMES_TO_MSF(sector + 150, &m, &s, &f); /* These have to be BCD. */ - buffer[12] = CDROM_BCD(m & 0xff); - buffer[13] = CDROM_BCD(s & 0xff); - buffer[14] = CDROM_BCD(f & 0xff); + buffer[0] = CDROM_BCD(m & 0xff); + buffer[1] = CDROM_BCD(s & 0xff); + buffer[2] = CDROM_BCD(f & 0xff); /* Data, should reflect the actual sector type. */ - buffer[15] = trk->mode2 ? 2 : 1; + buffer[3] = trk->mode2 ? 2 : 1; return 1; } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); From 31dee950ab3b0b52a82c46e13e608a02f38ecad1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Mar 2024 14:37:04 +0100 Subject: [PATCH 368/690] PC330: Correct the on-board graphics card to VLB, fixes #4302. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 23c05bdf8..4338f741f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7299,7 +7299,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, + .vid_device = &gd5430_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, @@ -7339,7 +7339,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, + .vid_device = &gd5430_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, From 0b0cb84bf7a2052407c3fb07cfb08413ffe23082 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Mar 2024 19:59:26 +0100 Subject: [PATCH 369/690] FPU: Re-enabled SoftFloat on 808x and implement the missing FBLD instruction, closes #4300. --- src/cpu/808x.c | 85 +++++++++++++++++++++--------- src/cpu/x87_ops.h | 84 ++++++++++++++--------------- src/cpu/x87_ops_loadstore.h | 83 +++++++++++++++++++++++++++++ src/cpu/x87_ops_sf_load_store.h | 93 +++++++++++++++++++++++++++++++++ 4 files changed, 278 insertions(+), 67 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index caff0fa60..5b411dd66 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -3196,31 +3196,66 @@ execx86(int cycs) if (!hasfpu) geteaw(); else - switch (opcode) { - case 0xD8: - ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xD9: - ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDA: - ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDB: - ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDC: - ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xDD: - ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDE: - ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDF: - ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); - break; + if (fpu_softfloat) { + switch (opcode) { + case 0xD8: + ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xD9: + ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xDA: + ops_sf_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xDB: + ops_sf_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xDC: + ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xDD: + ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xDE: + ops_sf_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xDF: + ops_sf_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } + } else { + switch (opcode) { + case 0xD8: + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xD9: + ops_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xDA: + ops_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xDB: + ops_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xDC: + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xDD: + ops_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xDE: + ops_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xDF: + ops_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } } cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on the 286+ core, but not here. */ diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 1d9220255..aef9289e7 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -797,7 +797,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -806,7 +806,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -815,7 +815,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -1055,7 +1055,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1064,7 +1064,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1073,7 +1073,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -2114,7 +2114,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2123,7 +2123,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2132,7 +2132,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2154,7 +2154,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2163,7 +2163,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2172,7 +2172,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2194,7 +2194,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2203,7 +2203,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2212,7 +2212,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2234,7 +2234,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2243,7 +2243,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2252,7 +2252,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2275,7 +2275,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2284,7 +2284,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2293,7 +2293,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2315,7 +2315,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2324,7 +2324,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2333,7 +2333,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -3373,7 +3373,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3382,7 +3382,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3391,7 +3391,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3413,7 +3413,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3422,7 +3422,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3431,7 +3431,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3453,7 +3453,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3462,7 +3462,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3471,7 +3471,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3493,7 +3493,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3502,7 +3502,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3511,7 +3511,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3534,7 +3534,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3543,7 +3543,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3552,7 +3552,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3574,7 +3574,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3583,7 +3583,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3592,7 +3592,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index d77c0ca2b..0936f325b 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -144,6 +144,89 @@ opFILDiq_a32(uint32_t fetchdat) } #endif +static int +FBLD_a16(uint32_t fetchdat) +{ + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + x87_push((double) load_val); + cpu_state.MM[cpu_state.TOP & 7].q = load_val; + FP_TAG_DEFAULT; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +FBLD_a32(uint32_t fetchdat) +{ + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + x87_push((double) load_val); + cpu_state.MM[cpu_state.TOP & 7].q = load_val; + FP_TAG_DEFAULT; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#endif + static int FBSTP_a16(uint32_t fetchdat) { diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index 383a7ee52..228d9fc06 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -183,6 +183,99 @@ sf_FILDiq_a32(uint32_t fetchdat) } #endif +static int +sf_FBLD_PACKED_BCD_a16(uint32_t fetchdat) +{ + floatx80 result; + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + FPU_check_pending_exceptions(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + if (!IS_TAG_EMPTY(-1)) { + FPU_stack_overflow(fetchdat); + } else { + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + result = int64_to_floatx80(load_val); + FPU_push(); + FPU_save_regi(result, 0); + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +sf_FBLD_PACKED_BCD_a32(uint32_t fetchdat) +{ + floatx80 result; + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + FPU_check_pending_exceptions(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + if (!IS_TAG_EMPTY(-1)) { + FPU_stack_overflow(fetchdat); + } else { + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + result = int64_to_floatx80(load_val); + FPU_push(); + FPU_save_regi(result, 0); + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#endif + static int sf_FLDs_a16(uint32_t fetchdat) { From 12e4d1b0831d292b320ec4fc2b0b1ed9b77872e0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 26 Mar 2024 23:29:06 +0100 Subject: [PATCH 370/690] SoftFloat: Correctly treat +INF and -INF as equal on 8087 and 287, fixes 287 detection in MCPDiag. --- src/cpu/softfloat/softfloatx80.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc index 3ac3e61b3..b4ce88b3f 100644 --- a/src/cpu/softfloat/softfloatx80.cc +++ b/src/cpu/softfloat/softfloatx80.cc @@ -23,6 +23,11 @@ these four paragraphs for those parts of this code that are retained. * Stanislav Shwartsman [sshwarts at sourceforge net] * ==========================================================================*/ +#include +#include +#include <86box/86box.h> +#include "../cpu.h" + #include "softfloatx80.h" #include "softfloat-round-pack.h" #include "softfloat-macros.h" @@ -305,6 +310,18 @@ int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *s float_class_t aClass = floatx80_class(a); float_class_t bClass = floatx80_class(b); + if (fpu_type < FPU_287XL) { + if ((aClass == float_positive_inf) || (bClass == float_negative_inf)) + { + return float_relation_equal; + } + + if ((aClass == float_negative_inf) || (bClass == float_positive_inf)) + { + return float_relation_equal; + } + } + if (aClass == float_SNaN || bClass == float_SNaN) { /* unsupported reported as SNaN */ From 8e21ba4699a2e8762c191e31cfc789487bde1e2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 13:59:37 +0100 Subject: [PATCH 371/690] SoftFloat: Fix 8087/287 comparison of infinites. --- src/cpu/softfloat/softfloatx80.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc index b4ce88b3f..fc2409601 100644 --- a/src/cpu/softfloat/softfloatx80.cc +++ b/src/cpu/softfloat/softfloatx80.cc @@ -311,12 +311,12 @@ int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *s float_class_t bClass = floatx80_class(b); if (fpu_type < FPU_287XL) { - if ((aClass == float_positive_inf) || (bClass == float_negative_inf)) + if ((aClass == float_positive_inf) && (bClass == float_negative_inf)) { return float_relation_equal; } - if ((aClass == float_negative_inf) || (bClass == float_positive_inf)) + if ((aClass == float_negative_inf) && (bClass == float_positive_inf)) { return float_relation_equal; } From 7a4a44d1d1368721f3a18a5aabbab926b19e406d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 17:24:06 +0100 Subject: [PATCH 372/690] Matrox: Apply DirectDraw transparency fixes by Cacodemon345. --- src/video/vid_mga.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 074303553..0de369b53 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5368,6 +5368,19 @@ blit_bitblt(mystique_t *mystique) int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint32_t bltckey = mystique->dwgreg.fcol; + uint32_t bltcmsk = mystique->dwgreg.bcol; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; + } switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: @@ -5670,6 +5683,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_8: src = svga->vram[src_addr & mystique->vram_mask]; dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -5680,6 +5695,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_16: src = ((uint16_t *) svga->vram)[src_addr & mystique->vram_mask_w]; dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -5690,6 +5707,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_24: src = *(uint32_t *) &svga->vram[(src_addr * 3) & mystique->vram_mask]; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); @@ -5700,6 +5719,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_32: src = ((uint32_t *) svga->vram)[src_addr & mystique->vram_mask_l]; dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); From 5445ef639f0d798acf8b810264af53f6589760b4 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:21:26 -0400 Subject: [PATCH 373/690] GHA: Disable UCRT64 in msys2 workflow --- .github/workflows/cmake_windows_msys2.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index c4cebaee3..0ed29f0b7 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -79,9 +79,9 @@ jobs: # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake steps: - name: Prepare MSYS2 environment From bf09f6c9fc82b3b5c51706b4a7a017bddffe30e8 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:16:21 -0400 Subject: [PATCH 374/690] Fix gcc warning with use of strncpy --- src/disk/zip.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/disk/zip.c b/src/disk/zip.c index 7045b1e41..08d3baee3 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -532,6 +532,11 @@ zip_load(zip_t *dev, char *fn) fatal("zip_load(): Error seeking to the beginning of the file\n"); strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + // After using strncpy, dev->drv->image_path needs to be explicitly null terminated to make gcc happy. + // In the event strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) (no null terminator) + // it is placed at the very end. Otherwise, it is placed right after the string. + const size_t term = strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) ? sizeof(dev->drv->image_path) - 1 : strlen(dev->drv->image_path); + dev->drv->image_path[term] = '\0'; return 1; } From f48b71020677ecd2c3442780b6139b0961daae51 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 19:55:34 +0100 Subject: [PATCH 375/690] Some changes in preparation for the not yet committable PAS16 changes. --- src/include/86box/filters.h | 27 ++++++++++++++++++ src/include/86box/pit.h | 9 +++++- src/include/86box/pit_fast.h | 12 ++++++++ src/include/86box/sound.h | 1 + src/pit.c | 53 ++++++++++++++++++++++++++---------- src/pit_fast.c | 14 +++++++--- 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index 16c9c7221..0aa1c17f1 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -422,4 +422,31 @@ low_fir_sb16(int c, int i, double NewSample) return out; } +extern double low_fir_pas16_coef[4][SB16_NCoef]; + +static inline double +low_fir_pas16(int c, int i, double NewSample) +{ + static double x[4][2][SB16_NCoef + 1]; // input samples + static int pos[4] = { 0, 0, 0, 0 }; + double out = 0.0; + int n; + + /* Calculate the new output */ + x[c][i][pos[c]] = NewSample; + + for (n = 0; n < ((SB16_NCoef + 1) - pos[c]) && n < SB16_NCoef; n++) + out += low_fir_pas16_coef[c][n] * x[c][i][n + pos[c]]; + for (; n < SB16_NCoef; n++) + out += low_fir_pas16_coef[c][n] * x[c][i][(n + pos[c]) - (SB16_NCoef + 1)]; + + if (i == 1) { + pos[c]++; + if (pos[c] > SB16_NCoef) + pos[c] = 0; + } + + return out; +} + #endif /*EMU_FILTERS_H*/ diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index ed60cfa29..4129a1093 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -113,6 +113,7 @@ extern double AGPCLK; extern uint64_t PITCONST; extern uint64_t PAS16CONST; +extern uint64_t PAS16CONST2; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; @@ -123,13 +124,19 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; -extern void pit_change_pas16_const(double prescale); +extern void pit_device_reset(pit_t *dev); + +extern void pit_change_pas16_consts(double prescale); extern void pit_set_pit_const(void *data, uint64_t pit_const); +extern void ctr_clock(void *data, int counter_id); + /* Sets a counter's CLOCK input. */ extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); +extern void pit_ctr_set_gate(void *data, int counter_id, int gate); + extern void pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); extern void pit_ctr_set_using_timer(void *data, int counter_id, int using_timer); diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 2a8181a94..5650ffb4d 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -71,10 +71,22 @@ typedef struct pitf_t { ctrf_t counters[3]; uint8_t ctrl; + + void *dev_priv; } pitf_t; extern void pitf_set_pit_const(void *data, uint64_t pit_const); +extern void pitf_handler(int set, uint16_t base, int size, void *priv); + +extern void pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); + +extern void pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer); + +extern void pitf_ctr_set_gate(void *data, int counter_id, int gate); + +extern void pitf_ctr_clock(void *data, int counter_id); + extern uint8_t pitf_read_reg(void *priv, uint8_t reg); extern const pit_intf_t pit_fast_intf; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 005b56d13..5f04c10fe 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -124,6 +124,7 @@ extern const device_t cms_device; extern const device_t gus_device; /* Pro Audio Spectrum 16 */ +extern const device_t pasplus_device; extern const device_t pas16_device; /* IBM PS/1 Audio Card */ diff --git a/src/pit.c b/src/pit.c index b5d402bb3..340cdccde 100644 --- a/src/pit.c +++ b/src/pit.c @@ -48,6 +48,7 @@ pit_intf_t pit_devs[2]; double cpuclock; double PITCONSTD; double PAS16CONSTD; +double PAS16CONST2D; double SYSCLK; double isa_timing; double bus_timing; @@ -58,6 +59,7 @@ double AGPCLK; uint64_t PITCONST; uint64_t PAS16CONST; +uint64_t PAS16CONST2; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -309,7 +311,7 @@ ctr_tick(ctr_t *ctr, void *priv) } } -static void +void ctr_clock(void *data, int counter_id) { pit_t *pit = (pit_t *) data; @@ -535,8 +537,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) int t = (addr & 3); ctr_t *ctr; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + } switch (addr & 3) { case 3: /* control */ @@ -552,8 +555,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_latch_count(&dev->counters[1]); if (val & 8) ctr_latch_count(&dev->counters[2]); - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Initiated readback command\n", t); + } } if (!(val & 0x10)) { if (val & 2) @@ -570,9 +574,10 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); + } } else { ctr->ctrl = val; ctr->rm = ctr->wm = (ctr->ctrl >> 4) & 3; @@ -584,13 +589,15 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_set_out(ctr, !!ctr->m, dev); ctr->state = 0; if (ctr->latched) { - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Reload while counter is latched\n", t); + } ctr->rl--; } - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + } } } break; @@ -608,8 +615,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = val; ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (1): Written byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -618,8 +626,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = (val << 8); ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (2): Written byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -630,15 +639,17 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = (ctr->l & 0x00ff) | (val << 8); ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (0x83): Written high byte %02X, latch now %04X\n", t, val, ctr->l); + } ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (3): Written low byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) { ctr->state = 0; ctr_set_out(ctr, 0, dev); @@ -774,8 +785,9 @@ pit_read(uint16_t addr, void *priv) break; } - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + } return ret; } @@ -855,6 +867,15 @@ ctr_reset(ctr_t *ctr) ctr->l_det = 0; } +void +pit_device_reset(pit_t *dev) +{ + dev->clock = 0; + + for (uint8_t i = 0; i < 3; i++) + ctr_reset(&dev->counters[i]); +} + void pit_reset(pit_t *dev) { @@ -1094,9 +1115,10 @@ pit_ps2_init(int type) } void -pit_change_pas16_const(double prescale) +pit_change_pas16_consts(double prescale) { - PAS16CONST = (uint64_t) ((PITCONSTD / prescale) * (double) (1ULL << 32)); + PAS16CONST = (uint64_t) ((PAS16CONSTD / prescale) * (double) (1ULL << 32)); + PAS16CONST2 = (uint64_t) ((PAS16CONST2D / prescale) * (double) (1ULL << 32)); } void @@ -1195,7 +1217,10 @@ pit_set_clock(uint32_t clock) TIMER_USEC = (uint64_t) ((cpuclock / 1000000.0) * (double) (1ULL << 32)); PAS16CONSTD = (cpuclock / 441000.0); - PAS16CONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); + PAS16CONST = (uint64_t) (PAS16CONSTD * (double) (1ULL << 32)); + + PAS16CONST2D = (cpuclock / 1008000.0); + PAS16CONST2 = (uint64_t) (PAS16CONST2D * (double) (1ULL << 32)); isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) diff --git a/src/pit_fast.c b/src/pit_fast.c index acaa6c271..0da671bfe 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -99,7 +99,7 @@ pitf_ctr_get_count(void *data, int counter_id) return (uint16_t) ctr->l; } -static void +void pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) @@ -111,7 +111,7 @@ pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int ctr->out_func = func; } -static void +void pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer) { if (tsc > 0) @@ -284,7 +284,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) pitf_dump_and_disable_timer(ctr); } -static void +void pitf_ctr_set_gate(void *data, int counter_id, int gate) { pitf_t *pit = (pitf_t *) data; @@ -619,7 +619,7 @@ pitf_timer_over(void *priv) pitf_over(ctr, pit); } -static void +void pitf_ctr_clock(void *data, int counter_id) { pitf_t *pit = (pitf_t *) data; @@ -692,6 +692,12 @@ pitf_close(void *priv) free(dev); } +void +pitf_handler(int set, uint16_t base, int size, void *priv) +{ + io_handler(set, base, size, pitf_read, NULL, NULL, pitf_write, NULL, NULL, priv); +} + static void * pitf_init(const device_t *info) { From 8b3866b9933f0ccbbb1c1dfd0cb2e3662638f171 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 22:19:06 +0100 Subject: [PATCH 376/690] SiS 5595 PMU: Remove a pointless tautology. --- src/chipset/sis_5595_pmu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c index 4c6dbf7c9..de351ad7c 100644 --- a/src/chipset/sis_5595_pmu.c +++ b/src/chipset/sis_5595_pmu.c @@ -140,7 +140,6 @@ sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t en uint16_t addr, uint16_t size) { sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id]; - enable = enable; /* Set up Device I/O traps dynamically. */ if (enable && !trap->trap) { From 7f4e8caefacf6c4f52f3164855ea068d1a024f74 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 22:23:33 +0100 Subject: [PATCH 377/690] IT86x1: Use PRIXPTR instead of the #ifdef's. --- src/sio/sio_it86x1f.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index ece59501f..00524863a 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -808,18 +808,10 @@ it86x1f_init(UNUSED(const device_t *info)) break; } if (i >= (sizeof(it86x1f_models) / sizeof(it86x1f_models[0]))) { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - fatal("IT86x1F: Unknown type %04" PRIX64 " selected\n", info->local); -#else - fatal("IT86x1F: Unknown type %04X selected\n", info->local); -#endif + fatal("IT86x1F: Unknown type %04" PRIXPTR " selected\n", info->local); return NULL; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - it86x1f_log("IT86x1F: init(%04" PRIX64 ")\n", info->local); -#else - it86x1f_log("IT86x1F: init(%04X)\n", info->local); -#endif + it86x1f_log("IT86x1F: init(%04" PRIXPTR ")\n", info->local); /* Let the resource data parser figure out the ROM size. */ dev->pnp_card = isapnp_add_card(it86x1f_models[i].pnp_rom, -1, it86x1f_models[i].pnp_config_changed, NULL, it86x1f_pnp_read_vendor_reg, it86x1f_pnp_write_vendor_reg, dev); From d290de418d14e50d311cac809cd66a46c09159a7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 23:56:55 +0100 Subject: [PATCH 378/690] Significantly reworked the Pro Audio Spectrum 16 and implemented a lot of missing stuff, and added the Pro Audio Spectrum Plus. --- src/dma.c | 23 + src/include/86box/dma.h | 2 + src/sound/snd_pas16.c | 1075 ++++++++++++++++++++++++++------------- src/sound/sound.c | 1 + 4 files changed, 737 insertions(+), 364 deletions(-) diff --git a/src/dma.c b/src/dma.c index 50ae598b8..b7c4b4863 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1397,6 +1397,29 @@ dma_advance(dma_t *dma_c) dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); } +int +dma_channel_readable(int channel) +{ + dma_t *dma_c = &dma[channel]; + + if (channel < 4) { + if (dma_command[0] & 0x04) + return 0; + } else { + if (dma_command[1] & 0x04) + return 0; + } + + if (!(dma_e & (1 << channel))) + return 0; + if ((dma_m & (1 << channel)) && !dma_req_is_soft) + return 0; + if ((dma_c->mode & 0xC) != 8) + return 0; + + return 1; +} + int dma_channel_read(int channel) { diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index 7ead53ba0..ff0dc0b5d 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -118,4 +118,6 @@ void dma_high_page_init(void); void dma_remove_sg(void); void dma_set_sg_base(uint8_t sg_base); +extern int dma_channel_readable(int channel); + #endif /*EMU_DMA_H*/ diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 45a18ff73..0a5c046b7 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -1,3 +1,92 @@ +/* + * 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. + * + * Pro Audio Spectrum Plus and 16 emulation. + * + * Original PAS uses: + * - 2 x OPL2; + * - PIT - sample rate/count; + * - LMC835N/LMC1982 - mixer; + * - YM3802 - MIDI Control System. + * + * 9A01 - I/O base: + * - base >> 2. + * + * All below + I/O base. + * + * B89 - Interrupt status / clear: + * - Bit 2 - sample rate; + * - Bit 3 - PCM; + * - Bit 4 - MIDI. + * + * B88 - Audio mixer control register. + * + * B8A - Audio filter control: + * - Bit 5 - mute?. + * + * B8B - Interrupt mask / board ID: + * - Bits 5-7 - board ID (read only on PAS16). + * + * F88 - PCM data (low). + * + * F89 - PCM data (high). + * + * F8A - PCM control?: + * - Bit 4 - input/output select (1 = output); + * - Bit 5 - mono/stereo select; + * - Bit 6 - PCM enable. + * + * 1388-138B - PIT clocked at 1193180 Hz: + * - 1388 - Sample rate; + * - 1389 - Sample count. + * + * 178B - ????. + * 2789 - Board revision. + * + * 8389: + * - Bit 2 - 8/16 bit. + * + * BF88 - Wait states. + * + * EF8B: + * - Bit 3 - 16 bits okay ?. + * + * F388: + * - Bit 6 - joystick enable. + * + * F389: + * - Bits 0-2 - DMA. + * + * F38A: + * - Bits 0-3 - IRQ. + * + * F788: + * - Bit 1 - SB emulation; + * - Bit 0 - MPU401 emulation. + * + * F789 - SB base address: + * - Bits 0-3 - Address bits 4-7. + * + * FB8A - SB IRQ/DMA: + * - Bits 3-5 - IRQ; + * - Bits 6-7 - DMA. + * + * FF88 - board model: + * - 3 = PAS16. + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * + * Copyright 2008-2024 Sarah Walker. + * Copyright 2024 Miran Grca. + */ +#include #include #include #include @@ -16,6 +105,7 @@ #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> +#include <86box/pit_fast.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -23,140 +113,69 @@ #include <86box/snd_sb_dsp.h> #include <86box/plat_unused.h> -/* Original PAS uses - 2 x OPL2 - PIT - sample rate/count - LMC835N/LMC1982 - mixer - YM3802 - MIDI Control System - - - 9A01 - IO base - base >> 2 - - All below + IO base - - B89 - interrupt status / clear - bit 2 - sample rate - bit 3 - PCM - bit 4 - MIDI - - B88 - Audio mixer control register - - B8A - Audio filter control - bit 5 - mute? - - B8B - interrupt mask / board ID - bits 5-7 - board ID (read only on PAS16) - - F88 - PCM data (low) - - F89 - PCM data (high) - - F8A - PCM control? - bit 4 - input/output select (1 = output) - bit 5 - mono/stereo select - bit 6 - PCM enable - - 1388-138b - PIT clocked at 1193180 Hz - 1388 - sample rate - 1389 - sample count - - 178b - - 2789 - board revision - - 8389 - - bit 2 - 8/16 bit - - BF88 - wait states - - EF8B - - bit 3 - 16 bits okay ? - - F388 - - bit 6 - joystick enable - - F389 - - bits 0-2 - DMA - - F38A - - bits 0-3 - IRQ - - F788 - - bit 1 - SB emulation - bit 0 - MPU401 emulation - - F789 - SB base addr - bits 0-3 - addr bits 4-7 - - FB8A - SB IRQ/DMA - bits 3-5 - IRQ - bits 6-7 - DMA - - FF88 - board model - 3 = PAS16 -*/ - typedef struct pas16_t { - uint16_t base; + uint8_t this_id; + uint8_t board_id; + uint8_t master_ff; + uint8_t irq; + uint8_t dma; + uint8_t sb_irqdma; + uint8_t type; + uint8_t filter; - int irq; - int dma; - - uint8_t audiofilt; - - uint8_t audio_mixer; - - uint8_t compat; - uint8_t compat_base; - - uint8_t enhancedscsi; - - uint8_t io_conf_1; - uint8_t io_conf_2; - uint8_t io_conf_3; - uint8_t io_conf_4; - - uint8_t irq_stat; - uint8_t irq_ena; + uint8_t audiofilt; + uint8_t audio_mixer; + uint8_t compat; + uint8_t compat_base; + uint8_t io_conf_1; + uint8_t io_conf_2; + uint8_t io_conf_3; + uint8_t io_conf_4; + uint8_t irq_stat; + uint8_t irq_ena; uint8_t pcm_ctrl; - uint16_t pcm_dat; + uint8_t prescale_div; + uint8_t stereo_lr; + uint8_t dma8_ff; + uint8_t waitstates; + uint8_t enhancedscsi; + uint8_t sys_conf_1; + uint8_t sys_conf_2; + uint8_t sys_conf_3; + uint8_t sys_conf_4; + uint8_t midi_ctrl; + uint8_t midi_stat; + uint8_t midi_data; + uint8_t fifo_stat; + + uint8_t midi_queue[256]; + + uint16_t base; + uint16_t new_base; uint16_t pcm_dat_l; uint16_t pcm_dat_r; - uint8_t sb_irqdma; + int16_t pcm_buffer[2][SOUNDBUFLEN * 2]; - int stereo_lr; - - uint8_t sys_conf_1; - uint8_t sys_conf_2; - uint8_t sys_conf_3; - uint8_t sys_conf_4; - uint8_t waitstates; - uint8_t midi_ctrl; - uint8_t midi_stat; - uint8_t midi_data; - uint8_t fifo_stat; - int midi_r; - int midi_w; - int midi_uart_out; - int midi_uart_in; - uint8_t midi_queue[256]; - int sysex; + int pos; + int midi_r; + int midi_w; + int midi_uart_out; + int midi_uart_in; + int sysex; fm_drv_t opl; sb_dsp_t dsp; - mpu_t *mpu; - pc_timer_t timer; - int16_t pcm_buffer[2][SOUNDBUFLEN]; + mpu_t * mpu; - int pos; - - pit_t *pit; + pitf_t * pit; } pas16_t; +static uint8_t pas16_next = 0; + static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; @@ -166,7 +185,7 @@ static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; enum { PAS16_INT_SAMP = 0x04, PAS16_INT_PCM = 0x08, - PAS16_INT_MIDI = 0x10, + PAS16_INT_MIDI = 0x10 }; enum { @@ -184,6 +203,47 @@ enum { PAS16_FILT_MUTE = 0x20 }; +#define PAS16_PCM_AND_DMA_ENA (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA) + +double low_fir_pas16_coef[4][SB16_NCoef]; + +static __inline double +sinc(double x) +{ + return sin(M_PI * x) / (M_PI * x); +} + +static void +recalc_pas16_filter(int c, int playback_freq) +{ + /* Cutoff frequency = playback / 2 */ + int n; + double w; + double h; + double fC = ((double) playback_freq) / (double) FREQ_96000; + double gain; + + for (n = 0; n < SB16_NCoef; n++) { + /* Blackman window */ + w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + /* Sinc filter */ + h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + + /* Create windowed-sinc filter */ + low_fir_pas16_coef[c][n] = w * h; + } + + low_fir_pas16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) + gain += low_fir_pas16_coef[c][n]; + + /* Normalise filter, to produce unity gain */ + for (n = 0; n < SB16_NCoef; n++) + low_fir_pas16_coef[c][n] /= gain; +} + #ifdef ENABLE_PAS16_LOG int pas16_do_log = ENABLE_PAS16_LOG; @@ -226,45 +286,45 @@ static uint8_t pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - uint8_t temp = 0xff; + uint8_t ret = 0xff; + + port -= pas16->base; + switch (port) { - case 0x388: - case 0x389: - case 0x38a: - case 0x38b: - temp = pas16->opl.read(port, pas16->opl.priv); + case 0x0000 ... 0x0003: + ret = pas16->opl.read(port + 0x0388, pas16->opl.priv); break; - case 0xb88: - temp = pas16->audio_mixer; + case 0x0800: + ret = pas16->audio_mixer; break; - case 0xb89: - temp = pas16->irq_stat; + case 0x0801: + ret = pas16->irq_stat & 0xdf; break; - case 0xb8a: - temp = pas16->audiofilt; + case 0x0802: + ret = pas16->audiofilt; break; - case 0xb8b: - temp = pas16->irq_ena | 0x20; - pas16_log("IRQ Mask read=%02x.\n", temp); + case 0x0803: + ret = pas16->irq_ena | (pas16->type ? 0x20 : 0x00); + pas16_log("IRQ Mask read=%02x.\n", ret); break; - case 0xf8a: - temp = pas16->pcm_ctrl; + case 0x0c02: + ret = pas16->pcm_ctrl; break; - case 0x1789: - case 0x178b: - temp = pas16->midi_ctrl; + case 0x1401: + case 0x1403: + ret = pas16->midi_ctrl; break; - case 0x178a: - case 0x1b8a: - temp = 0; + case 0x1402: + case 0x1802: + ret = 0; if (pas16->midi_uart_in) { if ((pas16->midi_data == 0xaa) && (pas16->midi_ctrl & 0x04)) - temp = pas16->midi_data; + ret = pas16->midi_data; else { - temp = pas16->midi_queue[pas16->midi_r]; + ret = pas16->midi_queue[pas16->midi_r]; if (pas16->midi_r != pas16->midi_w) { pas16->midi_r++; pas16->midi_r &= 0xff; @@ -275,206 +335,386 @@ pas16_in(uint16_t port, void *priv) } break; - case 0x1b88: - temp = pas16->midi_stat; + case 0x1800: + ret = pas16->midi_stat; break; - case 0x1b89: - temp = pas16->fifo_stat; + case 0x1801: + ret = pas16->fifo_stat; break; - case 0x2789: /*Board revision*/ - temp = 0x00; + case 0x2401: /* Board revision */ + ret = 0x00; break; - case 0x7f89: - temp = pas16->enhancedscsi & ~0x01; + case 0x7c01: + ret = pas16->enhancedscsi & ~0x01; break; - case 0x8388: - temp = pas16->sys_conf_1; + case 0x8000: + ret = pas16->sys_conf_1; break; - case 0x8389: - temp = pas16->sys_conf_2; + case 0x8001: + ret = pas16->sys_conf_2; break; - case 0x838a: - temp = pas16->sys_conf_3; + case 0x8002: + ret = pas16->sys_conf_3; break; - case 0x838b: - temp = pas16->sys_conf_4; + case 0x8003: + ret = pas16->sys_conf_4; break; - case 0xbf88: - temp = pas16->waitstates; + case 0xbc00: + ret = pas16->waitstates; break; - case 0xef8b: - temp = 0x00; + case 0xbc02: + ret = pas16->prescale_div; break; - case 0xf388: - temp = pas16->io_conf_1; + case 0xec03: + ret = pas16->type ? 0x0c : 0x04; break; - case 0xf389: - temp = pas16->io_conf_2; + + case 0xf000: + ret = pas16->io_conf_1; + break; + case 0xf001: + ret = pas16->io_conf_2; pas16_log("pas16_in : set PAS DMA %i\n", pas16->dma); break; - case 0xf38a: - temp = pas16->io_conf_3; + case 0xf002: + ret = pas16->io_conf_3; pas16_log("pas16_in : set PAS IRQ %i\n", pas16->irq); break; - case 0xf38b: - temp = pas16->io_conf_4; + case 0xf003: + ret = pas16->io_conf_4; break; - case 0xf788: - temp = pas16->compat; + case 0xf400: + ret = pas16->compat; break; - case 0xf789: - temp = pas16->compat_base; + case 0xf401: + ret = pas16->compat_base; break; - case 0xfb8a: - temp = pas16->sb_irqdma; + case 0xf802: + ret = pas16->sb_irqdma; break; - case 0xff88: /*Board model*/ - temp = 0x04; /*PAS16*/ + case 0xfc00: /* Board model */ + /* PAS16 or PASPlus */ + ret = pas16->type ? 0x04 : 0x01; break; - case 0xff8b: /*Master mode read*/ - temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ + case 0xfc03: /* Master mode read */ + /* AT bus, XT/AT timing */ + ret = pas16->type ? (0x20 | 0x10 | 0x01) : (0x10 | 0x01); break; default: break; } - pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); - return temp; + + pas16_log("[%04X:%08X] PAS16: [R] %04X (%04X) = %02X\n", + CS, cpu_state.pc, port + pas16->base, port, ret); + + return ret; +} + +static void +pas16_change_pit_clock_speed(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + pitf_t *pit = (pitf_t *) pas16->pit; + + if (pas16->type && (pas16->sys_conf_1 & 0x02) && pas16->prescale_div) { + pit_change_pas16_consts((double) pas16->prescale_div); + if (pas16->sys_conf_3 & 0x02) + pitf_set_pit_const(pit, PAS16CONST2); + else + pitf_set_pit_const(pit, PAS16CONST); + } else + pitf_set_pit_const(pit, PITCONST); +} + +static void +pas16_io_handler(pas16_t *pas16, int set) +{ + if (pas16->base != 0x0000) { + for (uint32_t addr = 0x0000; addr <= 0xffff; addr += 0x0400) { + pas16_log("%04X-%04X: %i\n", pas16->base + addr, pas16->base + addr + 3, set); + if (addr != 0x1000) + io_handler(set, pas16->base + addr, 0x0004, + pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + } + + pitf_handler(set, pas16->base + 0x1000, 0x0004, pas16->pit); + } +} + +static void +pas16_reset_pcm(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16->pcm_ctrl = 0x00; + + pas16->stereo_lr = 0; + pas16->dma8_ff = 0; + + pas16->irq_stat &= 0xd7; + + if (!pas16->irq_stat) + picintc(1 << pas16->irq); +} + +static void +pas16_reset_regs(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + pitf_t *pit = (pitf_t *) pas16->pit; + + picintc(1 << pas16->irq); + + pas16->sys_conf_1 &= 0xfd; + + pas16->sys_conf_2 = 0x00; + pas16->sys_conf_3 = 0x00; + + pas16->prescale_div = 0x00; + + pitf_set_pit_const(pit, PITCONST); + + pas16->audiofilt = 0x00; + pas16->filter = 0; + + pitf_ctr_set_gate(pit, 0, 0); + pitf_ctr_set_gate(pit, 1, 0); + + pas16_reset_pcm(pas16); + + pas16->irq_ena = 0x00; + pas16->irq_stat = 0x00; +} + +static void +pas16_reset_common(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16_reset_regs(pas16); + + picintc(1 << pas16->irq); + + pas16_io_handler(pas16, 0); + pas16->base = 0x0000; +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16_reset_common(priv); + + pas16->board_id = 0; + pas16->master_ff = 0; + + pas16->base = 0x0388; + pas16_io_handler(pas16, 1); + + pas16->new_base = 0x0388; } static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + + pas16_log("[%04X:%08X] PAS16: [W] %04X (%04X) = %02X\n", + CS, cpu_state.pc, port, port - pas16->base, val); + + port -= pas16->base; + switch (port) { - case 0x388: - case 0x389: - case 0x38a: - case 0x38b: - pas16->opl.write(port, val, pas16->opl.priv); + case 0x0000 ... 0x0003: + pas16->opl.write(port + 0x0388, val, pas16->opl.priv); break; - case 0xb88: + case 0x0800: pas16->audio_mixer = val; + if (!(val & 0x01)) + pas16_reset_pcm(pas16); break; - case 0xb89: + case 0x0801: pas16->irq_stat &= ~val; break; - case 0xb8a: + case 0x0802: + if ((val & 0x20) && !(pas16->audiofilt & 0x20)) { + pas16_log("Reset.\n"); + val = 0x20; + pas16_reset_regs(pas16); + } + pas16_update(pas16); + pitf_ctr_set_gate(pas16->pit, 0, 1); + pitf_ctr_set_gate(pas16->pit, 1, 1); + // pas16->pit->counters[0].gate = !!(val & 0x40); + // pas16->pit->counters[0].enabled = !!(val & 0x40); + // pas16->pit->counters[1].gate = !!(val & 0x80); + // pas16->pit->counters[1].enabled = !!(val & 0x80); + pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + pas16->dma8_ff = 0; pas16->audiofilt = val; + if (val & 0x1f) { + pas16->filter = 1; + switch (val & 0x1f) { + default: + pas16->filter = 0; + break; + case 0x01: + recalc_pas16_filter(0, 17897); + break; + case 0x02: + recalc_pas16_filter(0, 15909); + break; + case 0x04: + recalc_pas16_filter(0, 2982); + break; + case 0x09: + recalc_pas16_filter(0, 11931); + break; + case 0x11: + recalc_pas16_filter(0, 8948); + break; + case 0x19: + recalc_pas16_filter(0, 5965); + break; + } + } else + pas16->filter = 0; break; - case 0xb8b: + case 0x0803: pas16->irq_ena = val & 0x1f; break; - case 0xf88: + case 0x0c00: pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; break; - case 0xf89: + case 0x0c01: pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); break; - case 0xf8a: - if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ + case 0x0c02: + if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) { + /* Guess */ pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + /* Needed for 8-bit DMA to work correctly on a 16-bit DMA channel. */ + pas16->dma8_ff = 0; + } pas16->pcm_ctrl = val; + pas16_log("Now in: %s (%02X)\n", (pas16->pcm_ctrl & PAS16_PCM_MONO) ? "Mono" : "Stereo", val); break; - case 0x1789: - case 0x178b: + case 0x1401: + case 0x1403: pas16->midi_ctrl = val; if ((val & 0x60) == 0x60) { pas16->midi_uart_out = 0; pas16->midi_uart_in = 0; - } else if (val & 0x18) { + } else if (val & 0x18) pas16->midi_uart_out = 1; - } else if (val & 0x04) + else if (val & 0x04) pas16->midi_uart_in = 1; else pas16->midi_uart_out = 1; pas16_update_irq(pas16); break; - case 0x178a: - case 0x1b8a: + case 0x1402: + case 0x1802: pas16->midi_data = val; pas16_log("UART OUT=%d.\n", pas16->midi_uart_out); if (pas16->midi_uart_out) midi_raw_out_byte(val); break; - case 0x1b88: + case 0x1800: pas16->midi_stat = val; pas16_update_irq(pas16); break; - case 0x1b89: + case 0x1801: pas16->fifo_stat = val; break; - case 0x7f89: + case 0x7c01: pas16->enhancedscsi = val; break; - case 0x8388: + case 0x8000: if ((val & 0xc0) && !(pas16->sys_conf_1 & 0xc0)) { pas16_log("Reset.\n"); - picintc(1 << pas16->irq); val = 0x00; + pas16_reset_common(pas16); + pas16->base = pas16->new_base; + pas16_io_handler(pas16, 1); } + pas16->sys_conf_1 = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Now in: %s mode\n", (pas16->sys_conf_1 & 0x02) ? "native" : "compatibility"); break; - case 0x8389: + case 0x8001: pas16->sys_conf_2 = val; + pas16_log("Now in: %i bits (%02X)\n", + (pas16->sys_conf_2 & 0x04) ? ((pas16->sys_conf_2 & 0x08) ? 12 : 16) : 8, val); break; - case 0x838a: + case 0x8002: pas16->sys_conf_3 = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Use 1.008 MHz clok for PCM: %c\n", (val & 0x02) ? 'Y' : 'N'); break; - case 0x838b: + case 0x8003: pas16->sys_conf_4 = val; break; - case 0xbf88: + case 0xbc00: pas16->waitstates = val; break; + case 0xbc02: + pas16->prescale_div = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Prescale divider now: %i\n", val); + break; - case 0xf388: + case 0xf000: pas16->io_conf_1 = val; break; - case 0xf389: + case 0xf001: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; + pas16_change_pit_clock_speed(pas16); pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); break; - case 0xf38a: + case 0xf002: pas16->io_conf_3 = val; pas16->irq = val & 0x0f; - if (pas16->irq <= 6) { + if (pas16->irq <= 6) pas16->irq++; - } else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) + else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) pas16->irq += 3; else pas16->irq += 4; pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; - case 0xf38b: + case 0xf003: pas16->io_conf_4 = val; break; - case 0xf788: + case 0xf400: pas16->compat = val; + pas16_log("PCM compression is now %sabled\n", (val & 0x10) ? "en" : "dis"); if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); else @@ -484,7 +724,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) else mpu401_change_addr(pas16->mpu, 0); break; - case 0xf789: + case 0xf401: pas16->compat_base = val; if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); @@ -492,11 +732,12 @@ pas16_out(uint16_t port, uint8_t val, void *priv) mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; - case 0xfb8a: + case 0xf802: pas16->sb_irqdma = val; sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], + pas16_sb_dmas[(val >> 6) & 3]); break; default: @@ -504,35 +745,157 @@ pas16_out(uint16_t port, uint8_t val, void *priv) } } -static uint8_t -pas16_readdma(pas16_t *pas16) +/* + 8-bit mono: + - 8-bit DMA : On every timer 0 over, read the 8-bit sample and ctr_clock(); + (One ctr_clock() per timer 0 over) + - 16-bit DMA: On every even timer 0 over, read two 8-bit samples at once and ctr_clock(); + On every odd timer 0 over, read the MSB of the previously read sample word. + (One ctr_clock() per two timer 0 overs) + 8-bit stereo: + - 8-bit DMA : On every timer 0, read two 8-bit samples and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read two 8-bit samples and ctr_clock() once. + (One ctr_clock() per timer 0 over) + 16-bit mono (to be verified): + - 8-bit DMA : On every timer 0, read one 16-bit sample and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read one 16-bit sample and ctr_clock() once. + (One ctr_clock() per timer 0 over) + 16-bit stereo: + - 8-bit DMA : On every timer 0, read one 16-bit sample and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read one 16-bit sample and ctr_clock() twice. + (Two ctr_clock()'s per timer 0 over) + + What we can conclude from this is: + - Maximum 16 bits per timer 0 over; + - A 8-bit sample always takes one ctr_clock() tick, unless it has been read + alongside the previous sample; + - A 16-bit sample always takes two ctr_clock() ticks. + */ +static uint16_t +pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) { - return dma_channel_read(pas16->dma); + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) + ret = dma_channel_read(pas16->dma); + else + ret = 0x0000; + + for (uint8_t i = 0; i < timer1_ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + return ret; +} + +static uint16_t +pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) +{ + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { + ret = dma_channel_read(pas16->dma); + + if (pas16->dma < 5) + ret |= (dma_channel_read(pas16->dma) << 8); + } else + ret = 0x0000; + + for (uint8_t i = 0; i < timer1_ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + return ret; +} + +static uint16_t +pas16_readdmab(pas16_t *pas16) +{ + static uint16_t temp; + uint16_t ret; + + if (pas16->dma >= 5) { + if (pas16->dma8_ff) + temp >>= 8; + else + temp = pas16_dma_readb(pas16, 1); + + pas16->dma8_ff = !pas16->dma8_ff; + } else + temp = pas16_dma_readb(pas16, 1); + + ret = ((temp & 0xff) ^ 0x80) << 8; + + return ret; +} + +static uint16_t +pas16_readdmaw_mono(pas16_t *pas16) +{ + uint16_t ret; + + ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); + + return ret; +} + +static uint16_t +pas16_readdmaw_stereo(pas16_t *pas16) +{ + uint16_t ret; + + ret = pas16_dma_readw(pas16, 2); + + return ret; +} + +static uint16_t +pas16_readdma_mono(pas16_t *pas16) +{ + uint16_t ret; + + if (pas16->sys_conf_2 & 0x04) { + ret = pas16_readdmaw_mono(pas16); + + if (pas16->sys_conf_2 & 0x08) + ret &= 0xfff0; + } else + ret = pas16_readdmab(pas16); + + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) + ret ^= 0x8000; + + return ret; +} + +static uint16_t +pas16_readdma_stereo(pas16_t *pas16) +{ + uint16_t ret; + + if (pas16->sys_conf_2 & 0x04) { + ret = pas16_readdmaw_stereo(pas16); + + if (pas16->sys_conf_2 & 0x08) + ret &= 0xfff0; + } else + ret = pas16_readdmab(pas16); + + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) + ret ^= 0x8000; + + return ret; } static void -pas16_pcm_poll(void *priv) +pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) { - pas16_t *pas16 = (pas16_t *) priv; - pit_t *pit = (pit_t *) pas16->pit; - int data; - uint16_t temp = 0x0000; + pitf_t *pit = (pitf_t *) priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; + uint16_t temp; pas16_update(pas16); - if (pit->counters[0].m & 0x02) { - if (pit->counters[0].l & 0xff) { - if (pas16->dma >= 5) - timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); - else - timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); - } else { - if (pas16->dma >= 5) - timer_advance_u64(&pas16->timer, 0x100 * (PITCONST << 1ULL)); - else - timer_advance_u64(&pas16->timer, 0x100 * PITCONST); - } - } - pas16_update_irq(pas16); pas16->irq_stat |= PAS16_INT_SAMP; @@ -541,88 +904,51 @@ pas16_pcm_poll(void *priv) picint(1 << pas16->irq); } - /*Update sample rate counter*/ - pas16_log("T1=%d, master bit 1=%x, counter0=%d, counter1=%d, pcm dma ena=%02x 16bit?=%02x.\n", pit->counters[1].enable, pit->counters[0].m & 0x02, pit->counters[0].l, pit->counters[1].l, pas16->pcm_ctrl & 0xc0, pas16->sys_conf_2 & PAS16_SC2_16BIT); - if (pit->counters[1].enable) { - if ((pas16->pcm_ctrl & (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA))) { - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - data = pas16_readdma(pas16) << 8; - data |= pas16_readdma(pas16); - temp = data; - } else { - data = pas16_readdma(pas16); - temp = (data ^ 0x80) << 8; - } + if (((pas16->pcm_ctrl & PAS16_PCM_AND_DMA_ENA) == PAS16_PCM_AND_DMA_ENA) && + dma_channel_readable(pas16->dma) && (pit->counters[1].m & 2) && new_out) { + if (pas16->pcm_ctrl & PAS16_PCM_MONO) { + temp = pas16_readdma_mono(pas16); - if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) - temp ^= 0x8000; - if (pas16->pcm_ctrl & PAS16_PCM_MONO) - pas16->pcm_dat_l = pas16->pcm_dat_r = temp; - else { + pas16->pcm_dat_l = pas16->pcm_dat_r = temp; + } else { + temp = pas16_readdma_stereo(pas16); + + if (pas16->sys_conf_1 & 0x02) { + pas16->pcm_dat_l = temp; + + temp = pas16_readdma_stereo(pas16); + + pas16->pcm_dat_r = temp; + } else { if (pas16->stereo_lr) pas16->pcm_dat_r = temp; else pas16->pcm_dat_l = temp; pas16->stereo_lr = !pas16->stereo_lr; + pas16->irq_stat = (pas16->irq_stat & 0xdf) | (pas16->stereo_lr << 5); } } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - pit->counters[1].lback -= 2; - if (!pit->counters[1].lback) { - if (pit->counters[1].m & 0x02) { - if (pit->counters[1].lback2 & 0xfffe) - pit->counters[1].lback = pit->counters[1].lback2 & 0xfffe; - else - pit->counters[1].lback = 0; - } else { - pit->counters[1].lback = 0; - pit->counters[1].enable = 0; - } - pas16_log("16-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("16-bit: INT PCM.\n"); - picint(1 << pas16->irq); - } - } - } else { - pit->counters[1].lback--; - if (!pit->counters[1].lback) { - if (pit->counters[1].m & 0x02) { - if (pit->counters[1].lback2 & 0xffff) - pit->counters[1].lback = pit->counters[1].lback2 & 0xffff; - else - pit->counters[1].lback = 0; - } else { - pit->counters[1].lback = 0; - pit->counters[1].enable = 0; - } - pas16_log("8-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("8-bit: INT PCM.\n"); - picint(1 << pas16->irq); - } - } - } - } + } } static void -pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) { - pit_t *pit = (pit_t *)priv; - pas16_t *pas16 = (pas16_t *)pit->dev_priv; + pitf_t *pit = (pitf_t * )priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; - pas16_log("PAS16 pit timer0 out=%x, cnt0=%d, cnt1=%d.\n", new_out, pit->counters[0].l, pit->counters[1].l); - pit_ctr_set_clock(&pit->counters[0], new_out, pit); - pit->counters[1].enable = new_out; - if (!timer_is_enabled(&pas16->timer)) { - if (pas16->dma >= 5) - timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); - else - timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + /* At new_out = 0, it's in the counter reload phase. */ + if ((pas16->pcm_ctrl & PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16->irq_stat |= PAS16_INT_PCM; + pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); + picint(1 << pas16->irq); + + pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + pas16->dma8_ff = 0; + } } } @@ -631,16 +957,14 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - for (uint32_t addr = 0x000; addr < 0x10000; addr += 0x400) { - if (addr != 0x1000) { - io_removehandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - } - } - pit_handler(0, pas16->base + 0x1000, 0x0004, pas16->pit); - pit_handler(1, pas16->base + 0x1000, 0x0004, pas16->pit); + pas16_log("[%04X:%08X] PAS16: [W] %04X = %02X\n", CS, cpu_state.pc, port, val); - pas16->base = val << 2; + if (pas16->master_ff && (pas16->board_id == pas16->this_id)) + pas16->new_base = val << 2; + else if (!pas16->master_ff) + pas16->board_id = val; + + pas16->master_ff = !pas16->master_ff; } static void @@ -693,8 +1017,16 @@ pas16_update(pas16_t *pas16) } } else { for (; pas16->pos < sound_pos_global; pas16->pos++) { - pas16->pcm_buffer[0][pas16->pos] = (int16_t) pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] = (int16_t) pas16->pcm_dat_r; + pas16->pcm_buffer[0][pas16->pos] = 0; + pas16->pcm_buffer[1][pas16->pos] = 0; + if (pas16->pcm_ctrl & 0x08) + pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_l; + if (pas16->pcm_ctrl & 0x04) + pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_r; + if (pas16->pcm_ctrl & 0x02) + pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_l; + if (pas16->pcm_ctrl & 0x01) + pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_r; } } } @@ -708,7 +1040,10 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) pas16_update(pas16); for (int c = 0; c < len * 2; c++) { buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); + if (pas16->filter) + buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1])) / 2.0; + else + buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); } pas16->pos = 0; @@ -730,31 +1065,22 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) static void pas16_speed_changed(void *priv) { - pas16_t *pas16 = (pas16_t *) priv; - - /* TODO: In PAS16 mode: - pit_change_pas16_const(prescale); - pit_set_pit_const(pas16->pit, PAS16CONST); - */ - - pit_set_pit_const(pas16->pit, PITCONST); -} - -static void -pas16_reset(void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - - /* TODO: Reset the entire PAS16 state here. */ - pit_set_pit_const(pas16->pit, PITCONST); + pas16_change_pit_clock_speed(priv); } static void * -pas16_init(UNUSED(const device_t *info)) +pas16_init(const device_t *info) { - pas16_t *pas16 = malloc(sizeof(pas16_t)); - memset(pas16, 0, sizeof(pas16_t)); + pas16_t *pas16 = calloc(1, sizeof(pas16_t)); + if (pas16_next > 3) { + fatal("Attempting to add a Pro Audio Spectrum instance beyond the maximum amount\n"); + + free(pas16); + return NULL; + } + + pas16->type = info->local & 0xff; fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); @@ -763,20 +1089,22 @@ pas16_init(UNUSED(const device_t *info)) mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); - pas16->pit = device_add(&i8254_ext_io_device); - pit_set_pit_const(pas16->pit, PITCONST); - pas16->pit->dev_priv = pas16; - pas16->irq = 10; - pas16->dma = 3; - pas16->base = 0x0388; - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); - pit_ctr_set_using_timer(pas16->pit, 0, 1); - pit_ctr_set_using_timer(pas16->pit, 1, 0); - pit_ctr_set_using_timer(pas16->pit, 2, 0); + pas16->this_id = 0xbc + pas16_next; - timer_add(&pas16->timer, pas16_pcm_poll, pas16, 0); + pas16->pit = device_add(&i8254_ext_io_fast_device); + pas16_reset(pas16); + pas16->pit->dev_priv = pas16; + pas16->irq = pas16->type ? 10 : 5; + pas16->dma = 3; + for (uint8_t i = 0; i < 3; i++) + pitf_ctr_set_gate(pas16->pit, i, 0); + + pitf_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); + pitf_ctr_set_out_func(pas16->pit, 1, pas16_pit_timer1); + pitf_ctr_set_using_timer(pas16->pit, 0, 1); + pitf_ctr_set_using_timer(pas16->pit, 1, 0); + pitf_ctr_set_using_timer(pas16->pit, 2, 0); sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); @@ -784,6 +1112,8 @@ pas16_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + pas16_next++; + return pas16; } @@ -793,6 +1123,8 @@ pas16_close(void *priv) pas16_t *pas16 = (pas16_t *) priv; free(pas16); + + pas16_next = 0; } static const device_config_t pas16_config[] = { @@ -805,7 +1137,7 @@ static const device_config_t pas16_config[] = { }, { .name = "receive_input", - .description = "Receive input (PAS16 MIDI)", + .description = "Receive input (PAS MIDI)", .type = CONFIG_BINARY, .default_string = "", .default_int = 1 @@ -813,10 +1145,10 @@ static const device_config_t pas16_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; -const device_t pas16_device = { - .name = "Pro Audio Spectrum 16", - .internal_name = "pas16", - .flags = DEVICE_ISA | DEVICE_AT, +const device_t pasplus_device = { + .name = "Pro Audio Spectrum Plus", + .internal_name = "pasplus", + .flags = DEVICE_ISA, .local = 0, .init = pas16_init, .close = pas16_close, @@ -826,3 +1158,18 @@ const device_t pas16_device = { .force_redraw = NULL, .config = pas16_config }; + + +const device_t pas16_device = { + .name = "Pro Audio Spectrum 16", + .internal_name = "pas16", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = pas16_init, + .close = pas16_close, + .reset = pas16_reset, + { .available = NULL }, + .speed_changed = pas16_speed_changed, + .force_redraw = NULL, + .config = pas16_config +}; diff --git a/src/sound/sound.c b/src/sound/sound.c index 9acf99460..cf7a7a33c 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -149,6 +149,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, + { &pasplus_device }, { &pas16_device }, { &pssj_isa_device }, { &tndy_device }, From 97ba1cd8e0e60018e5d55122f12cf2aa340cc5e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 00:18:30 +0100 Subject: [PATCH 379/690] Moved the ATi VGA Wonder 18800 out of the Dev branch. --- CMakeLists.txt | 1 - src/include/86box/video.h | 2 -- src/video/CMakeLists.txt | 4 ---- src/video/vid_ati18800.c | 43 +++++++++++++++++++++++++-------------- src/video/vid_table.c | 2 -- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bafadcc1..c0066e04a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,6 @@ cmake_dependent_option(OLIVETTI "Olivetti M290" cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) -cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) # Ditto but for Qt diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e56498807..bf36bf7de 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -320,9 +320,7 @@ extern const device_t mach64gx_pci_device; extern const device_t mach64vt2_device; /* ATi 18800 */ -# if defined(DEV_BRANCH) && defined(USE_VGAWONDER) extern const device_t ati18800_wonder_device; -# endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 8fbd62e35..12ba34a02 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(VGAWONDER) - target_compile_definitions(vid PRIVATE USE_VGAWONDER) -endif() - if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) endif() diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index b54f6b89e..7f0993ef8 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -32,21 +32,14 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -# define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" -#endif +#define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" #define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" enum { -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, ATI18800_EDGE16 -#else - ATI18800_VGA88 = 0, - ATI18800_EDGE16 -#endif }; typedef struct ati18800_t { @@ -257,11 +250,10 @@ ati18800_init(const device_t *info) switch (info->local) { default: -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) case ATI18800_WONDER: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = device_get_config_int("memory"); break; -#endif case ATI18800_VGA88: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ati18800->memory = 256; @@ -291,13 +283,11 @@ ati18800_init(const device_t *info) return ati18800; } -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) static int ati18800_wonder_available(void) { return rom_present(BIOS_ROM_PATH_WONDER); } -#endif static int ati18800_vga88_available(void) @@ -337,7 +327,31 @@ ati18800_force_redraw(void *priv) ati18800->svga.fullchange = changeframecount; } -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) +static const device_config_t ati18800_wonder_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 kB", + .value = 256 + }, + { + .description = "512 kB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + const device_t ati18800_wonder_device = { .name = "ATI-18800", .internal_name = "ati18800w", @@ -349,9 +363,8 @@ const device_t ati18800_wonder_device = { { .available = ati18800_wonder_available }, .speed_changed = ati18800_speed_changed, .force_redraw = ati18800_force_redraw, - .config = NULL + .config = ati18800_wonder_config }; -#endif const device_t ati18800_vga88_device = { .name = "ATI 18800-1", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 9992eff45..e526216c3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,9 +91,7 @@ video_cards[] = { { &ati28800_wonderxl24_device }, #endif { &ati18800_device }, -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) { &ati18800_wonder_device }, -#endif { &cga_device }, { &sega_device }, { &gd5401_isa_device }, From 7bd510dc1013018ba6307e1cbe1f5eee8cede40f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 00:25:30 +0100 Subject: [PATCH 380/690] Actually take the Olivetti M290 Dev branched option into account. --- src/machine/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index e88631044..ecc374e66 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -37,6 +37,10 @@ if(LASERXT) target_compile_definitions(mch PRIVATE USE_LASERXT) endif() +if(OLIVETTI) + target_compile_definitions(mch PRIVATE USE_OLIVETTI) +endif() + if(OPEN_AT) target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() From 2fd5fe86cd5e35ac089c79d4eb7ff49e682906b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 18:12:30 +0100 Subject: [PATCH 381/690] SiS 55xx: Add sanity check to the PCI to ISA bridge close code, fixes #4304. --- src/chipset/sis_5513_p2i.c | 3 ++- src/chipset/sis_5581.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index d0c423a8e..ef9a6746d 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -1197,7 +1197,8 @@ sis_5513_pci_to_isa_close(void *priv) sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; FILE *fp = NULL; - fp = nvr_fopen(dev->fn, "wb"); + if (dev->fn != NULL) + fp = nvr_fopen(dev->fn, "wb"); if (fp != NULL) { (void) fwrite(dev->apc_regs, 256, 1, fp); diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c index 98b37897c..e2308c2d9 100644 --- a/src/chipset/sis_5581.c +++ b/src/chipset/sis_5581.c @@ -43,7 +43,6 @@ #include <86box/sis_55xx.h> #include <86box/chipset.h> -#define ENABLE_SIS_5581_LOG 1 #ifdef ENABLE_SIS_5581_LOG int sis_5581_do_log = ENABLE_SIS_5581_LOG; From 3ec5f6f4a32b1df702e783481fd833182671d624 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Mar 2024 23:56:59 +0200 Subject: [PATCH 382/690] SiS 5571: Use the correct register for recalculating the SMRAM mapping, fixes #4318. --- src/chipset/sis_5571_h2p.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c index 26c74a3c0..4a4ee9b83 100644 --- a/src/chipset/sis_5571_h2p.c +++ b/src/chipset/sis_5571_h2p.c @@ -119,18 +119,18 @@ sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev) { smram_disable_all(); - switch (dev->pci_conf[0x68] >> 6) { + switch (dev->pci_conf[0xa3] >> 6) { case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); break; default: From 46840b239d55188a4df4d48b39a3fa1ca82d5365 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 12:57:48 +0200 Subject: [PATCH 383/690] MGA: Implement hardware dithering modes by Cacodemon345, fixes Windows 3.1 dynamic resolution switching. --- src/video/vid_mga.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0de369b53..36df9e9e4 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3579,6 +3579,12 @@ blit_fbitblt(mystique_t *mystique) mystique->blitter_complete_refcount++; } +static uint8_t +dither_24_to_8(int r, int g, int b) +{ + return ((b >> 6) & 3) | (((g >> 5) & 7) << 2) | (((r >> 5) & 7) << 5); +} + static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { @@ -3811,6 +3817,26 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) while (size >= 24) { if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(dither(mystique, (data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF, mystique->dwgreg.xdst & 1, mystique->dwgreg.selline & 1), dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + } + case MACCESS_PWIDTH_8: + { + dst = ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(dither_24_to_8((data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF), dst, mystique->dwgreg.dwgctrl_running); + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + } case MACCESS_PWIDTH_32: dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; @@ -3852,13 +3878,39 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); while (size >= 32) { int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + pclog("maccess = 0x%X\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + dst = bitop(dither(mystique, (data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF, mystique->dwgreg.xdst & 1, mystique->dwgreg.selline & 1), dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + } + case MACCESS_PWIDTH_8: + { + dst = ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(dither_24_to_8((data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF), dst, mystique->dwgreg.dwgctrl_running); + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + } + default: { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + } + } } size = 0; From 05bbb2a807000424ab6feae799a6d7c09fd1dc71 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 31 Mar 2024 23:58:15 +0500 Subject: [PATCH 384/690] Modem: Increase phonebook size to 200 entries Also make some string operations (such as phonebook file parsing) safer --- src/network/net_modem.c | 138 +++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 082874f54..4bc056ea1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -74,11 +74,13 @@ typedef enum modem_slip_stage_t MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; +#define NUMBER_BUFFER_SIZE 128 +#define PHONEBOOK_SIZE 200 typedef struct modem_phonebook_entry_t { - char phone[1024]; - char address[1024]; + char phone[NUMBER_BUFFER_SIZE]; + char address[NUMBER_BUFFER_SIZE]; } modem_phonebook_entry_t; typedef struct modem_t @@ -135,7 +137,7 @@ typedef struct modem_t uint8_t command; } telClient; - modem_phonebook_entry_t entries[20]; + modem_phonebook_entry_t entries[PHONEBOOK_SIZE]; uint32_t entries_num; netcard_t *card; @@ -155,39 +157,92 @@ static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); +// https://stackoverflow.com/a/122974 +char *trim(char *str) +{ + size_t len = 0; + char *frontp = str; + char *endp = NULL; + + if( str == NULL ) { return NULL; } + if( str[0] == '\0' ) { return str; } + + len = strlen(str); + endp = str + len; + + /* Move the front and back pointers to address the first non-whitespace + * characters from each end. + */ + while( isspace((unsigned char) *frontp) ) { ++frontp; } + if( endp != frontp ) + { + while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + } + + if( frontp != str && endp == frontp ) + *str = '\0'; + else if( str + len - 1 != endp ) + *(endp + 1) = '\0'; + + /* Shift the string so that it starts at str so that if it's dynamically + * allocated, we can still free it on the returned pointer. Note the reuse + * of endp to mean the front of the string buffer now. + */ + endp = str; + if( frontp != str ) + { + while( *frontp ) { *endp++ = *frontp++; } + *endp = '\0'; + } + + return str; +} + static void modem_read_phonebook_file(modem_t* modem, const char* path) { FILE* file = plat_fopen(path, "r"); - char* buf = NULL; + char* buf = NULL; + char* buf2 = NULL; size_t size = 0; if (!file) return; modem->entries_num = 0; + pclog("Phonebook: Reading file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; - int res = 0; - buf[strcspn(buf, "\r\n")] = 0; + buf[strcspn(buf, "\r\n")] = '\0'; - res = sscanf(buf, "%s %s", entry.phone, entry.address); + /* Remove surrounding whitespace from the input line and find the address part. */ + buf = trim(buf); + buf2 = &buf[strcspn(buf, " \t")]; - if (res == 0 || res == 1) { + /* Remove surrounding whitespace and any extra text from the address part, then store it. */ + buf2 = trim(buf2); + buf2[strcspn(buf2, " \t")] = '\0'; + strncpy(entry.address, buf2, sizeof(entry.address) - 1); + + /* Split the line to get the phone number part, then store it. */ + buf2[0] = '\0'; + strncpy(entry.phone, buf, sizeof(entry.phone) - 1); + + if ((entry.phone[0] == '\0') || (entry.address[0] == '\0')) { /* Appears to be a bad line. */ + pclog("Phonebook: Skipped a bad line\n"); continue; } - if (res == EOF) - break; - if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ + pclog("Phonebook: Invalid character in phone number %s\n", entry.phone); continue; } + pclog("Phonebook: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; - if (modem->entries_num >= 20) + if (modem->entries_num >= PHONEBOOK_SIZE) break; } fclose(file); @@ -573,8 +628,8 @@ modem_dial(modem_t* modem, const char* str) } else { - char buf[128] = ""; - strcpy(buf, str); + char buf[NUMBER_BUFFER_SIZE] = ""; + strncpy(buf, str, sizeof(buf) - 1); // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -615,47 +670,6 @@ is_next_token(const char* a, size_t N, const char *b) return (strncmp(a, b, N_without_null) == 0); } -// https://stackoverflow.com/a/122974 -char *trim(char *str) -{ - size_t len = 0; - char *frontp = str; - char *endp = NULL; - - if( str == NULL ) { return NULL; } - if( str[0] == '\0' ) { return str; } - - len = strlen(str); - endp = str + len; - - /* Move the front and back pointers to address the first non-whitespace - * characters from each end. - */ - while( isspace((unsigned char) *frontp) ) { ++frontp; } - if( endp != frontp ) - { - while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} - } - - if( frontp != str && endp == frontp ) - *str = '\0'; - else if( str + len - 1 != endp ) - *(endp + 1) = '\0'; - - /* Shift the string so that it starts at str so that if it's dynamically - * allocated, we can still free it on the returned pointer. Note the reuse - * of endp to mean the front of the string buffer now. - */ - endp = str; - if( frontp != str ) - { - while( *frontp ) { *endp++ = *frontp++; } - *endp = '\0'; - } - - return str; -} - static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { int i = 0; for (i = 0; i < modem->entries_num; i++) { @@ -710,8 +724,8 @@ modem_do_command(modem_t* modem) modem_send_res(modem, ResERROR); return; case 'D': { // Dial. - char buffer[128]; - char obuffer[128]; + char buffer[NUMBER_BUFFER_SIZE]; + char obuffer[NUMBER_BUFFER_SIZE]; char * foundstr = &scanbuf[0]; const char *mappedaddr = NULL; size_t i = 0; @@ -719,7 +733,8 @@ modem_do_command(modem_t* modem) if (*foundstr == 'T' || *foundstr == 'P') foundstr++; - if ((!foundstr[0]) || (strlen(foundstr) > 253)) { + if ((!foundstr[0]) || (strlen(foundstr) > (NUMBER_BUFFER_SIZE - 1))) { + // Check for empty or too long strings modem_send_res(modem, ResERROR); return; } @@ -739,7 +754,12 @@ modem_do_command(modem_t* modem) for (i = 0; i < fl; i++) if (foundstr[i] < '0' || foundstr[i] > '9') isNum = false; - if (isNum) { + if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { + // Check if the number is long enough to cause buffer + // overflows during the number => IP transformation + modem_send_res(modem, ResERROR); + return; + } else if (isNum) { // Parameter is a number with at least 12 digits => this cannot // be a valid IP/name // Transform by adding dots From b63c1e04ebf655855498953e2d56050ae3ec41fd Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 00:08:47 +0500 Subject: [PATCH 385/690] Modem: Fix escape guard counter never resetting Escape sequence guard timer now actually works --- src/network/net_modem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4bc056ea1..4831faf60 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -391,6 +391,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) modem->plusinc = 0; } } + modem->cmdpause = 0; if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; @@ -597,6 +598,7 @@ modem_reset(modem_t* modem) modem->cmdpos = 0; modem->cmdbuf[0] = 0; modem->flowcontrol = 0; + modem->cmdpause = 0; modem->plusinc = 0; modem->dtrmode = 2; From 2353d1f917dde8053e1d82f7db36cbde3ba03edf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 00:10:45 +0500 Subject: [PATCH 386/690] Modem: Stop command line processing after dialing "Phone numbers" with letters in them, such as hostnames, are no longer interpreted as commands --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4831faf60..42862975f 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -795,7 +795,7 @@ modem_do_command(modem_t* modem) } } modem_dial(modem, foundstr); - break; + return; } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { From 94c917eaaf160d581d9aff051210d59ed355a1c9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:41:21 +0500 Subject: [PATCH 387/690] Modem: Implement `ATD;` (return to command mode after dialing) To simulate the in-progress dialing, the number before the semicolon is appended to a temporary buffer; when an ATD command without a semicolon is issued, the buffer contents are prepended and the complete number is dialed at once. Fixes Windows 98 dialer being stuck if "wait for dial tone" option was enabled. --- src/network/net_modem.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 42862975f..6c0a8a7f1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -105,6 +105,7 @@ typedef struct modem_t Fifo8 data_pending; /* Data yet to be sent to the host. */ char cmdbuf[512]; + char numberinprogress[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; uint32_t port; int plusinc, flowcontrol; @@ -597,6 +598,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->numberinprogress[0] = 0; modem->flowcontrol = 0; modem->cmdpause = 0; modem->plusinc = 0; @@ -626,6 +628,7 @@ modem_dial(modem_t* modem, const char* str) { pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); + modem->numberinprogress[0] = 0; modem->tcpIpMode = false; } else @@ -643,6 +646,7 @@ modem_dial(modem_t* modem, const char* str) port = 23; } + modem->numberinprogress[0] = 0; modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { pclog("Failed to create client socket\n"); @@ -734,15 +738,28 @@ modem_do_command(modem_t* modem) if (*foundstr == 'T' || *foundstr == 'P') foundstr++; - - if ((!foundstr[0]) || (strlen(foundstr) > (NUMBER_BUFFER_SIZE - 1))) { + + if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { // Check for empty or too long strings modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; return; } foundstr = trim(foundstr); + // Check for ; and return to command mode if found + char *semicolon = strchr(foundstr, ';'); + if (semicolon != NULL) { + pclog("Semicolon found in number, returning to command mode\n"); + strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); + scanbuf = semicolon + 1; + break; + } else { + strcat(modem->numberinprogress, foundstr); + foundstr = modem->numberinprogress; + } + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -760,6 +777,7 @@ modem_do_command(modem_t* modem) // Check if the number is long enough to cause buffer // overflows during the number => IP transformation modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; return; } else if (isNum) { // Parameter is a number with at least 12 digits => this cannot @@ -818,6 +836,7 @@ modem_do_command(modem_t* modem) case 'H': // Hang up switch (modem_scan_number(&scanbuf)) { case 0: + modem->numberinprogress[0] = 0; if (modem->connected) { modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); From e64136586663b230e04b39ca6cc0c4ec4bf19930 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:42:55 +0500 Subject: [PATCH 388/690] Modem: Implement `AT&C` (DCD signal control) --- src/network/net_modem.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6c0a8a7f1..e2330ee37 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -110,6 +110,7 @@ typedef struct modem_t uint32_t port; int plusinc, flowcontrol; int in_warmup, dtrmode; + int dcdmode; bool connected, ringing; bool echo, numericresponse; @@ -571,7 +572,7 @@ modem_enter_idle_state(modem_t* modem) serial_set_cts(modem->serial, 1); serial_set_dsr(modem->serial, 1); - serial_set_dcd(modem->serial, 0); + serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); serial_set_ri(modem->serial, 0); } @@ -595,6 +596,7 @@ modem_enter_connected_state(modem_t* modem) void modem_reset(modem_t* modem) { + modem->dcdmode = 1; modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; @@ -930,6 +932,16 @@ modem_do_command(modem_t* modem) case '&': { // & escaped commands char cmdchar = modem_fetch_character(&scanbuf); switch(cmdchar) { + case 'C': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 2) + modem->dcdmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } case 'K': { const uint32_t val = modem_scan_number(&scanbuf); if (val < 5) From ba499b9563aa9870e1294b95d49a43071d4a70ec Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:56:01 +0500 Subject: [PATCH 389/690] Modem: Implement `ATDL` (dial last number) --- src/network/net_modem.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index e2330ee37..82810f97c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -106,6 +106,7 @@ typedef struct modem_t char cmdbuf[512]; char numberinprogress[NUMBER_BUFFER_SIZE]; + char lastnumber[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; uint32_t port; int plusinc, flowcontrol; @@ -600,6 +601,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; modem->flowcontrol = 0; modem->cmdpause = 0; @@ -637,6 +639,7 @@ modem_dial(modem_t* modem, const char* str) { char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); + strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -738,8 +741,17 @@ modem_do_command(modem_t* modem) const char *mappedaddr = NULL; size_t i = 0; - if (*foundstr == 'T' || *foundstr == 'P') + if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing foundstr++; + else if (*foundstr == 'L') { // Redial last number + if (modem->lastnumber[0] == 0) + modem_send_res(modem, ResERROR); + else { + pclog("Redialing number %s\n", modem->lastnumber); + modem_dial(modem, modem->lastnumber); + } + return; + } if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { // Check for empty or too long strings From 9b8680b7cfe953367db0ec9929f7f5fb3e150cc0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 12:49:30 +0500 Subject: [PATCH 390/690] Modem: Implement `A/` (repeat last command) --- src/network/net_modem.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 82810f97c..d0cd636ce 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -74,6 +74,8 @@ typedef enum modem_slip_stage_t MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; + +#define COMMAND_BUFFER_SIZE 512 #define NUMBER_BUFFER_SIZE 128 #define PHONEBOOK_SIZE 200 @@ -104,7 +106,8 @@ typedef struct modem_t Fifo8 data_pending; /* Data yet to be sent to the host. */ - char cmdbuf[512]; + char cmdbuf[COMMAND_BUFFER_SIZE]; + char prevcmdbuf[COMMAND_BUFFER_SIZE]; char numberinprogress[NUMBER_BUFFER_SIZE]; char lastnumber[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; @@ -155,7 +158,7 @@ typedef struct modem_t #define MREG_GUARD_TIME 12 #define MREG_DTR_DELAY 25 -static void modem_do_command(modem_t* modem); +static void modem_do_command(modem_t* modem, int repeat); static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -454,8 +457,15 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) } if (modem->cmdpos == 1 && toupper(txval) != 'T') { - modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); - modem->cmdpos = 0; + if (txval == '/') { + // Repeat the last command. + modem_echo(modem, txval); + pclog("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_do_command(modem, 1); + } else { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + } return; } } else { @@ -474,7 +484,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) if (txval == modem->reg[MREG_CR_CHAR]) { modem_echo(modem, txval); - modem_do_command(modem); + modem_do_command(modem, 0); return; } } @@ -601,6 +611,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->prevcmdbuf[0] = 0; modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; modem->flowcontrol = 0; @@ -692,11 +703,26 @@ static const char *modem_get_address_from_phonebook(modem_t* modem, const char * } static void -modem_do_command(modem_t* modem) +modem_do_command(modem_t* modem, int repeat) { int i = 0; char *scanbuf = NULL; - modem->cmdbuf[modem->cmdpos] = 0; + + if (repeat) { + /* Handle the case of A/ being invoked without a previous command to run */ + if ((modem->prevcmdbuf[0] == '\0')) { + modem_send_res(modem, ResOK); + return; + } + /* Load the stored previous command line */ + strncpy(modem->cmdbuf, modem->prevcmdbuf, sizeof(modem->cmdbuf) - 1); + modem->cmdbuf[COMMAND_BUFFER_SIZE - 1] = '\0'; + } else { + /* Store the command line to be recalled */ + strncpy(modem->prevcmdbuf, modem->cmdbuf, sizeof(modem->prevcmdbuf) - 1); + modem->prevcmdbuf[COMMAND_BUFFER_SIZE - 1] = '\0'; + modem->cmdbuf[modem->cmdpos] = modem->prevcmdbuf[modem->cmdpos] = '\0'; + } modem->cmdpos = 0; for (i = 0; i < sizeof(modem->cmdbuf); i++) { modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); From 93f7705c83fa68f74a061d7ab192a5cfa59b466a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 12:50:23 +0500 Subject: [PATCH 391/690] Modem: Extra logging and misc improvements --- src/network/net_modem.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index d0cd636ce..6554bda0c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -35,6 +35,7 @@ #include <86box/serial.h> #include <86box/plat.h> #include <86box/network.h> +#include <86box/version.h> #include <86box/plat_unused.h> #include <86box/plat_netsocket.h> @@ -523,6 +524,7 @@ void modem_send_res(modem_t* modem, const ResTypes response) { response == ResCONNECT || response == ResNOCARRIER)) { return; } + pclog("Modem response: %s\n", response_str); if (modem->numericresponse && code != ~0) { modem_send_number(modem, code); } else if (response_str != NULL) { @@ -651,6 +653,8 @@ modem_dial(modem_t* modem, const char* str) char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); + pclog("Connecting to %s...\n", buf); + // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -800,6 +804,7 @@ modem_do_command(modem_t* modem, int repeat) foundstr = modem->numberinprogress; } + pclog("Dialing number %s\n", foundstr); mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -858,7 +863,7 @@ modem_do_command(modem_t* modem, int repeat) case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; - case 4: modem_send_line(modem, "Modem compiled for 86Box"); break; + case 4: modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); break; } break; case 'E': // Echo on/off @@ -902,6 +907,8 @@ modem_do_command(modem_t* modem, int repeat) break; case 'M': // Monitor case 'L': // Volume + case 'W': + case 'X': modem_scan_number(&scanbuf); break; case 'A': // Answer call @@ -1039,13 +1046,16 @@ modem_dtr_callback_timer(void* priv) if (dev->connected) { switch (dev->dtrmode) { case 1: + pclog("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; break; case 2: + pclog("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_enter_idle_state(dev); break; case 3: + pclog("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_reset(dev); break; @@ -1388,6 +1398,7 @@ modem_cmdpause_timer_callback(void *priv) if (modem->plusinc == 0) { modem->plusinc = 1; } else if (modem->plusinc == 4) { + pclog("Escape sequence triggered, returning to command mode\n"); modem->mode = MODEM_MODE_COMMAND; modem_send_res(modem, ResOK); modem->plusinc = 0; From 9a8bc1ab080899887e9a70463fff2a4dc64d4a9c Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:08:52 +0500 Subject: [PATCH 392/690] Modem: Disable most logging by default --- src/network/net_modem.c | 60 +++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6554bda0c..b1acbb5ce 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -39,6 +39,24 @@ #include <86box/plat_unused.h> #include <86box/plat_netsocket.h> +#ifdef ENABLE_MODEM_LOG +int modem_do_log = ENABLE_MODEM_LOG; + +static void +modem_log(const char *fmt, ...) +{ + va_list ap; + + if (modem_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define modem_log(fmt, ...) +#endif + /* From RFC 1055. */ #define END 0300 /* indicates end of packet */ #define ESC 0333 /* indicates byte stuffing */ @@ -217,7 +235,7 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem->entries_num = 0; - pclog("Phonebook: Reading file %s...\n", path); + modem_log("Modem: Reading phone book file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; buf[strcspn(buf, "\r\n")] = '\0'; @@ -237,17 +255,17 @@ modem_read_phonebook_file(modem_t* modem, const char* path) if ((entry.phone[0] == '\0') || (entry.address[0] == '\0')) { /* Appears to be a bad line. */ - pclog("Phonebook: Skipped a bad line\n"); + modem_log("Modem: Skipped a bad line\n"); continue; } if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ - pclog("Phonebook: Invalid character in phone number %s\n", entry.phone); + modem_log("Modem: Invalid character in phone number %s\n", entry.phone); continue; } - pclog("Phonebook: Mapped phone number %s to address %s\n", entry.phone, entry.address); + modem_log("Modem: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; if (modem->entries_num >= PHONEBOOK_SIZE) break; @@ -338,7 +356,7 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) uint8_t *processed_tx_packet = calloc(len, 1); uint8_t c = 0; - pclog("Processing SLIP packet of %u bytes\n", len); + modem_log("Processing SLIP packet of %u bytes\n", len); while (pos < len) { c = p[pos]; @@ -461,7 +479,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) if (txval == '/') { // Repeat the last command. modem_echo(modem, txval); - pclog("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); modem_do_command(modem, 1); } else { modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); @@ -524,7 +542,7 @@ void modem_send_res(modem_t* modem, const ResTypes response) { response == ResCONNECT || response == ResNOCARRIER)) { return; } - pclog("Modem response: %s\n", response_str); + modem_log("Modem response: %s\n", response_str); if (modem->numericresponse && code != ~0) { modem_send_number(modem, code); } else if (response_str != NULL) { @@ -643,7 +661,7 @@ modem_dial(modem_t* modem, const char* str) modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { - pclog("Turning on SLIP\n"); + modem_log("Turning on SLIP\n"); modem_enter_connected_state(modem); modem->numberinprogress[0] = 0; modem->tcpIpMode = false; @@ -653,7 +671,7 @@ modem_dial(modem_t* modem, const char* str) char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); - pclog("Connecting to %s...\n", buf); + modem_log("Connecting to %s...\n", buf); // Scan host for port uint16_t port; @@ -738,7 +756,7 @@ modem_do_command(modem_t* modem, int repeat) return; } - pclog("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); + modem_log("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); scanbuf = &modem->cmdbuf[2]; @@ -777,7 +795,7 @@ modem_do_command(modem_t* modem, int repeat) if (modem->lastnumber[0] == 0) modem_send_res(modem, ResERROR); else { - pclog("Redialing number %s\n", modem->lastnumber); + modem_log("Redialing number %s\n", modem->lastnumber); modem_dial(modem, modem->lastnumber); } return; @@ -795,7 +813,7 @@ modem_do_command(modem_t* modem, int repeat) // Check for ; and return to command mode if found char *semicolon = strchr(foundstr, ';'); if (semicolon != NULL) { - pclog("Semicolon found in number, returning to command mode\n"); + modem_log("Semicolon found in number, returning to command mode\n"); strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); scanbuf = semicolon + 1; break; @@ -804,7 +822,7 @@ modem_do_command(modem_t* modem, int repeat) foundstr = modem->numberinprogress; } - pclog("Dialing number %s\n", foundstr); + modem_log("Dialing number %s\n", foundstr); mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -1046,16 +1064,16 @@ modem_dtr_callback_timer(void* priv) if (dev->connected) { switch (dev->dtrmode) { case 1: - pclog("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; break; case 2: - pclog("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_enter_idle_state(dev); break; case 3: - pclog("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_reset(dev); break; @@ -1211,7 +1229,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) if (!modem->connected) { /* Drop packet. */ - pclog("Dropping %d bytes\n", io_len - 14); + modem_log("Dropping %d bytes\n", io_len - 14); return 0; } @@ -1220,11 +1238,11 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } if (!(buf[12] == 0x08 && buf[13] == 0x00)) { - pclog("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); + modem_log("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); return 0; } - pclog("Receiving %d bytes\n", io_len - 14); + modem_log("Receiving %d bytes\n", io_len - 14); /* Strip the Ethernet header. */ io_len -= 14; buf += 14; @@ -1398,7 +1416,7 @@ modem_cmdpause_timer_callback(void *priv) if (modem->plusinc == 0) { modem->plusinc = 1; } else if (modem->plusinc == 4) { - pclog("Escape sequence triggered, returning to command mode\n"); + modem_log("Escape sequence triggered, returning to command mode\n"); modem->mode = MODEM_MODE_COMMAND; modem_send_res(modem, ResOK); modem->plusinc = 0; @@ -1453,6 +1471,7 @@ void modem_close(void *priv) free(priv); } +// clang-format off static const device_config_t modem_config[] = { { .name = "port", @@ -1522,6 +1541,7 @@ static const device_config_t modem_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t modem_device = { .name = "Standard Hayes-compliant Modem", From 0a1e92e239be366c2833470e2c6c11f631d9e2a1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:13:19 +0500 Subject: [PATCH 393/690] clang-format modem and serial passthrough related files --- src/device/serial_passthrough.c | 12 +- src/include/86box/plat_netsocket.h | 19 +- src/network/net_modem.c | 1352 +++++++++++++++------------- src/qt/win_netsocket.c | 84 +- src/qt/win_serial_passthrough.c | 2 +- src/unix/unix_netsocket.c | 94 +- src/unix/unix_serial_passthrough.c | 2 +- 7 files changed, 814 insertions(+), 751 deletions(-) diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index 1b1c5e3bf..eec9fa62a 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -370,12 +370,12 @@ static const device_config_t serial_passthrough_config[] = { // clang-format on const device_t serial_passthrough_device = { - .name = "Serial Passthrough Device", - .flags = 0, - .local = 0, - .init = serial_passthrough_dev_init, - .close = serial_passthrough_dev_close, - .reset = NULL, + .name = "Serial Passthrough Device", + .flags = 0, + .local = 0, + .init = serial_passthrough_dev_init, + .close = serial_passthrough_dev_close, + .reset = NULL, { .poll = NULL }, .speed_changed = serial_passthrough_speed_changed, .force_redraw = NULL, diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h index 9a2181ae1..c994ef9b9 100644 --- a/src/include/86box/plat_netsocket.h +++ b/src/include/86box/plat_netsocket.h @@ -1,24 +1,23 @@ #ifndef _WIN32 -#define SOCKET int +# define SOCKET int #else -#include -#include +# include +# include #endif -enum net_socket_types -{ +enum net_socket_types { /* Only TCP is supported for now. */ NET_SOCKET_TCP }; SOCKET plat_netsocket_create(int type); SOCKET plat_netsocket_create_server(int type, unsigned short port); -void plat_netsocket_close(SOCKET socket); +void plat_netsocket_close(SOCKET socket); SOCKET plat_netsocket_accept(SOCKET socket); -int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); +int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ +int plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port); /* Returns 0 in case of inability to send. -1 in case of errors. */ -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock); -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock); \ No newline at end of file +int plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock); +int plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock); diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b1acbb5ce..0555978af 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -58,89 +58,84 @@ modem_log(const char *fmt, ...) #endif /* From RFC 1055. */ -#define END 0300 /* indicates end of packet */ -#define ESC 0333 /* indicates byte stuffing */ -#define ESC_END 0334 /* ESC ESC_END means END data byte */ -#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ +#define END 0300 /* indicates end of packet */ +#define ESC 0333 /* indicates byte stuffing */ +#define ESC_END 0334 /* ESC ESC_END means END data byte */ +#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ typedef enum ResTypes { - ResNONE, - ResOK, - ResERROR, - ResCONNECT, - ResRING, - ResBUSY, - ResNODIALTONE, - ResNOCARRIER, - ResNOANSWER + ResNONE, + ResOK, + ResERROR, + ResCONNECT, + ResRING, + ResBUSY, + ResNODIALTONE, + ResNOCARRIER, + ResNOANSWER } ResTypes; -enum modem_types -{ +enum modem_types { MODEM_TYPE_SLIP = 1, MODEM_TYPE_PPP = 2, MODEM_TYPE_TCPIP = 3 }; -typedef enum modem_mode_t -{ +typedef enum modem_mode_t { MODEM_MODE_COMMAND = 0, - MODEM_MODE_DATA = 1 + MODEM_MODE_DATA = 1 } modem_mode_t; -typedef enum modem_slip_stage_t -{ +typedef enum modem_slip_stage_t { MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; #define COMMAND_BUFFER_SIZE 512 -#define NUMBER_BUFFER_SIZE 128 -#define PHONEBOOK_SIZE 200 +#define NUMBER_BUFFER_SIZE 128 +#define PHONEBOOK_SIZE 200 -typedef struct modem_phonebook_entry_t -{ +typedef struct modem_phonebook_entry_t { char phone[NUMBER_BUFFER_SIZE]; char address[NUMBER_BUFFER_SIZE]; } modem_phonebook_entry_t; -typedef struct modem_t -{ +typedef struct modem_t { uint8_t mac[6]; serial_t *serial; uint32_t baudrate; modem_mode_t mode; - uint8_t esc_character_expected; + uint8_t esc_character_expected; pc_timer_t host_to_serial_timer; pc_timer_t dtr_timer; pc_timer_t cmdpause_timer; - uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ + uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ uint32_t tx_count; - Fifo8 rx_data; /* Data received from the network. */ - uint8_t reg[100]; + Fifo8 rx_data; /* Data received from the network. */ + uint8_t reg[100]; Fifo8 data_pending; /* Data yet to be sent to the host. */ - char cmdbuf[COMMAND_BUFFER_SIZE]; - char prevcmdbuf[COMMAND_BUFFER_SIZE]; - char numberinprogress[NUMBER_BUFFER_SIZE]; - char lastnumber[NUMBER_BUFFER_SIZE]; - uint32_t cmdpos; + char cmdbuf[COMMAND_BUFFER_SIZE]; + char prevcmdbuf[COMMAND_BUFFER_SIZE]; + char numberinprogress[NUMBER_BUFFER_SIZE]; + char lastnumber[NUMBER_BUFFER_SIZE]; + uint32_t cmdpos; uint32_t port; - int plusinc, flowcontrol; - int in_warmup, dtrmode; - int dcdmode; + int plusinc, flowcontrol; + int in_warmup, dtrmode; + int dcdmode; - bool connected, ringing; - bool echo, numericresponse; - bool tcpIpMode, tcpIpConnInProgress; - bool cooldown; - bool telnet_mode; - bool dtrstate; + bool connected, ringing; + bool echo, numericresponse; + bool tcpIpMode, tcpIpConnInProgress; + bool cooldown; + bool telnet_mode; + bool dtrstate; uint32_t tcpIpConnCounter; int doresponse; @@ -153,82 +148,89 @@ typedef struct modem_t SOCKET waitingclientsocket; struct { - bool binary[2]; - bool echo[2]; - bool supressGA[2]; - bool timingMark[2]; - bool inIAC; - bool recCommand; - uint8_t command; - } telClient; + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + bool inIAC; + bool recCommand; + uint8_t command; + } telClient; modem_phonebook_entry_t entries[PHONEBOOK_SIZE]; - uint32_t entries_num; - + uint32_t entries_num; + netcard_t *card; } modem_t; #define MREG_AUTOANSWER_COUNT 0 -#define MREG_RING_COUNT 1 -#define MREG_ESCAPE_CHAR 2 -#define MREG_CR_CHAR 3 -#define MREG_LF_CHAR 4 -#define MREG_BACKSPACE_CHAR 5 -#define MREG_GUARD_TIME 12 -#define MREG_DTR_DELAY 25 +#define MREG_RING_COUNT 1 +#define MREG_ESCAPE_CHAR 2 +#define MREG_CR_CHAR 3 +#define MREG_LF_CHAR 4 +#define MREG_BACKSPACE_CHAR 5 +#define MREG_GUARD_TIME 12 +#define MREG_DTR_DELAY 25 -static void modem_do_command(modem_t* modem, int repeat); -static void modem_accept_incoming_call(modem_t* modem); +static void modem_do_command(modem_t *modem, int repeat); +static void modem_accept_incoming_call(modem_t *modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); // https://stackoverflow.com/a/122974 -char *trim(char *str) +char * +trim(char *str) { - size_t len = 0; - char *frontp = str; - char *endp = NULL; + size_t len = 0; + char *frontp = str; + char *endp = NULL; - if( str == NULL ) { return NULL; } - if( str[0] == '\0' ) { return str; } + if (str == NULL) { + return NULL; + } + if (str[0] == '\0') { + return str; + } - len = strlen(str); + len = strlen(str); endp = str + len; /* Move the front and back pointers to address the first non-whitespace * characters from each end. */ - while( isspace((unsigned char) *frontp) ) { ++frontp; } - if( endp != frontp ) - { - while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + while (isspace((unsigned char) *frontp)) { + ++frontp; + } + if (endp != frontp) { + while (isspace((unsigned char) *(--endp)) && endp != frontp) { } } - if( frontp != str && endp == frontp ) - *str = '\0'; - else if( str + len - 1 != endp ) - *(endp + 1) = '\0'; + if (frontp != str && endp == frontp) + *str = '\0'; + else if (str + len - 1 != endp) + *(endp + 1) = '\0'; /* Shift the string so that it starts at str so that if it's dynamically * allocated, we can still free it on the returned pointer. Note the reuse * of endp to mean the front of the string buffer now. */ endp = str; - if( frontp != str ) - { - while( *frontp ) { *endp++ = *frontp++; } - *endp = '\0'; + if (frontp != str) { + while (*frontp) { + *endp++ = *frontp++; + } + *endp = '\0'; } return str; } static void -modem_read_phonebook_file(modem_t* modem, const char* path) +modem_read_phonebook_file(modem_t *modem, const char *path) { - FILE* file = plat_fopen(path, "r"); - char* buf = NULL; - char* buf2 = NULL; + FILE *file = plat_fopen(path, "r"); + char *buf = NULL; + char *buf2 = NULL; size_t size = 0; if (!file) return; @@ -238,14 +240,14 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem_log("Modem: Reading phone book file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; - buf[strcspn(buf, "\r\n")] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; /* Remove surrounding whitespace from the input line and find the address part. */ - buf = trim(buf); + buf = trim(buf); buf2 = &buf[strcspn(buf, " \t")]; /* Remove surrounding whitespace and any extra text from the address part, then store it. */ - buf2 = trim(buf2); + buf2 = trim(buf2); buf2[strcspn(buf2, " \t")] = '\0'; strncpy(entry.address, buf2, sizeof(entry.address) - 1); @@ -264,7 +266,7 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem_log("Modem: Invalid character in phone number %s\n", entry.phone); continue; } - + modem_log("Modem: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; if (modem->entries_num >= PHONEBOOK_SIZE) @@ -274,36 +276,37 @@ modem_read_phonebook_file(modem_t* modem, const char* path) } static void -modem_echo(modem_t* modem, uint8_t c) +modem_echo(modem_t *modem, uint8_t c) { - if (modem->echo && fifo8_num_free(&modem->data_pending)) fifo8_push(&modem->data_pending, c); + if (modem->echo && fifo8_num_free(&modem->data_pending)) + fifo8_push(&modem->data_pending, c); } static uint32_t modem_scan_number(char **scan) { - char c = 0; - uint32_t ret = 0; - while (1) { + char c = 0; + uint32_t ret = 0; + while (1) { c = **scan; if (c == 0) break; - if (c >= '0' && c <= '9') { - ret*=10; - ret+=c-'0'; - *scan = *scan + 1; - } else - break; - } - return ret; + if (c >= '0' && c <= '9') { + ret *= 10; + ret += c - '0'; + *scan = *scan + 1; + } else + break; + } + return ret; } static uint8_t modem_fetch_character(char **scan) { uint8_t c = **scan; - *scan = *scan + 1; - return c; + *scan = *scan + 1; + return c; } static void @@ -315,37 +318,36 @@ modem_speed_changed(void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baudrate) * 9); #if 0 serial_clear_fifo(dev->serial); #endif } static void -modem_send_line(modem_t* modem, const char* line) +modem_send_line(modem_t *modem, const char *line) { fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); - fifo8_push_all(&modem->data_pending, (uint8_t*)line, strlen(line)); + fifo8_push_all(&modem->data_pending, (uint8_t *) line, strlen(line)); fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); } - static void -modem_send_number(modem_t* modem, uint32_t val) +modem_send_number(modem_t *modem, uint32_t val) { - fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); - fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); - fifo8_push(&modem->data_pending, val / 100 + '0'); - val = val%100; - fifo8_push(&modem->data_pending, val / 10 + '0'); - val = val%10; - fifo8_push(&modem->data_pending, val + '0'); + fifo8_push(&modem->data_pending, val / 100 + '0'); + val = val % 100; + fifo8_push(&modem->data_pending, val / 10 + '0'); + val = val % 10; + fifo8_push(&modem->data_pending, val + '0'); - fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); - fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); } static void @@ -391,13 +393,12 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) } send_tx_packet: - if (received) - { - uint8_t* buf = calloc(received + 14, 1); + if (received) { + uint8_t *buf = calloc(received + 14, 1); buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = 0xFF; buf[6] = buf[7] = buf[8] = buf[9] = buf[10] = buf[11] = 0xFC; - buf[12] = 0x08; - buf[13] = 0x00; + buf[12] = 0x08; + buf[13] = 0x00; memcpy(buf + 14, processed_tx_packet, received); network_tx(modem->card, buf, received + 14); free(buf); @@ -407,7 +408,7 @@ send_tx_packet: } static void -modem_data_mode_process_byte(modem_t* modem, uint8_t data) +modem_data_mode_process_byte(modem_t *modem, uint8_t data) { if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { if (modem->plusinc >= 1 && modem->plusinc <= 3 && modem->reg[MREG_ESCAPE_CHAR] == data) { @@ -421,7 +422,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; if (data == END && !modem->tcpIpMode) { - process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t) modem->tx_count); modem->tx_count = 0; } } @@ -430,7 +431,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) static void host_to_modem_cb(void *priv) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; if (modem->in_warmup) goto no_write_to_machine; @@ -460,143 +461,169 @@ host_to_modem_cb(void *priv) } no_write_to_machine: - timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double) modem->baudrate) * (double) 9); } static void modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; if (modem->mode == MODEM_MODE_COMMAND) { if (modem->cmdpos < 2) { - // Ignore everything until we see "AT" sequence. - if (modem->cmdpos == 0 && toupper(txval) != 'A') { - return; - } + // Ignore everything until we see "AT" sequence. + if (modem->cmdpos == 0 && toupper(txval) != 'A') { + return; + } - if (modem->cmdpos == 1 && toupper(txval) != 'T') { - if (txval == '/') { - // Repeat the last command. - modem_echo(modem, txval); - modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); - modem_do_command(modem, 1); - } else { - modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); - modem->cmdpos = 0; - } - return; - } + if (modem->cmdpos == 1 && toupper(txval) != 'T') { + if (txval == '/') { + // Repeat the last command. + modem_echo(modem, txval); + modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_do_command(modem, 1); + } else { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + } + return; + } } else { - // Now entering command. - if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { - if (modem->cmdpos > 2) { - modem_echo(modem, txval); - modem->cmdpos--; - } - return; - } + // Now entering command. + if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { + if (modem->cmdpos > 2) { + modem_echo(modem, txval); + modem->cmdpos--; + } + return; + } - if (txval == modem->reg[MREG_LF_CHAR]) { - return; // Real modem doesn't seem to skip this? - } + if (txval == modem->reg[MREG_LF_CHAR]) { + return; // Real modem doesn't seem to skip this? + } - if (txval == modem->reg[MREG_CR_CHAR]) { - modem_echo(modem, txval); - modem_do_command(modem, 0); - return; - } - } + if (txval == modem->reg[MREG_CR_CHAR]) { + modem_echo(modem, txval); + modem_do_command(modem, 0); + return; + } + } if (modem->cmdpos < 99) { - modem_echo(modem, txval); - modem->cmdbuf[modem->cmdpos] = txval; - modem->cmdpos++; - } + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; + } } else { modem_data_mode_process_byte(modem, txval); } } -void modem_send_res(modem_t* modem, const ResTypes response) { - char response_str_connect[256] = { 0 }; - const char* response_str = NULL; - uint32_t code = -1; +void +modem_send_res(modem_t *modem, const ResTypes response) +{ + char response_str_connect[256] = { 0 }; + const char *response_str = NULL; + uint32_t code = -1; snprintf(response_str_connect, sizeof(response_str_connect), "CONNECT %u", modem->baudrate); - switch (response) { - case ResOK: code = 0; response_str = "OK"; break; - case ResCONNECT: code = 1; response_str = response_str_connect; break; - case ResRING: code = 2; response_str = "RING"; break; - case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; - case ResERROR: code = 4; response_str = "ERROR"; break; - case ResNODIALTONE: code = 6; response_str = "NO DIALTONE"; break; - case ResBUSY: code = 7; response_str = "BUSY"; break; - case ResNOANSWER: code = 8; response_str = "NO ANSWER"; break; - case ResNONE: return; - } + switch (response) { + case ResOK: + code = 0; + response_str = "OK"; + break; + case ResCONNECT: + code = 1; + response_str = response_str_connect; + break; + case ResRING: + code = 2; + response_str = "RING"; + break; + case ResNOCARRIER: + code = 3; + response_str = "NO CARRIER"; + break; + case ResERROR: + code = 4; + response_str = "ERROR"; + break; + case ResNODIALTONE: + code = 6; + response_str = "NO DIALTONE"; + break; + case ResBUSY: + code = 7; + response_str = "BUSY"; + break; + case ResNOANSWER: + code = 8; + response_str = "NO ANSWER"; + break; + case ResNONE: + return; + } - if (modem->doresponse != 1) { - if (modem->doresponse == 2 && (response == ResRING || - response == ResCONNECT || response == ResNOCARRIER)) { - return; - } - modem_log("Modem response: %s\n", response_str); - if (modem->numericresponse && code != ~0) { - modem_send_number(modem, code); - } else if (response_str != NULL) { - modem_send_line(modem, response_str); - } + if (modem->doresponse != 1) { + if (modem->doresponse == 2 && (response == ResRING || response == ResCONNECT || response == ResNOCARRIER)) { + return; + } + modem_log("Modem response: %s\n", response_str); + if (modem->numericresponse && code != ~0) { + modem_send_number(modem, code); + } else if (response_str != NULL) { + modem_send_line(modem, response_str); + } - // if(CSerial::CanReceiveByte()) // very fast response - // if(rqueue->inuse() && CSerial::getRTS()) - // { uint8_t rbyte =rqueue->getb(); - // CSerial::receiveByte(rbyte); - // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", - // GetPortNumber(), rbyte); - // } - } + // if(CSerial::CanReceiveByte()) // very fast response + // if(rqueue->inuse() && CSerial::getRTS()) + // { uint8_t rbyte =rqueue->getb(); + // CSerial::receiveByte(rbyte); + // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", + // GetPortNumber(), rbyte); + // } + } } void -modem_enter_idle_state(modem_t* modem) +modem_enter_idle_state(modem_t *modem) { timer_disable(&modem->dtr_timer); - modem->connected = false; - modem->ringing = false; - modem->mode = MODEM_MODE_COMMAND; - modem->in_warmup = 0; + modem->connected = false; + modem->ringing = false; + modem->mode = MODEM_MODE_COMMAND; + modem->in_warmup = 0; modem->tcpIpConnInProgress = 0; - modem->tcpIpConnCounter = 0; + modem->tcpIpConnCounter = 0; - if (modem->waitingclientsocket != (SOCKET)-1) + if (modem->waitingclientsocket != (SOCKET) -1) plat_netsocket_close(modem->waitingclientsocket); - - if (modem->clientsocket != (SOCKET)-1) + + if (modem->clientsocket != (SOCKET) -1) plat_netsocket_close(modem->clientsocket); - modem->clientsocket = modem->waitingclientsocket = (SOCKET)-1; - if (modem->serversocket != (SOCKET)-1) { + modem->clientsocket = modem->waitingclientsocket = (SOCKET) -1; + if (modem->serversocket != (SOCKET) -1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); - while (modem->waitingclientsocket != (SOCKET)-1) { + while (modem->waitingclientsocket != (SOCKET) -1) { plat_netsocket_close(modem->waitingclientsocket); modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); } plat_netsocket_close(modem->serversocket); - modem->serversocket = (SOCKET)-1; + modem->serversocket = (SOCKET) -1; } - if (modem->waitingclientsocket != (SOCKET)-1) + if (modem->waitingclientsocket != (SOCKET) -1) plat_netsocket_close(modem->waitingclientsocket); - modem->waitingclientsocket = (SOCKET)-1; - modem->tcpIpMode = false; + modem->waitingclientsocket = (SOCKET) -1; + modem->tcpIpMode = false; modem->tcpIpConnInProgress = false; if (modem->listen_port) { modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); - if (modem->serversocket == (SOCKET)-1) { + if (modem->serversocket == (SOCKET) -1) { pclog("Failed to set up server on port %d\n", modem->listen_port); } } @@ -608,15 +635,15 @@ modem_enter_idle_state(modem_t* modem) } void -modem_enter_connected_state(modem_t* modem) +modem_enter_connected_state(modem_t *modem) { modem_send_res(modem, ResCONNECT); - modem->mode = MODEM_MODE_DATA; - modem->ringing = false; + modem->mode = MODEM_MODE_DATA; + modem->ringing = false; modem->connected = true; modem->tcpIpMode = true; - modem->cooldown = true; - modem->tx_count = 0; + modem->cooldown = true; + modem->tx_count = 0; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); @@ -625,49 +652,46 @@ modem_enter_connected_state(modem_t* modem) } void -modem_reset(modem_t* modem) +modem_reset(modem_t *modem) { modem->dcdmode = 1; modem_enter_idle_state(modem); - modem->cmdpos = 0; - modem->cmdbuf[0] = 0; - modem->prevcmdbuf[0] = 0; - modem->lastnumber[0] = 0; + modem->cmdpos = 0; + modem->cmdbuf[0] = 0; + modem->prevcmdbuf[0] = 0; + modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; - modem->flowcontrol = 0; - modem->cmdpause = 0; - modem->plusinc = 0; - modem->dtrmode = 2; + modem->flowcontrol = 0; + modem->cmdpause = 0; + modem->plusinc = 0; + modem->dtrmode = 2; - memset(&modem->reg,0,sizeof(modem->reg)); - modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer - modem->reg[MREG_RING_COUNT] = 1; - modem->reg[MREG_ESCAPE_CHAR] = '+'; - modem->reg[MREG_CR_CHAR] = '\r'; - modem->reg[MREG_LF_CHAR] = '\n'; - modem->reg[MREG_BACKSPACE_CHAR] = '\b'; - modem->reg[MREG_GUARD_TIME] = 50; - modem->reg[MREG_DTR_DELAY] = 5; + memset(&modem->reg, 0, sizeof(modem->reg)); + modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer + modem->reg[MREG_RING_COUNT] = 1; + modem->reg[MREG_ESCAPE_CHAR] = '+'; + modem->reg[MREG_CR_CHAR] = '\r'; + modem->reg[MREG_LF_CHAR] = '\n'; + modem->reg[MREG_BACKSPACE_CHAR] = '\b'; + modem->reg[MREG_GUARD_TIME] = 50; + modem->reg[MREG_DTR_DELAY] = 5; - modem->echo = true; - modem->doresponse = 0; - modem->numericresponse = false; + modem->echo = true; + modem->doresponse = 0; + modem->numericresponse = false; } void -modem_dial(modem_t* modem, const char* str) +modem_dial(modem_t *modem, const char *str) { modem->tcpIpConnCounter = 0; - modem->tcpIpMode = false; - if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) - { + modem->tcpIpMode = false; + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { modem_log("Turning on SLIP\n"); modem_enter_connected_state(modem); modem->numberinprogress[0] = 0; - modem->tcpIpMode = false; - } - else - { + modem->tcpIpMode = false; + } else { char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); @@ -675,59 +699,60 @@ modem_dial(modem_t* modem, const char* str) // Scan host for port uint16_t port; - char * hasport = strrchr(buf,':'); + char *hasport = strrchr(buf, ':'); if (hasport) { *hasport++ = 0; - port = (uint16_t)atoi(hasport); - } - else { + port = (uint16_t) atoi(hasport); + } else { port = 23; } modem->numberinprogress[0] = 0; - modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); + modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { pclog("Failed to create client socket\n"); - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); return; } if (-1 == plat_netsocket_connect(modem->clientsocket, buf, port)) { pclog("Failed to connect to %s\n", buf); - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); return; } modem->tcpIpConnInProgress = 1; - modem->tcpIpConnCounter = 0; + modem->tcpIpConnCounter = 0; } } static bool -is_next_token(const char* a, size_t N, const char *b) +is_next_token(const char *a, size_t N, const char *b) { - // Is 'b' at least as long as 'a'? - size_t N_without_null = N - 1; - if (strnlen(b, N) < N_without_null) - return false; - return (strncmp(a, b, N_without_null) == 0); + // Is 'b' at least as long as 'a'? + size_t N_without_null = N - 1; + if (strnlen(b, N) < N_without_null) + return false; + return (strncmp(a, b, N_without_null) == 0); } -static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { +static const char * +modem_get_address_from_phonebook(modem_t *modem, const char *input) +{ int i = 0; - for (i = 0; i < modem->entries_num; i++) { - if (strcmp(input, modem->entries[i].phone) == 0) - return modem->entries[i].address; - } + for (i = 0; i < modem->entries_num; i++) { + if (strcmp(input, modem->entries[i].phone) == 0) + return modem->entries[i].address; + } - return NULL; + return NULL; } static void -modem_do_command(modem_t* modem, int repeat) +modem_do_command(modem_t *modem, int repeat) { - int i = 0; + int i = 0; char *scanbuf = NULL; if (repeat) { @@ -750,11 +775,11 @@ modem_do_command(modem_t* modem, int repeat) modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); } - /* AT command set interpretation */ - if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { - modem_send_res(modem, ResERROR); - return; - } + /* AT command set interpretation */ + if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { + modem_send_res(modem, ResERROR); + return; + } modem_log("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); @@ -782,142 +807,159 @@ modem_do_command(modem_t* modem, int repeat) } modem_send_res(modem, ResERROR); return; - case 'D': { // Dial. - char buffer[NUMBER_BUFFER_SIZE]; - char obuffer[NUMBER_BUFFER_SIZE]; - char * foundstr = &scanbuf[0]; - const char *mappedaddr = NULL; - size_t i = 0; + case 'D': + { // Dial. + char buffer[NUMBER_BUFFER_SIZE]; + char obuffer[NUMBER_BUFFER_SIZE]; + char *foundstr = &scanbuf[0]; + const char *mappedaddr = NULL; + size_t i = 0; - if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing - foundstr++; - else if (*foundstr == 'L') { // Redial last number - if (modem->lastnumber[0] == 0) - modem_send_res(modem, ResERROR); - else { - modem_log("Redialing number %s\n", modem->lastnumber); - modem_dial(modem, modem->lastnumber); + if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing + foundstr++; + else if (*foundstr == 'L') { // Redial last number + if (modem->lastnumber[0] == 0) + modem_send_res(modem, ResERROR); + else { + modem_log("Redialing number %s\n", modem->lastnumber); + modem_dial(modem, modem->lastnumber); + } + return; } - return; - } - if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { - // Check for empty or too long strings - modem_send_res(modem, ResERROR); - modem->numberinprogress[0] = 0; - return; - } - - foundstr = trim(foundstr); - - // Check for ; and return to command mode if found - char *semicolon = strchr(foundstr, ';'); - if (semicolon != NULL) { - modem_log("Semicolon found in number, returning to command mode\n"); - strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); - scanbuf = semicolon + 1; - break; - } else { - strcat(modem->numberinprogress, foundstr); - foundstr = modem->numberinprogress; - } - - modem_log("Dialing number %s\n", foundstr); - mappedaddr = modem_get_address_from_phonebook(modem, foundstr); - if (mappedaddr) { - modem_dial(modem, mappedaddr); - return; - } - - if (strlen(foundstr) >= 12) { - // Check if supplied parameter only consists of digits - bool isNum = true; - size_t fl = strlen(foundstr); - for (i = 0; i < fl; i++) - if (foundstr[i] < '0' || foundstr[i] > '9') - isNum = false; - if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { - // Check if the number is long enough to cause buffer - // overflows during the number => IP transformation + if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { + // Check for empty or too long strings modem_send_res(modem, ResERROR); modem->numberinprogress[0] = 0; return; - } else if (isNum) { - // Parameter is a number with at least 12 digits => this cannot - // be a valid IP/name - // Transform by adding dots - size_t j = 0; - const size_t foundlen = strlen(foundstr); - for (i = 0; i < foundlen; i++) { - buffer[j++] = foundstr[i]; - // Add a dot after the third, sixth and ninth number - if (i == 2 || i == 5 || i == 8) - buffer[j++] = '.'; - // If the string is longer than 12 digits, - // interpret the rest as port - if (i == 11 && foundlen > 12) - buffer[j++] = ':'; - } - buffer[j] = 0; - foundstr = buffer; - - // Remove Zeros from beginning of octets - size_t k = 0; - size_t foundlen2 = strlen(foundstr); - for (i = 0; i < foundlen2; i++) { - if (i == 0 && foundstr[0] == '0') continue; - if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') continue; - if (foundstr[i] == '0' && foundstr[i-1] == '.') continue; - if (foundstr[i] == '0' && foundstr[i-1] == '0' && foundstr[i-2] == '.') continue; - obuffer[k++] = foundstr[i]; - } - obuffer[k] = 0; - foundstr = obuffer; } + + foundstr = trim(foundstr); + + // Check for ; and return to command mode if found + char *semicolon = strchr(foundstr, ';'); + if (semicolon != NULL) { + modem_log("Semicolon found in number, returning to command mode\n"); + strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); + scanbuf = semicolon + 1; + break; + } else { + strcat(modem->numberinprogress, foundstr); + foundstr = modem->numberinprogress; + } + + modem_log("Dialing number %s\n", foundstr); + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); + if (mappedaddr) { + modem_dial(modem, mappedaddr); + return; + } + + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + size_t fl = strlen(foundstr); + for (i = 0; i < fl; i++) + if (foundstr[i] < '0' || foundstr[i] > '9') + isNum = false; + if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { + // Check if the number is long enough to cause buffer + // overflows during the number => IP transformation + modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; + return; + } else if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + size_t j = 0; + const size_t foundlen = strlen(foundstr); + for (i = 0; i < foundlen; i++) { + buffer[j++] = foundstr[i]; + // Add a dot after the third, sixth and ninth number + if (i == 2 || i == 5 || i == 8) + buffer[j++] = '.'; + // If the string is longer than 12 digits, + // interpret the rest as port + if (i == 11 && foundlen > 12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + + // Remove Zeros from beginning of octets + size_t k = 0; + size_t foundlen2 = strlen(foundstr); + for (i = 0; i < foundlen2; i++) { + if (i == 0 && foundstr[0] == '0') + continue; + if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') + continue; + if (foundstr[i] == '0' && foundstr[i - 1] == '.') + continue; + if (foundstr[i] == '0' && foundstr[i - 1] == '0' && foundstr[i - 2] == '.') + continue; + obuffer[k++] = foundstr[i]; + } + obuffer[k] = 0; + foundstr = obuffer; + } + } + modem_dial(modem, foundstr); + return; } - modem_dial(modem, foundstr); - return; - } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { - case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; - case 4: modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); break; + case 3: + modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); + break; + case 4: + modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); + break; } break; case 'E': // Echo on/off switch (modem_scan_number(&scanbuf)) { - case 0: modem->echo = false; break; - case 1: modem->echo = true; break; + case 0: + modem->echo = false; + break; + case 1: + modem->echo = true; + break; } break; case 'V': switch (modem_scan_number(&scanbuf)) { - case 0: modem->numericresponse = true; break; - case 1: modem->numericresponse = false; break; + case 0: + modem->numericresponse = true; + break; + case 1: + modem->numericresponse = false; + break; } break; case 'H': // Hang up switch (modem_scan_number(&scanbuf)) { - case 0: - modem->numberinprogress[0] = 0; - if (modem->connected) { - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); - return; - } - // else return ok + case 0: + modem->numberinprogress[0] = 0; + if (modem->connected) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + // else return ok } break; case 'O': // Return to data mode switch (modem_scan_number(&scanbuf)) { - case 0: - if (modem->connected) { - modem->mode = MODEM_MODE_DATA; - return; - } else { - modem_send_res(modem, ResERROR); - return; - } + case 0: + if (modem->connected) { + modem->mode = MODEM_MODE_DATA; + return; + } else { + modem_send_res(modem, ResERROR); + return; + } } break; case 'T': // Tone Dial @@ -939,130 +981,137 @@ modem_do_command(modem_t* modem, int repeat) break; } return; - case 'Z': { // Reset and load profiles - // scan the number away, if any - modem_scan_number(&scanbuf); - if (modem->connected) - modem_send_res(modem, ResNOCARRIER); - modem_reset(modem); - break; - } + case 'Z': + { // Reset and load profiles + // scan the number away, if any + modem_scan_number(&scanbuf); + if (modem->connected) + modem_send_res(modem, ResNOCARRIER); + modem_reset(modem); + break; + } case ' ': // skip space break; - case 'Q': { - // Response options - // 0 = all on, 1 = all off, - // 2 = no ring and no connect/carrier in answermode - const uint32_t val = modem_scan_number(&scanbuf); - if (!(val > 2)) { - modem->doresponse = val; - break; - } else { - modem_send_res(modem, ResERROR); - return; + case 'Q': + { + // Response options + // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + const uint32_t val = modem_scan_number(&scanbuf); + if (!(val > 2)) { + modem->doresponse = val; + break; + } else { + modem_send_res(modem, ResERROR); + return; + } } - } - case 'S': { // Registers - const uint32_t index = modem_scan_number(&scanbuf); - if (index >= 100) { - modem_send_res(modem, ResERROR); - return; //goto ret_none; - } + case 'S': + { // Registers + const uint32_t index = modem_scan_number(&scanbuf); + if (index >= 100) { + modem_send_res(modem, ResERROR); + return; // goto ret_none; + } - while (scanbuf[0] == ' ') - scanbuf++; // skip spaces + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces - if (scanbuf[0] == '=') { // set register - scanbuf++; - while (scanbuf[0] == ' ') - scanbuf++; // skip spaces - const uint32_t val = modem_scan_number(&scanbuf); - modem->reg[index] = val; - break; - } - else if (scanbuf[0] == '?') { // get register - modem_send_number(modem, modem->reg[index]); - scanbuf++; - break; - } - // else - // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 - // " with %" PRIu8 ".", - // GetPortNumber(), index, reg[index]); - } - break; - case '&': { // & escaped commands - char cmdchar = modem_fetch_character(&scanbuf); - switch(cmdchar) { - case 'C': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 2) - modem->dcdmode = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case 'K': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 5) - modem->flowcontrol = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case 'D': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 4) - modem->dtrmode = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case '\0': - // end of string - modem_send_res(modem, ResERROR); - return; - } - break; - } - break; - case '\\': { // \ escaped commands - char cmdchar = modem_fetch_character(&scanbuf); - switch (cmdchar) { - case 'N': - // error correction stuff - not emulated - if (modem_scan_number(&scanbuf) > 5) { - modem_send_res(modem, ResERROR); - return; - } - break; - case '\0': - // end of string - modem_send_res(modem, ResERROR); - return; - } - break; - } - case '\0': - modem_send_res(modem, ResOK); - return; - } + if (scanbuf[0] == '=') { // set register + scanbuf++; + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + const uint32_t val = modem_scan_number(&scanbuf); + modem->reg[index] = val; + break; + } else if (scanbuf[0] == '?') { // get register + modem_send_number(modem, modem->reg[index]); + scanbuf++; + break; + } + // else + // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 + // " with %" PRIu8 ".", + // GetPortNumber(), index, reg[index]); + } + break; + case '&': + { // & escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'C': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 2) + modem->dcdmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'K': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 5) + modem->flowcontrol = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'D': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 4) + modem->dtrmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + break; + case '\\': + { // \ escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'N': + // error correction stuff - not emulated + if (modem_scan_number(&scanbuf) > 5) { + modem_send_res(modem, ResERROR); + return; + } + break; + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + modem_send_res(modem, ResOK); + return; + } } } void -modem_dtr_callback_timer(void* priv) +modem_dtr_callback_timer(void *priv) { modem_t *dev = (modem_t *) priv; if (dev->connected) { - switch (dev->dtrmode) { + switch (dev->dtrmode) { case 1: modem_log("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; @@ -1082,9 +1131,9 @@ modem_dtr_callback_timer(void* priv) } void -modem_dtr_callback(serial_t* serial, int status, void *priv) +modem_dtr_callback(serial_t *serial, int status, void *priv) { - modem_t *dev = (modem_t *) priv; + modem_t *dev = (modem_t *) priv; dev->dtrstate = !!status; if (status == 1) timer_disable(&dev->dtr_timer); @@ -1093,15 +1142,15 @@ modem_dtr_callback(serial_t* serial, int status, void *priv) } static void -fifo8_resize_2x(Fifo8* fifo) +fifo8_resize_2x(Fifo8 *fifo) { - uint32_t pos = 0; + uint32_t pos = 0; uint32_t size = fifo->capacity * 2; uint32_t used = fifo8_num_used(fifo); if (!used) return; - uint8_t* temp_buf = calloc(fifo->capacity * 2, 1); + uint8_t *temp_buf = calloc(fifo->capacity * 2, 1); if (!temp_buf) { fatal("net_modem: Out Of Memory!\n"); } @@ -1118,111 +1167,117 @@ fifo8_resize_2x(Fifo8* fifo) #define TEL_CLIENT 0 #define TEL_SERVER 1 -void modem_process_telnet(modem_t* modem, uint8_t *data, uint32_t size) +void +modem_process_telnet(modem_t *modem, uint8_t *data, uint32_t size) { uint32_t i = 0; - for (i = 0; i < size; i++) { - uint8_t c = data[i]; - if (modem->telClient.inIAC) { - if (modem->telClient.recCommand) { - if ((c != 0) && (c != 1) && (c != 3)) { - if (modem->telClient.command > 250) { - /* Reject anything we don't recognize */ - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, c); /* We won't do crap! */ - } - } - switch (modem->telClient.command) { - case 251: /* Will */ - if (c == 0) modem->telClient.binary[TEL_SERVER] = true; - if (c == 1) modem->telClient.echo[TEL_SERVER] = true; - if (c == 3) modem->telClient.supressGA[TEL_SERVER] = true; - break; - case 252: /* Won't */ - if (c == 0) modem->telClient.binary[TEL_SERVER] = false; - if (c == 1) modem->telClient.echo[TEL_SERVER] = false; - if (c == 3) modem->telClient.supressGA[TEL_SERVER] = false; - break; - case 253: /* Do */ - if (c == 0) { - modem->telClient.binary[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ - } - if (c == 1) { - modem->telClient.echo[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ - } - if (c == 3) { - modem->telClient.supressGA[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ - } - break; - case 254: /* Don't */ - if (c == 0) { - modem->telClient.binary[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ - } - if (c == 1) { - modem->telClient.echo[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ - } - if (c == 3) { - modem->telClient.supressGA[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ - } - break; - default: - break; - } - modem->telClient.inIAC = false; - modem->telClient.recCommand = false; - continue; - } else { - if (c == 249) { - /* Go Ahead received */ - modem->telClient.inIAC = false; - continue; - } - modem->telClient.command = c; - modem->telClient.recCommand = true; + for (i = 0; i < size; i++) { + uint8_t c = data[i]; + if (modem->telClient.inIAC) { + if (modem->telClient.recCommand) { + if ((c != 0) && (c != 1) && (c != 3)) { + if (modem->telClient.command > 250) { + /* Reject anything we don't recognize */ + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, c); /* We won't do crap! */ + } + } + switch (modem->telClient.command) { + case 251: /* Will */ + if (c == 0) + modem->telClient.binary[TEL_SERVER] = true; + if (c == 1) + modem->telClient.echo[TEL_SERVER] = true; + if (c == 3) + modem->telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if (c == 0) + modem->telClient.binary[TEL_SERVER] = false; + if (c == 1) + modem->telClient.echo[TEL_SERVER] = false; + if (c == 3) + modem->telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ + } + break; + default: + break; + } + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + continue; + } else { + if (c == 249) { + /* Go Ahead received */ + modem->telClient.inIAC = false; + continue; + } + modem->telClient.command = c; + modem->telClient.recCommand = true; - if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { - /* Binary data with value of 255 */ - modem->telClient.inIAC = false; - modem->telClient.recCommand = false; - fifo8_push(&modem->rx_data, 0xff); - continue; - } - } - } else { - if (c == 0xff) { - modem->telClient.inIAC = true; - continue; - } - fifo8_push(&modem->rx_data, c); - } - } + if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + fifo8_push(&modem->rx_data, 0xff); + continue; + } + } + } else { + if (c == 0xff) { + modem->telClient.inIAC = true; + continue; + } + fifo8_push(&modem->rx_data, c); + } + } } static int modem_rx(void *priv, uint8_t *buf, int io_len) { -#if 1 - modem_t* modem = (modem_t*)priv; - uint32_t i = 0; + modem_t *modem = (modem_t *) priv; + uint32_t i = 0; if (modem->tcpIpMode) return 0; @@ -1265,7 +1320,6 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } fifo8_push(&modem->rx_data, END); return 1; -#endif } static void @@ -1275,17 +1329,17 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * (double) 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baudrate) * (double) 9); #if 0 serial_clear_fifo(dev->serial); #endif } static void -modem_accept_incoming_call(modem_t* modem) +modem_accept_incoming_call(modem_t *modem) { if (modem->waitingclientsocket != -1) { - modem->clientsocket = modem->waitingclientsocket; + modem->clientsocket = modem->waitingclientsocket; modem->waitingclientsocket = -1; modem_enter_connected_state(modem); modem->in_warmup = 250; @@ -1297,8 +1351,8 @@ modem_accept_incoming_call(modem_t* modem) static void modem_cmdpause_timer_callback(void *priv) { - modem_t *modem = (modem_t *) priv; - uint32_t guard_threashold = 0; + modem_t *modem = (modem_t *) priv; + uint32_t guard_threshold = 0; timer_on_auto(&modem->cmdpause_timer, 1000); if (modem->tcpIpConnInProgress) { @@ -1326,7 +1380,7 @@ modem_cmdpause_timer_callback(void *priv) modem_enter_idle_state(modem); modem_send_res(modem, ResNOANSWER); modem->tcpIpConnInProgress = 0; - modem->tcpIpMode = 0; + modem->tcpIpMode = 0; break; } } while (0); @@ -1341,26 +1395,25 @@ modem_cmdpause_timer_callback(void *priv) modem->ringing = true; modem_send_res(modem, ResRING); serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - modem->ringtimer = 3000; + modem->ringtimer = 3000; modem->reg[MREG_RING_COUNT] = 0; } } } - if (modem->ringing) { - if (modem->ringtimer <= 0) { - modem->reg[MREG_RING_COUNT]++; - if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && - (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { - modem_accept_incoming_call(modem); - return; - } - modem_send_res(modem, ResRING); + if (modem->ringing) { + if (modem->ringtimer <= 0) { + modem->reg[MREG_RING_COUNT]++; + if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(modem); + return; + } + modem_send_res(modem, ResRING); serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - modem->ringtimer = 3000; - } - --modem->ringtimer; - } + modem->ringtimer = 3000; + } + --modem->ringtimer; + } if (modem->in_warmup) { modem->in_warmup--; @@ -1368,12 +1421,11 @@ modem_cmdpause_timer_callback(void *priv) modem->tx_count = 0; fifo8_reset(&modem->rx_data); } - } - else if (modem->connected && modem->tcpIpMode) { + } else if (modem->connected && modem->tcpIpMode) { if (modem->tx_count) { int wouldblock = 0; - int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); - + int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); + if (res <= 0 && !wouldblock) { /* No bytes sent or error. */ modem->tx_count = 0; @@ -1390,8 +1442,8 @@ modem_cmdpause_timer_callback(void *priv) } if (modem->connected) { uint8_t buffer[16]; - int wouldblock = 0; - int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); + int wouldblock = 0; + int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { if (modem->telnet_mode) @@ -1410,31 +1462,30 @@ modem_cmdpause_timer_callback(void *priv) } } - modem->cmdpause++; - guard_threashold = (uint32_t)(modem->reg[MREG_GUARD_TIME] * 20); - if (modem->cmdpause > guard_threashold) { - if (modem->plusinc == 0) { - modem->plusinc = 1; - } else if (modem->plusinc == 4) { - modem_log("Escape sequence triggered, returning to command mode\n"); - modem->mode = MODEM_MODE_COMMAND; - modem_send_res(modem, ResOK); - modem->plusinc = 0; - } - } + modem->cmdpause++; + guard_threshold = (uint32_t) (modem->reg[MREG_GUARD_TIME] * 20); + if (modem->cmdpause > guard_threshold) { + if (modem->plusinc == 0) { + modem->plusinc = 1; + } else if (modem->plusinc == 4) { + modem_log("Escape sequence triggered, returning to command mode\n"); + modem->mode = MODEM_MODE_COMMAND; + modem_send_res(modem, ResOK); + modem->plusinc = 0; + } + } } /* Initialize the device for use by the user. */ static void * modem_init(const device_t *info) { - modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); - const char* phonebook_file = NULL; + modem_t *modem = (modem_t *) calloc(1, sizeof(modem_t)); + const char *phonebook_file = NULL; memset(modem->mac, 0xfc, 6); - - modem->port = device_get_config_int("port"); - modem->baudrate = device_get_config_int("baudrate"); + modem->port = device_get_config_int("port"); + modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); modem->telnet_mode = device_get_config_int("telnet_mode"); @@ -1456,13 +1507,14 @@ modem_init(const device_t *info) if (phonebook_file && phonebook_file[0] != 0) { modem_read_phonebook_file(modem, phonebook_file); } - + return modem; } -void modem_close(void *priv) +void +modem_close(void *priv) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; modem->listen_port = 0; modem_reset(modem); fifo8_destroy(&modem->data_pending); diff --git a/src/qt/win_netsocket.c b/src/qt/win_netsocket.c index 902d5e6ff..55a84d414 100644 --- a/src/qt/win_netsocket.c +++ b/src/qt/win_netsocket.c @@ -19,50 +19,52 @@ #include #include -SOCKET plat_netsocket_create(int type) +SOCKET +plat_netsocket_create(int type) { SOCKET socket = -1; - u_long yes = 1; + u_long yes = 1; if (type != NET_SOCKET_TCP) return -1; - + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) return -1; ioctlsocket(socket, FIONBIO, &yes); - + return socket; } -SOCKET plat_netsocket_create_server(int type, unsigned short port) +SOCKET +plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET socket = -1; - u_long yes = 1; + SOCKET socket = -1; + u_long yes = 1; if (type != NET_SOCKET_TCP) return -1; - + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) return -1; - - memset(&sock_addr, 0, sizeof(struct sockaddr_in)); - - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = htons(port); - if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = htons(port); + + if (bind(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { plat_netsocket_close(socket); - return (SOCKET)-1; + return (SOCKET) -1; } if (listen(socket, 5) == SOCKET_ERROR) { plat_netsocket_close(socket); - return (SOCKET)-1; + return (SOCKET) -1; } ioctlsocket(socket, FIONBIO, &yes); @@ -70,28 +72,31 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) return socket; } -void plat_netsocket_close(SOCKET socket) +void +plat_netsocket_close(SOCKET socket) { - closesocket((SOCKET)socket); + closesocket((SOCKET) socket); } -SOCKET plat_netsocket_accept(SOCKET socket) +SOCKET +plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); if (clientsocket == INVALID_SOCKET) return -1; - + return clientsocket; } -int plat_netsocket_connected(SOCKET socket) +int +plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); fd_set wrfds, exfds; struct timeval tv; - int res = SOCKET_ERROR; + int res = SOCKET_ERROR; int status = 0; int optlen = 4; @@ -107,21 +112,21 @@ int plat_netsocket_connected(SOCKET socket) if (res == SOCKET_ERROR) return -1; - + if (res >= 1 && FD_ISSET(socket, &exfds)) { - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); pclog("Socket error %d\n", status); return -1; } if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; - - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); if (res == SOCKET_ERROR) return -1; - + if (status != 0) return -1; @@ -131,14 +136,15 @@ int plat_netsocket_connected(SOCKET socket) return 1; } -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +int +plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port) { struct sockaddr_in sock_addr; - int res = -1; + int res = -1; - sock_addr.sin_family = AF_INET; + sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(hostname); - sock_addr.sin_port = htons(port); + sock_addr.sin_port = htons(port); if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { struct hostent *hp; @@ -151,22 +157,23 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p return -1; } - res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + res = connect(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); if (error == WSAEISCONN || error == WSAEWOULDBLOCK) return 0; - + res = -1; } return res; } -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock) { - int res = send(socket, (const char*)data, size, 0); + int res = send(socket, (const char *) data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); @@ -179,9 +186,10 @@ int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int s return res; } -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock) { - int res = recv(socket, (char*)data, size, 0); + int res = recv(socket, (char *) data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); diff --git a/src/qt/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c index b2d09b1d0..2b77bd219 100644 --- a/src/qt/win_serial_passthrough.c +++ b/src/qt/win_serial_passthrough.c @@ -173,7 +173,7 @@ open_pseudo_terminal(serial_passthrough_t *dev) char ascii_pipe_name[1024] = { 0 }; strncpy(ascii_pipe_name, dev->named_pipe, sizeof(ascii_pipe_name)); ascii_pipe_name[1023] = '\0'; - dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL); + dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL); if (dev->master_fd == (intptr_t) INVALID_HANDLE_VALUE) { wchar_t errorMsg[1024] = { 0 }; wchar_t finalMsg[1024] = { 0 }; diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e6ec6285f..d626d025b 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -19,91 +19,92 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include #include -SOCKET plat_netsocket_create(int type) +SOCKET +plat_netsocket_create(int type) { - SOCKET fd = -1; - int yes = 1; + SOCKET fd = -1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; - + fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) return -1; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); - + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); + return fd; } -SOCKET plat_netsocket_create_server(int type, unsigned short port) +SOCKET +plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET fd = -1; - int yes = 1; + SOCKET fd = -1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; - + fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) return -1; - - memset(&sock_addr, 0, sizeof(struct sockaddr_in)); - - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = htons(port); - if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = htons(port); + + if (bind(fd, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)) == -1) { plat_netsocket_close(fd); - return (SOCKET)-1; + return (SOCKET) -1; } if (listen(fd, 5) == -1) { plat_netsocket_close(fd); - return (SOCKET)-1; + return (SOCKET) -1; } fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); return fd; } -void plat_netsocket_close(SOCKET socket) +void +plat_netsocket_close(SOCKET socket) { - close((SOCKET)socket); + close((SOCKET) socket); } -SOCKET plat_netsocket_accept(SOCKET socket) +SOCKET +plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); if (clientsocket == -1) return -1; - + return clientsocket; } -int plat_netsocket_connected(SOCKET socket) +int +plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); fd_set wrfds; struct timeval tv; - int res = -1; + int res = -1; int status = 0; socklen_t optlen = 4; @@ -117,15 +118,15 @@ int plat_netsocket_connected(SOCKET socket) if (res == -1) return -1; - + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; - - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); if (res == -1) return -1; - + if (status != 0) return -1; @@ -135,16 +136,17 @@ int plat_netsocket_connected(SOCKET socket) return 1; } -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +int +plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port) { struct sockaddr_in sock_addr; - int res = -1; + int res = -1; - sock_addr.sin_family = AF_INET; + sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(hostname); - sock_addr.sin_port = htons(port); + sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == ((in_addr_t)-1) || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == ((in_addr_t) -1) || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); @@ -155,22 +157,23 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p return -1; } - res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + res = connect(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)); if (res == -1) { int error = errno; if (error == EISCONN || error == EWOULDBLOCK || error == EAGAIN || error == EINPROGRESS) return 0; - + res = -1; } return res; } -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock) { - int res = send(socket, (const char*)data, size, 0); + int res = send(socket, (const char *) data, size, 0); if (res == -1) { int error = errno; @@ -183,9 +186,10 @@ int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int s return res; } -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock) { - int res = recv(socket, (char*)data, size, 0); + int res = recv(socket, (char *) data, size, 0); if (res == -1) { int error = errno; diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 646b77d6c..0184ebbc0 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -22,7 +22,7 @@ # define _BSD_SOURCE 1 #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -# define __BSD_VISIBLE 1 +# define __BSD_VISIBLE 1 #endif #include #include From 3f64d6d00ccbd42f0bd305c772c931913ead69d7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:51:16 +0500 Subject: [PATCH 394/690] Simplify EditorConfig, add .ui Remove rules made redundant by the new indentation style Add Qt .ui files --- .editorconfig | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/.editorconfig b/.editorconfig index 29d9ac0ba..fa7defd57 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,34 +5,11 @@ indent_style = space indent_size = 4 tab_width = 4 -# Disabled for now since not all editors support setting a tab_width value different from indent_size -# Relevant VSCode extension issue: https://github.com/editorconfig/editorconfig-vscode/issues/190 -# [*.rc] -# indent_style = space -# indent_size = 4 -# tab_width = 4 - -# [Makefile.*] -# indent_style = space -# indent_size = 4 -# tab_width = 4 - [*.manifest] -indent_style = space indent_size = 2 [*.yml] -indent_style = space indent_size = 2 -[**/CMakeLists.txt] -indent_style = space -indent_size = 4 - -[*.cmake] -indent_style = space -indent_size = 4 - -[*.json] -indent_style = space -indent_size = 4 +[*.ui] +indent_size = 1 From 9c53413ca44cc7144e3bdfc96132604268b1113d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:35:55 +0200 Subject: [PATCH 395/690] Give the P5MP3 PS/2 keyboard and mouse latches, fixes #4320. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4338f741f..c2bb3925b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8705,7 +8705,7 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, .flags = MACHINE_APM, .ram = { .min = 2048, From 5d94a361f12ba39039fd279e14d82e6f90da1548 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:36:38 +0200 Subject: [PATCH 396/690] net_modem: Remove excess parentheses. --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 0555978af..078320fb4 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -757,7 +757,7 @@ modem_do_command(modem_t *modem, int repeat) if (repeat) { /* Handle the case of A/ being invoked without a previous command to run */ - if ((modem->prevcmdbuf[0] == '\0')) { + if (modem->prevcmdbuf[0] == '\0') { modem_send_res(modem, ResOK); return; } From 038871d998aae5d8f093d1e641bccbe0dac9be19 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:54:49 +0200 Subject: [PATCH 397/690] SiS 496/497: Fix soft reset behavior, fixes #4319. --- src/chipset/sis_85c496.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 1e9b74f41..3c3d5bd8c 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -388,8 +388,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x67: /* Miscellaneous Control */ dev->pci_conf[addr] = val & 0xf9; - if (valxor & 0x60) - port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40)); + cpu_cpurst_on_sr = ((val & 0xa0) == 0x80) && !(dev->pci_conf[0xc6] & 0x08); break; /* 86C497 Specific Registers (80h ~ FFh) */ @@ -480,7 +479,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0xc6: /* 85C497 Post / INIT Configuration */ dev->pci_conf[addr] = val & 0x0f; - cpu_cpurst_on_sr = !(val & 0x08); + cpu_cpurst_on_sr = ((dev->pci_conf[0x67] & 0xa0) == 0x80) && !(val & 0x08); soft_reset_pci = !!(val & 0x04); break; case 0xc8: @@ -610,6 +609,9 @@ sis_85c496_reset(void *priv) sis_85c49x_pci_write(0, 0xd0, 0x78, dev); sis_85c49x_pci_write(0, 0xd4, 0x00, dev); + dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0xc6] = 0x00; + ide_pri_disable(); ide_sec_disable(); @@ -617,7 +619,7 @@ sis_85c496_reset(void *priv) sis_85c497_isa_reset(dev); - cpu_cpurst_on_sr = 1; + cpu_cpurst_on_sr = 0; soft_reset_pci = 0; } From ee7df0616823c2386d052bd96de55d4c96cfc388 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 00:08:40 +0200 Subject: [PATCH 398/690] Voodoo: Honor monitor overscan. --- src/video/vid_svga.c | 2 ++ src/video/vid_voodoo_display.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 6e32bdc40..a8bf76505 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -90,6 +90,7 @@ svga_set_override(svga_t *svga, int val) svga->fullchange = svga->monitor->mon_changeframecount; svga->override = val; +#ifdef OVERRIDE_OVERSCAN if (!val) { /* Override turned off, restore overscan X and Y per the CRTC. */ svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; @@ -104,6 +105,7 @@ svga_set_override(svga_t *svga, int val) } else svga->monitor->mon_overscan_x = svga->monitor->mon_overscan_y = 16; /* Override turned off, fix overcan X and Y to 16. */ +#endif } void diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index e6cf13674..d04376941 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -511,6 +511,8 @@ voodoo_callback(void *priv) { voodoo_t *voodoo = (voodoo_t *) priv; const monitor_t *monitor = &monitors[voodoo->monitor_index]; + int v_y_add = (monitor->mon_overscan_y >> 1); + int v_x_add = (monitor->mon_overscan_x >> 1); if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { if (voodoo->line < voodoo->v_disp) { @@ -534,7 +536,7 @@ voodoo_callback(void *priv) } if (draw_voodoo->dirty_line[draw_line]) { - uint32_t *p = &monitor->target_buffer->line[voodoo->line + 8][8]; + uint32_t *p = &monitor->target_buffer->line[voodoo->line + v_y_add][v_x_add]; uint16_t *src = (uint16_t *) &draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line * draw_voodoo->row_width]; int x; @@ -548,8 +550,8 @@ voodoo_callback(void *priv) voodoo->dirty_line_high = voodoo->line; /* Draw left overscan. */ - for (x = 0; x < 8; x++) - monitor->target_buffer->line[voodoo->line + 8][x] = 0x00000000; + for (x = 0; x < v_x_add; x++) + monitor->target_buffer->line[voodoo->line + v_y_add][x] = 0x00000000; if (voodoo->scrfilter && voodoo->scrfilterEnabled) { uint8_t fil[4096 * 3]; /* interleaved 24-bit RGB */ @@ -570,8 +572,9 @@ voodoo_callback(void *priv) } /* Draw right overscan. */ - for (x = 0; x < 8; x++) - monitor->target_buffer->line[voodoo->line + 8][voodoo->h_disp + x + 8] = 0x00000000; + for (x = 0; x < v_x_add; x++) + monitor->target_buffer->line[voodoo->line + v_y_add][voodoo->h_disp + x + v_x_add] = + 0x00000000; } } } From 42be0ab641d7ea2402c01a8118aac5b913cf553a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 2 Apr 2024 00:20:27 +0200 Subject: [PATCH 399/690] Voodoo: vertical display programming fix. Apparently some software reprograms the vertical display wrong sometimes (in this case, vdisp + 2). This should fix software titles that use such techniques... --- src/video/vid_voodoo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 734179fa9..93bdd1a4c 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -505,6 +505,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo->videoDimensions = val; voodoo->h_disp = (val & 0xfff) + 1; voodoo->v_disp = (val >> 16) & 0xfff; + if ((voodoo->v_disp == 386) || (voodoo->v_disp == 402) || + (voodoo->v_disp == 482) || (voodoo->v_disp == 602)) + voodoo->v_disp -= 2; break; case SST_fbiInit0: if (voodoo->initEnable & 0x01) { From e712f8060a433adc05f5e3f14d282cf5e06adab6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 14:54:25 +0200 Subject: [PATCH 400/690] ET4000AX: Do not wrap row offset. --- src/video/vid_et4000.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 7ceacb823..1a28b767b 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -664,8 +664,6 @@ et4000_recalctimings(svga_t *svga) svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) svga->split |= 0x400; - if (!svga->rowoffset) - svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { From 38e044ca34b40d77c66f1c525ce0c6fb0938756f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 2 Apr 2024 15:09:18 +0200 Subject: [PATCH 401/690] Tseng Labs fixes and bug-compatible fixes too. ET3000AX: the chip in question should not support 1MB of video memory. ET4000AX: the early TC6058AF revision can support 1MB of video memory (e.g.: Diamond Speedstar BIOS D3.10, undumped anyway), and actually don't update the rowoffset to 256 when using such chip in 320x200x256 mode. Fixes the copper demo in said chip revision. --- src/include/86box/vid_svga.h | 1 + src/video/vid_et3000.c | 2 -- src/video/vid_et4000.c | 19 +++++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 2f8a83a1d..bc33ac746 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -129,6 +129,7 @@ typedef struct svga_t { int hblank_end_mask; int hblank_sub; int packed_4bpp; + int ps_bit_bug; int ati_4color; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index 97da08822..a7d2a749f 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -557,8 +557,6 @@ static const device_config_t et3000_config[] = { .value = 256 }, { .description = "512 KB", .value = 512 }, - { .description = "1 MB", - .value = 1024 }, { .description = "" } } }, { .type = CONFIG_END } }; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 7ceacb823..583487c5f 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -652,7 +652,9 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + + svga->ps_bit_bug = (dev->type == ET4000_TYPE_TC6058AF) && svga->lowres && ((svga->gdcreg[5] & 0x60) >= 0x40); if (svga->crtc[0x35] & 1) svga->vblankstart |= 0x400; @@ -664,7 +666,7 @@ et4000_recalctimings(svga_t *svga) svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) svga->split |= 0x400; - if (!svga->rowoffset) + if (!svga->rowoffset && !svga->ps_bit_bug) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal |= 0x100; @@ -729,13 +731,6 @@ et4000_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->render = svga_render_8bpp_highres; } - - if (dev->type == ET4000_TYPE_TC6058AF) { - if (svga->render == svga_render_8bpp_lowres) - svga->render = svga_render_8bpp_tseng_lowres; - else if (svga->render == svga_render_8bpp_highres) - svga->render = svga_render_8bpp_tseng_highres; - } } static void @@ -962,6 +957,10 @@ static const device_config_t et4000_tc6058af_config[] = { .description = "512 KB", .value = 512 }, + { + .description = "1 MB", + .value = 1024 + }, { .description = "" } @@ -1071,7 +1070,7 @@ const device_t et4000_tc6058af_isa_device = { .name = "Tseng Labs ET4000AX (TC6058AF) (ISA)", .internal_name = "et4000ax_tc6058af", .flags = DEVICE_ISA, - .local = 0, + .local = ET4000_TYPE_TC6058AF, .init = et4000_init, .close = et4000_close, .reset = NULL, From 57b064c412089a45e9fecccfe4258e8dc5974015 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 07:54:09 -0400 Subject: [PATCH 402/690] ui: Warning for performance impact of softfloat --- src/qt/qt_settingsmachine.cpp | 15 ++ src/qt/qt_settingsmachine.hpp | 1 + src/qt/qt_settingsmachine.ui | 257 +++++++++++++++++++--------------- 3 files changed, 162 insertions(+), 111 deletions(-) diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 475730db9..aff55203e 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -61,6 +61,11 @@ SettingsMachine::SettingsMachine(QWidget *parent) break; } + auto warning_icon = ui->softFloatWarningIcon->style()->standardIcon(QStyle::SP_MessageBoxWarning); + ui->softFloatWarningIcon->setPixmap(warning_icon.pixmap(warning_icon.actualSize(QSize(16, 16)))); + ui->softFloatWarningIcon->setVisible(false); + ui->softFloatWarningText->setVisible(false); + auto *waitStatesModel = ui->comboBoxWaitStates->model(); waitStatesModel->insertRows(0, 9); auto idx = waitStatesModel->index(0, 0); @@ -337,3 +342,13 @@ SettingsMachine::on_pushButtonConfigure_clicked() const auto *device = machine_get_device(machineId); DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } + +void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { + if(state == Qt::Checked) { + ui->softFloatWarningIcon->setVisible(true); + ui->softFloatWarningText->setVisible(true); + } else { + ui->softFloatWarningIcon->setVisible(false); + ui->softFloatWarningText->setVisible(false); + } +} \ No newline at end of file diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index 9d0ec62ff..7e89d7fa4 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -35,6 +35,7 @@ private slots: private slots: void on_comboBoxMachineType_currentIndexChanged(int index); + void on_checkBoxFPUSoftfloat_stateChanged(int state); private: Ui::SettingsMachine *ui; diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 54bc06f5c..0c9c2708e 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -7,7 +7,7 @@ 0 0 458 - 434 + 459
@@ -41,13 +41,6 @@ 0 - - - - Wait states: - - - @@ -55,6 +48,13 @@ + + + + FPU: + + + @@ -69,55 +69,21 @@ - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 30 - - - - 0 - 0 - - - - - - - - PIT mode: - - - - - - - 30 - - - - 0 - 0 - - - - - + + + + + 0 + 0 + + + + + + + + Machine type: + @@ -144,15 +110,15 @@ - - 30 - 0 0 + + 30 + @@ -167,27 +133,31 @@ - - 30 - 0 0 + + 30 +
- - - - - 0 - 0 - + + + + Wait states: + + + + + + + Machine: @@ -229,55 +199,120 @@ - - - - Machine type: - - - - - - - Machine: - - - - - - - FPU: - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 30 + + + + + + + PIT mode: + + + + + + + + 0 + 0 + + + + 30 + + + + - - - - 2 - 2 - - - - Dynamic Recompiler - - + + + + + + 2 + 2 + + + + Dynamic Recompiler + + + + - - - - 3 - 3 - - - - Softfloat FPU - - + + + + + + 3 + 3 + + + + Softfloat FPU + + + + + + + + + + + + + + High performance impact + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + From 3cf3865980014b179606d368c52ff1da7bb47920 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 08:00:02 -0400 Subject: [PATCH 403/690] ui: Disable add-on voodoo when main voodoo is selected --- src/qt/qt_settingsdisplay.cpp | 20 ++++++++++++++++++++ src/qt/qt_settingsdisplay.ui | 14 +++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 4d8919a73..631e3b966 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -139,6 +139,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) if (index < 0) { return; } + static QRegularExpression voodooRegex("3dfx|voodoo|banshee", QRegularExpression::CaseInsensitiveOption); auto curVideoCard_2 = videoCard[1]; videoCard[0] = ui->comboBoxVideo->currentData().toInt(); if (videoCard[0] == VID_INTERNAL) @@ -207,6 +208,25 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } + + // Is the currently selected video card a voodoo? + if (ui->comboBoxVideo->currentText().contains(voodooRegex)) { + // Get the name of the video card currently in use + const device_t *video_dev = video_card_getdevice(gfxcard[0]); + const QString currentVideoName = DeviceConfig::DeviceName(video_dev, video_get_internal_name(gfxcard[0]), 1); + // Is it a voodoo? + const bool currentCardIsVoodoo = currentVideoName.contains(voodooRegex); + // Don't uncheck if + // * Current card is voodoo + // * Add-on voodoo was manually overridden in config + if (ui->checkBoxVoodoo->isChecked() && !currentCardIsVoodoo) { + // Otherwise, uncheck the add-on voodoo when a main voodoo is selected + ui->checkBoxVoodoo->setCheckState(Qt::Unchecked); + } + ui->checkBoxVoodoo->setDisabled(true); + } else { + ui->checkBoxVoodoo->setDisabled(false); + } } void diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index 5dd76287f..a9b7e6e2c 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -61,15 +61,15 @@ - - 30 - 0 0 + + 30 + @@ -102,7 +102,7 @@ - Voodoo Graphics + Voodoo 1 or 2 Graphics @@ -122,15 +122,15 @@ - - 30 - 0 0 + + 30 + From 4d8e7bd24edc6377ccbc2e5a94b999e6975c3482 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:23:55 -0400 Subject: [PATCH 404/690] qt: Add UUID features, MAC address configuration, machine move detection --- src/86box.c | 1 + src/config.c | 11 ++++++++ src/device.c | 3 +-- src/include/86box/86box.h | 12 ++++++--- src/qt/qt_deviceconfig.cpp | 39 ++++++++++++++++++++++++++++ src/qt/qt_main.cpp | 21 +++++++++++++++ src/qt/qt_util.cpp | 53 ++++++++++++++++++++++++++++++++++++++ src/qt/qt_util.hpp | 5 ++++ 8 files changed, 139 insertions(+), 6 deletions(-) diff --git a/src/86box.c b/src/86box.c index 88229a820..67d0bb165 100644 --- a/src/86box.c +++ b/src/86box.c @@ -206,6 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether also apply when maximized. */ int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus loss */ +char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ /* Statistics. */ extern int mmuflush; diff --git a/src/config.c b/src/config.c index da02a93b0..95d23cea3 100644 --- a/src/config.c +++ b/src/config.c @@ -209,6 +209,12 @@ load_general(void) ini_section_delete_var(cat, "window_coordinates"); do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0); + + p = ini_section_get_string(cat, "uuid", NULL); + if (p != NULL) + strncpy(uuid, p, sizeof(uuid) - 1); + else + strncpy(uuid, "", sizeof(uuid) - 1); } /* Load monitor section. */ @@ -1878,6 +1884,11 @@ save_general(void) else ini_section_delete_var(cat, "do_auto_pause"); + if (strnlen(uuid, sizeof(uuid) - 1) > 0) + ini_section_set_string(cat, "uuid", uuid); + else + ini_section_delete_var(cat, "uuid"); + ini_delete_section_if_empty(config, cat); } diff --git a/src/device.c b/src/device.c index b934e7246..321f105e5 100644 --- a/src/device.c +++ b/src/device.c @@ -467,8 +467,7 @@ device_has_config(const device_t *dev) config = dev->config; while (config->type != -1) { - if (config->type != CONFIG_MAC) - c++; + c++; config++; } diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index b34b95621..3f5f3f2ab 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -35,6 +35,9 @@ #define MAX_PREV_IMAGES 4 #define MAX_IMAGE_PATH_LEN 2048 +/* Max UUID Length */ +#define MAX_UUID_LEN 64 + /* Default language 0xFFFF = from system, 0x409 = en-US */ #define DEFAULT_LANGUAGE 0x0409 @@ -167,10 +170,11 @@ extern uint16_t key_prefix_2_2; extern uint16_t key_uncapture_1; extern uint16_t key_uncapture_2; -extern char exe_path[2048]; /* path (dir) of executable */ -extern char usr_path[1024]; /* path (dir) of user data */ -extern char cfg_path[1024]; /* full path of config file */ -extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ +extern char exe_path[2048]; /* path (dir) of executable */ +extern char usr_path[1024]; /* path (dir) of user data */ +extern char cfg_path[1024]; /* full path of config file */ +extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ +extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */ #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 6c7db0f3d..d2ae70245 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -29,7 +29,9 @@ #include #include #include +#include #include +#include extern "C" { #include <86box/86box.h> @@ -38,6 +40,7 @@ extern "C" { #include <86box/device.h> #include <86box/midi_rtmidi.h> #include <86box/mem.h> +#include <86box/random.h> #include <86box/rom.h> } @@ -116,6 +119,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se device_set_context(&device_context, device, instance); auto device_label = new QLabel(device->name); + device_label->setAlignment(Qt::AlignCenter); dc.ui->formLayout->addRow(device_label); auto line = new QFrame; line->setFrameShape(QFrame::HLine); @@ -291,6 +295,33 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se cbox->setCurrentIndex(currentIndex); break; } + case CONFIG_MAC: + { + // QHBoxLayout for the line edit widget and the generate button + auto hboxLayout = new QHBoxLayout(); + auto generateButton = new QPushButton(tr("Generate")); + auto lineEdit = new QLineEdit; + // Allow the line edit to expand and fill available space + lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred); + lineEdit->setInputMask("HH:HH:HH;0"); + lineEdit->setObjectName(config->name); + // Display the current or generated MAC in uppercase + // When stored it will be converted to lowercase + if (config_get_mac(device_context.name, config->name, config->default_int) & 0xFF000000) { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + } else { + auto current_mac = QString(config_get_string(device_context.name, config->name, const_cast(config->default_string))); + lineEdit->setText(current_mac.toUpper()); + } + // Action for the generate button + connect(generateButton, &QPushButton::clicked, [lineEdit] { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + }); + hboxLayout->addWidget(lineEdit); + hboxLayout->addWidget(generateButton); + dc.ui->formLayout->addRow(config->description, hboxLayout); + break; + } } ++config; } @@ -362,6 +393,14 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se config_set_int(device_context.name, const_cast(config->name), spinBox->value()); break; } + case CONFIG_MAC: + { + const auto *lineEdit = dc.findChild(config->name); + // Store the mac address as lowercase + auto macText = lineEdit->displayText().toLower(); + config_set_string(device_context.name, config->name, macText.toUtf8().constData()); + break; + } } config++; } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a621d1441..78eaff5e9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef QT_STATIC /* Static builds need plugin imports */ @@ -71,6 +72,7 @@ extern "C" { #include "cocoa_mouse.hpp" #include "qt_styleoverride.hpp" #include "qt_unixmanagerfilter.hpp" +#include "qt_util.hpp" // Void Cast #define VC(x) const_cast(x) @@ -220,6 +222,25 @@ main(int argc, char *argv[]) return 6; } + // UUID / copy / move detection + if(!util::compareUuid()) { + QMessageBox movewarnbox; + movewarnbox.setIcon(QMessageBox::Icon::Warning); + movewarnbox.setText("This machine might have been moved or copied."); + movewarnbox.setInformativeText("In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure."); + const QPushButton *movedButton = movewarnbox.addButton(QObject::tr("I Moved It"), QMessageBox::AcceptRole); + const QPushButton *copiedButton = movewarnbox.addButton(QObject::tr("I Copied It"), QMessageBox::DestructiveRole); + QPushButton *cancelButton = movewarnbox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole); + movewarnbox.setDefaultButton(cancelButton); + movewarnbox.exec(); + if (movewarnbox.clickedButton() == copiedButton) { + util::storeCurrentUuid(); + util::generateNewMacAdresses(); + } else if (movewarnbox.clickedButton() == movedButton) { + util::storeCurrentUuid(); + } + } + #ifdef Q_OS_WINDOWS # if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) HWND winbox = FindWindow("TWinBoxMain", NULL); diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index b05b656bb..0a59cdf5d 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -21,8 +21,20 @@ #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) # include #endif +#include #include "qt_util.hpp" +extern "C" { +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/device.h> +#include <86box/ini.h> +#include <86box/random.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +} + namespace util { QScreen * screenOfWidget(QWidget *widget) @@ -56,4 +68,45 @@ DlgFilter(std::initializer_list extensions, bool last) return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); } +QString currentUuid() +{ + return QUuid::createUuidV5(QUuid{}, QString(usr_path)).toString(QUuid::WithoutBraces); +} + +bool compareUuid() +{ + // A uuid not set in the config file will have a zero length. + // Any uuid that is lower than the minimum length will be considered invalid + // and a new one will be generated + if (const auto currentUuidLength = QString(uuid).length(); currentUuidLength < UUID_MIN_LENGTH) { + storeCurrentUuid(); + return true; + } + // The uuid appears to be a valid, at least by length. + // Compare with a simple string match + return uuid == currentUuid(); +} + +void +storeCurrentUuid() +{ + strncpy(uuid, currentUuid().toUtf8().constData(), sizeof(uuid) - 1); +} + +void +generateNewMacAdresses() +{ + for (int i = 0; i < NET_CARD_MAX; ++i) { + auto net_card = net_cards_conf[i]; + if (net_card.device_num != 0) { + const auto network_device = network_card_getdevice(net_card.device_num); + device_context_t device_context; + + device_set_context(&device_context, network_device, i+1); + auto generatedMac = QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate()).toLower(); + config_set_string(device_context.name, "mac", generatedMac.toUtf8().constData()); + } + } +} + } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 6ecd904b3..07e44b621 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -8,10 +8,15 @@ class QScreen; namespace util { +static constexpr auto UUID_MIN_LENGTH = 36; /* Creates extension list for qt filedialog */ QString DlgFilter(std::initializer_list extensions, bool last = false); /* Returns screen the widget is on */ QScreen *screenOfWidget(QWidget *widget); +QString currentUuid(); +void storeCurrentUuid(); +bool compareUuid(); +void generateNewMacAdresses(); }; #endif From 165ad489ef02087ead30f12ac184b2c0a403b88f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:58:43 -0400 Subject: [PATCH 405/690] Trim the newline from the resulting string on macOS --- src/qt/qt_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index c7cc76ffe..275d1df2e 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -686,7 +686,7 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { return; } QByteArray result = process->readAll(); - auto command_result = QString(result).split(": ").last(); + auto command_result = QString(result).split(": ").last().trimmed(); if(!command_result.isEmpty()) { cpu_string = command_result; } From f637e72488de866d05b2af03daff94379fb79f42 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Mon, 1 Apr 2024 09:40:00 -0400 Subject: [PATCH 406/690] config: Add host_cpu and emu_build_num to general --- src/config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/config.c b/src/config.c index da02a93b0..08edb4c59 100644 --- a/src/config.c +++ b/src/config.c @@ -77,6 +77,7 @@ #include <86box/plat_dir.h> #include <86box/ui.h> #include <86box/snd_opl.h> +#include <86box/version.h> static int cx; static int cy; @@ -1878,6 +1879,15 @@ save_general(void) else ini_section_delete_var(cat, "do_auto_pause"); + char cpu_buf[128] = { 0 }; + plat_get_cpu_string(cpu_buf, 128); + ini_section_set_string(cat, "host_cpu", cpu_buf); + + if (EMU_BUILD_NUM != 0) + ini_section_set_int(cat, "emu_build_num", EMU_BUILD_NUM); + else + ini_section_delete_var(cat, "emu_build_num"); + ini_delete_section_if_empty(config, cat); } From c8a1843cdf20b6edcb4f2b9bd123b7fb74c9b370 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 23:31:44 +0200 Subject: [PATCH 407/690] FDC: Disable DSR reset on the PS/1-2011/2121 / PS/2-30 FDC. --- src/floppy/fdc.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index e16da138d..491df2f47 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -780,24 +780,26 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (!(val & 0x80)) { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -6; - } - if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { - if (fdc->power_down) { - timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); - fdc->interrupt = -5; - } else { + if (!(fdc->flags & FDC_FLAG_PS1)) { + if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; + fdc->interrupt = -6; + } + if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; - fdc->perp &= 0xfc; + fdc->perp &= 0xfc; - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); - fdc_ctrl_reset(fdc); + fdc_ctrl_reset(fdc); + } } } fdc->dsr = val; From 48718eb169f8995853dac8923be5769ca3c809a0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Apr 2024 14:08:05 +0200 Subject: [PATCH 408/690] MGA: Fixes hard freezes when using DynaView 3D on non-16-bpp modes on Windows 3.x. --- src/video/vid_mga.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 36df9e9e4..5c094c6c9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4505,6 +4505,19 @@ blit_line(mystique_t *mystique, int closed, int autoline) int b = 0; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 20) & 0x7; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 20) & 0x7; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 21) & 0x3; + dst = (r << 5) | (g << 2) | b; + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + case MACCESS_PWIDTH_16: if (!(mystique->dwgreg.dr[4] & (1 << 23))) r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; @@ -4518,6 +4531,33 @@ blit_line(mystique_t *mystique, int closed, int autoline) svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; break; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + dst = (r << 16) | (g << 8) | b; + + ((uint32_t *) svga->vram)[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = dst | (old_dst & 0xFF000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + dst = (r << 16) | (g << 8) | b; + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + default: fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } From fcbbae181f46e0365e71a95a9cced9b5553b2a9d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Apr 2024 14:09:27 +0200 Subject: [PATCH 409/690] MGA: fixes pitch mask to be correct according to the docs (it incorrectly stripped bit 11 of the pitch before). Reference: Page 3-74 (PDF page number 87), https://www.vgamuseum.info/images/doc/matrox/mga-2164w_dev_spec.pdf. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 5c094c6c9..bbba9ca6f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -337,7 +337,7 @@ #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) -#define PITCH_MASK 0x7e0 +#define PITCH_MASK 0xfe0 #define PITCH_YLIN (1 << 15) #define SGN_SDYDXL (1 << 0) From 982c7c46f93282295bea44678a73845db4a20bc0 Mon Sep 17 00:00:00 2001 From: Sasamiya <117635969+kzmidze@users.noreply.github.com> Date: Thu, 4 Apr 2024 00:08:52 +0800 Subject: [PATCH 410/690] Update language modules --- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 7dd7be6d2..c8bd8f7bd 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -439,10 +439,10 @@ msgid "Standalone MPU-401" msgstr "独立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用单精度浮点 (FLOAT32)" +msgstr "使用单精度浮点 (FLOAT32) 音频" msgid "FM synth driver" -msgstr "调频合成器驱动器" +msgstr "FM synth driver" msgid "Nuked (more accurate)" msgstr "Nuked (更准确)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 8ea4d2290..3de6bf4c4 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -439,10 +439,10 @@ msgid "Standalone MPU-401" msgstr "獨立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用單精度浮點 (FLOAT32)" +msgstr "使用單精度浮點 (FLOAT32) 音訊" msgid "FM synth driver" -msgstr "調頻合成器驅動器" +msgstr "FM synth driver" msgid "Nuked (more accurate)" msgstr "Nuked (更準確)" From f93692a045c9d558eb9a345e65d126239d3c8733 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Apr 2024 03:09:35 +0200 Subject: [PATCH 411/690] More Pro Audio Spectrum 16 work, closes #4313. --- src/dma.c | 195 ++++++++++++++++++++++++++++++++++------ src/include/86box/dma.h | 2 + src/pit.c | 8 +- src/pit_fast.c | 28 ++++-- src/sound/snd_pas16.c | 188 +++++++++++++++++++++++++------------- 5 files changed, 322 insertions(+), 99 deletions(-) diff --git a/src/dma.c b/src/dma.c index b7c4b4863..ebe75bba6 100644 --- a/src/dma.c +++ b/src/dma.c @@ -42,6 +42,7 @@ static int dma_wp[2]; static uint8_t dma_stat; static uint8_t dma_stat_rq; static uint8_t dma_stat_rq_pc; +static uint8_t dma_stat_adv_pend; static uint8_t dma_command[2]; static uint8_t dma_req_is_soft; static uint8_t dma_advanced; @@ -457,6 +458,7 @@ dma_read(uint16_t addr, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; uint8_t temp; + int count; switch (addr & 0xf) { case 0: @@ -473,10 +475,13 @@ dma_read(uint16_t addr, UNUSED(void *priv)) case 5: case 7: /*Count registers*/ dma_wp[0] ^= 1; + count = dma[channel].cc/* + 1*/; + // if (count > dma[channel].cb) + // count = 0x0000; if (dma_wp[0]) - temp = dma[channel].cc & 0xff; + temp = count & 0xff; else - temp = dma[channel].cc >> 8; + temp = count >> 8; return temp; case 8: /*Status register*/ @@ -529,8 +534,10 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) case 8: /*Control register*/ dma_command[0] = val; +#ifdef ENABLE_DMA_LOG if (val & 0x01) pclog("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc); +#endif return; case 9: /*Request register */ @@ -538,7 +545,9 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) if (val & 4) { dma_stat_rq_pc |= (1 << channel); if ((channel == 0) && (dma_command[0] & 0x01)) { +#ifdef ENABLE_DMA_LOG pclog("Memory to memory transfer start\n"); +#endif dma_mem_to_mem_transfer(); } else dma_block_transfer(channel); @@ -767,9 +776,16 @@ static uint8_t dma16_read(uint16_t addr, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; - uint8_t temp; +#ifdef ENABLE_DMA_LOG + uint16_t port = addr; +#endif + uint8_t ret; + int count; addr >>= 1; + + ret = dmaregs[1][addr & 0xf]; + switch (addr & 0xf) { case 0: case 2: @@ -778,41 +794,53 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) dma_wp[1] ^= 1; if (dma_ps2.is_ps2) { if (dma_wp[1]) - return (dma[channel].ac); - return ((dma[channel].ac >> 8) & 0xff); - } - if (dma_wp[1]) - return ((dma[channel].ac >> 1) & 0xff); - return ((dma[channel].ac >> 9) & 0xff); + ret = (dma[channel].ac); + else + ret = ((dma[channel].ac >> 8) & 0xff); + } else if (dma_wp[1]) + ret = ((dma[channel].ac >> 1) & 0xff); + else + ret = ((dma[channel].ac >> 9) & 0xff); + break; case 1: case 3: case 5: case 7: /*Count registers*/ dma_wp[1] ^= 1; + count = dma[channel].cc/* + 1*/; + // if (count > dma[channel].cb) + // count = 0x0000; if (dma_wp[1]) - temp = dma[channel].cc & 0xff; + ret = count & 0xff; else - temp = dma[channel].cc >> 8; - return temp; + ret = count >> 8; + break; case 8: /*Status register*/ - temp = (dma_stat_rq_pc & 0xf0); - temp |= dma_stat >> 4; + ret = (dma_stat_rq_pc & 0xf0); + ret |= dma_stat >> 4; dma_stat &= ~0xf0; - return temp; + break; default: break; } - return (dmaregs[1][addr & 0xf]); +#ifdef ENABLE_DMA_LOG + pclog("dma16_read(%08X) = %02X\n", port, ret); +#endif + + return ret; } static void dma16_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; +#ifdef ENABLE_DMA_LOG + pclog("dma16_write(%08X, %02X)\n", addr, val); +#endif addr >>= 1; dmaregs[1][addr & 0xf] = val; @@ -1076,11 +1104,12 @@ dma_reset(void) dma[c].transfer_mode = (c & 4) ? 0x0202 : 0x0101; } - dma_stat = 0x00; - dma_stat_rq = 0x00; - dma_stat_rq_pc = 0x00; - dma_req_is_soft = 0; - dma_advanced = 0; + dma_stat = 0x00; + dma_stat_rq = 0x00; + dma_stat_rq_pc = 0x00; + dma_stat_adv_pend = 0x00; + dma_req_is_soft = 0; + dma_advanced = 0; memset(dma_buffer, 0x00, sizeof(dma_buffer)); memset(dma16_buffer, 0x00, sizeof(dma16_buffer)); @@ -1401,23 +1430,130 @@ int dma_channel_readable(int channel) { dma_t *dma_c = &dma[channel]; + int ret = 1; if (channel < 4) { if (dma_command[0] & 0x04) - return 0; + ret = 0; } else { if (dma_command[1] & 0x04) - return 0; + ret = 0; } if (!(dma_e & (1 << channel))) - return 0; + ret = 0; if ((dma_m & (1 << channel)) && !dma_req_is_soft) - return 0; + ret = 0; if ((dma_c->mode & 0xC) != 8) - return 0; + ret = 0; - return 1; + return ret; +} + +int +dma_channel_read_only(int channel) +{ + dma_t *dma_c = &dma[channel]; + uint16_t temp; + + if (channel < 4) { + if (dma_command[0] & 0x04) + return (DMA_NODATA); + } else { + if (dma_command[1] & 0x04) + return (DMA_NODATA); + } + + if (!(dma_e & (1 << channel))) + return (DMA_NODATA); + if ((dma_m & (1 << channel)) && !dma_req_is_soft) + return (DMA_NODATA); + if ((dma_c->mode & 0xC) != 8) + return (DMA_NODATA); + + dma_channel_advance(channel); + + if (!dma_at && !channel) + refreshread(); + + if (!dma_c->size) { + temp = _dma_read(dma_c->ac, dma_c); + + if (dma_c->mode & 0x20) { + if (dma_ps2.is_ps2) + dma_c->ac--; + else if (dma_advanced) + dma_retreat(dma_c); + else + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff); + } else { + if (dma_ps2.is_ps2) + dma_c->ac++; + else if (dma_advanced) + dma_advance(dma_c); + else + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff); + } + } else { + temp = _dma_readw(dma_c->ac, dma_c); + + if (dma_c->mode & 0x20) { + if (dma_ps2.is_ps2) + dma_c->ac -= 2; + else if (dma_advanced) + dma_retreat(dma_c); + else + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff); + } else { + if (dma_ps2.is_ps2) + dma_c->ac += 2; + else if (dma_advanced) + dma_advance(dma_c); + else + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff); + } + } + + dma_stat_rq |= (1 << channel); + + dma_stat_adv_pend |= (1 << channel); + + return temp; +} + +int +dma_channel_advance(int channel) +{ + dma_t *dma_c = &dma[channel]; + int tc = 0; + + if (dma_stat_adv_pend & (1 << channel)) { + dma_c->cc--; + if (dma_c->cc < 0) { + if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) + dma_sg_next_addr(dma_c); + else { + tc = 1; + if (dma_c->mode & 0x10) { /*Auto-init*/ + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } + } + + if (tc) { + if (dma_advanced && (dma_c->sg_status & 1) && ((dma_c->sg_command & 0xc0) == 0x40)) { + picint(1 << 13); + dma_c->sg_status |= 8; + } + } + + dma_stat_adv_pend &= ~(1 << channel); + } + + return tc; } int @@ -1442,6 +1578,9 @@ dma_channel_read(int channel) if ((dma_c->mode & 0xC) != 8) return (DMA_NODATA); + if (dma_stat_adv_pend & (1 << channel)) + dma_channel_advance(channel); + if (!dma_at && !channel) refreshread(); @@ -1573,6 +1712,8 @@ dma_channel_write(int channel, uint16_t val) dma_stat_rq |= (1 << channel); + dma_stat_adv_pend &= ~(1 << channel); + dma_c->cc--; if (dma_c->cc < 0) { if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index ff0dc0b5d..23ce04898 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -96,6 +96,8 @@ extern void writedma2(uint8_t temp); extern int dma_get_drq(int channel); extern void dma_set_drq(int channel, int set); +extern int dma_channel_read_only(int channel); +extern int dma_channel_advance(int channel); extern int dma_channel_read(int channel); extern int dma_channel_write(int channel, uint16_t val); diff --git a/src/pit.c b/src/pit.c index 340cdccde..7ae50f413 100644 --- a/src/pit.c +++ b/src/pit.c @@ -246,9 +246,9 @@ ctr_tick(ctr_t *ctr, void *priv) } else ctr->count -= (ctr->newcount ? 1 : 2); if (ctr->count < 0) { + ctr_set_out(ctr, 0, pit); ctr_load_count(ctr); ctr->state = 3; - ctr_set_out(ctr, 0, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -265,9 +265,9 @@ ctr_tick(ctr_t *ctr, void *priv) } else ctr->count -= (ctr->newcount ? 3 : 2); if (ctr->count < 0) { + ctr_set_out(ctr, 1, pit); ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -443,8 +443,6 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) int old = ctr->gate; uint8_t mode = ctr->m & 3; - ctr->gate = gate; - switch (mode) { case 1: case 2: @@ -470,6 +468,8 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) default: break; } + + ctr->gate = gate; } static __inline void diff --git a/src/pit_fast.c b/src/pit_fast.c index 0da671bfe..e986600ee 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -133,7 +133,7 @@ pitf_read_timer(ctrf_t *ctr) read = 0; if (read > 0x10000) read = 0x10000; - if (ctr->m == 3) + if ((ctr->m == 3) && ctr->using_timer) read <<= 1; return read; } @@ -191,6 +191,8 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + else + ctr->newcount = (l & 1); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -269,6 +271,8 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + else + ctr->newcount = (l & 1); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -330,14 +334,23 @@ pitf_over(ctrf_t *ctr, void *priv) case 3: /*Square wave mode*/ if (ctr->out) { pitf_ctr_set_out(ctr, 0, pit); - ctr->count += (l >> 1); - if (ctr->using_timer) + if (ctr->using_timer) { + ctr->count += (l >> 1); timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * ctr->pit_const)); + } else { + ctr->count += l; + ctr->newcount = (l & 1); + } } else { pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); - if (ctr->using_timer) + if (ctr->using_timer) { + ctr->count += (l >> 1); timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + } else { + ctr->count += l; + ctr->newcount = (l & 1); + } } #if 0 if (!t) @@ -631,7 +644,12 @@ pitf_ctr_clock(void *data, int counter_id) if (ctr->using_timer) return; - ctr->count -= (ctr->m == 3) ? 2 : 1; + if ((ctr->m == 3) && ctr->newcount) { + ctr->count -= ctr->out ? 1 : 3; + ctr->newcount = 0; + } else + ctr->count -= (ctr->m == 3) ? 2 : 1; + if (!ctr->count) pitf_over(ctr, pit); } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 0a5c046b7..9812ced64 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -154,10 +154,14 @@ typedef struct pas16_t { uint16_t base; uint16_t new_base; + uint16_t sb_compat_base; + uint16_t mpu401_base; + uint16_t dma8_dat; + uint16_t ticks; uint16_t pcm_dat_l; uint16_t pcm_dat_r; - int16_t pcm_buffer[2][SOUNDBUFLEN * 2]; + int32_t pcm_buffer[2][SOUNDBUFLEN * 2]; int pos; int midi_r; @@ -371,7 +375,11 @@ pas16_in(uint16_t port, void *priv) break; case 0xec03: - ret = pas16->type ? 0x0c : 0x04; +#ifdef NEWER_PAS16 + ret = pas16->type ? 0x0c : 0x06; +#else + ret = pas16->type ? 0x0f : 0x06; +#endif break; case 0xf000: @@ -390,7 +398,13 @@ pas16_in(uint16_t port, void *priv) break; case 0xf400: - ret = pas16->compat; + ret = (pas16->compat & 0xf3); + + if (pas16->dsp.sb_irqm8 || pas16->dsp.sb_irqm16 || pas16->dsp.sb_irqm401) + ret |= 0x04; + + if (pas16->mpu->mode == M_UART) + ret |= 0x08; break; case 0xf401: ret = pas16->compat_base; @@ -402,11 +416,13 @@ pas16_in(uint16_t port, void *priv) case 0xfc00: /* Board model */ /* PAS16 or PASPlus */ - ret = pas16->type ? 0x04 : 0x01; + ret = pas16->type ? 0x0c : 0x01; break; case 0xfc03: /* Master mode read */ /* AT bus, XT/AT timing */ - ret = pas16->type ? (0x20 | 0x10 | 0x01) : (0x10 | 0x01); + ret = 0x11; + if (pas16->type) + ret |= 0x20; break; default: @@ -458,7 +474,6 @@ pas16_reset_pcm(void *priv) pas16->pcm_ctrl = 0x00; pas16->stereo_lr = 0; - pas16->dma8_ff = 0; pas16->irq_stat &= 0xd7; @@ -490,6 +505,7 @@ pas16_reset_regs(void *priv) pitf_ctr_set_gate(pit, 1, 0); pas16_reset_pcm(pas16); + pas16->dma8_ff = 0; pas16->irq_ena = 0x00; pas16->irq_stat = 0x00; @@ -522,6 +538,11 @@ pas16_reset(void *priv) pas16_io_handler(pas16, 1); pas16->new_base = 0x0388; + + pas16->sb_compat_base = 0x0220; + pas16->compat = 0x02; + pas16->compat_base = 0x02; + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); } static void @@ -546,25 +567,25 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x0801: pas16->irq_stat &= ~val; + if (!(pas16->irq_stat & 0x1f)) + picintc(1 << pas16->irq); break; case 0x0802: + pas16_update(pas16); + + pitf_ctr_set_gate(pas16->pit, 1, !!(val & 0x80)); + pitf_ctr_set_gate(pas16->pit, 0, !!(val & 0x40)); + + pas16->stereo_lr = 0; + pas16->dma8_ff = 0; + if ((val & 0x20) && !(pas16->audiofilt & 0x20)) { pas16_log("Reset.\n"); - val = 0x20; pas16_reset_regs(pas16); } - pas16_update(pas16); - pitf_ctr_set_gate(pas16->pit, 0, 1); - pitf_ctr_set_gate(pas16->pit, 1, 1); - // pas16->pit->counters[0].gate = !!(val & 0x40); - // pas16->pit->counters[0].enabled = !!(val & 0x40); - // pas16->pit->counters[1].gate = !!(val & 0x80); - // pas16->pit->counters[1].enabled = !!(val & 0x80); - pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; - pas16->dma8_ff = 0; pas16->audiofilt = val; + if (val & 0x1f) { pas16->filter = 1; switch (val & 0x1f) { @@ -595,6 +616,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x0803: pas16->irq_ena = val & 0x1f; + pas16->irq_stat &= ((val & 0x1f) | 0xe0); + + if (!(pas16->irq_stat & 0x1f)) + picintc(1 << pas16->irq); break; case 0x0c00: @@ -607,7 +632,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) { /* Guess */ pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; + pas16->irq_stat &= 0xd7; /* Needed for 8-bit DMA to work correctly on a 16-bit DMA channel. */ pas16->dma8_ff = 0; } @@ -713,10 +738,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf400: - pas16->compat = val; + pas16->compat = val & 0xf3; pas16_log("PCM compression is now %sabled\n", (val & 0x10) ? "en" : "dis"); if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); else sb_dsp_setaddr(&pas16->dsp, 0); if (pas16->compat & 0x01) @@ -726,14 +751,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf401: pas16->compat_base = val; + pas16->sb_compat_base = ((pas16->compat_base & 0xf) << 4) | 0x200; + pas16_log("SB Compatibility base: %04X\n", pas16->sb_compat_base); if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); if (pas16->compat & 0x01) mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; case 0xf802: pas16->sb_irqdma = val; + mpu401_setirq(pas16->mpu, pas16_sb_irqs[val & 7]); sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], @@ -774,18 +802,33 @@ pas16_out(uint16_t port, uint8_t val, void *priv) alongside the previous sample; - A 16-bit sample always takes two ctr_clock() ticks. */ +static uint16_t +pas16_dma_channel_read(pas16_t *pas16, int channel) +{ + int status; + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { + if (pas16->dma >= 5) { + dma_channel_advance(pas16->dma); + status = dma_channel_read_only(pas16->dma); + } else + status = dma_channel_read(pas16->dma); + ret = (status == DMA_NODATA) ? 0x0000 : (status & 0xffff); + } else + ret = 0x0000; + + return ret; +} + static uint16_t pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) { uint16_t ret; - if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) - ret = dma_channel_read(pas16->dma); - else - ret = 0x0000; + ret = pas16_dma_channel_read(pas16, pas16->dma); - for (uint8_t i = 0; i < timer1_ticks; i++) - pitf_ctr_clock(pas16->pit, 1); + pas16->ticks += timer1_ticks; return ret; } @@ -795,16 +838,14 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) { uint16_t ret; - if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { - ret = dma_channel_read(pas16->dma); + if (pas16->dma >= 5) + ret = pas16_dma_channel_read(pas16, pas16->dma); + else { + ret = pas16_dma_channel_read(pas16, pas16->dma); + ret |= (pas16_dma_channel_read(pas16, pas16->dma) << 8); + } - if (pas16->dma < 5) - ret |= (dma_channel_read(pas16->dma) << 8); - } else - ret = 0x0000; - - for (uint8_t i = 0; i < timer1_ticks; i++) - pitf_ctr_clock(pas16->pit, 1); + pas16->ticks += timer1_ticks; return ret; } @@ -812,20 +853,19 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) static uint16_t pas16_readdmab(pas16_t *pas16) { - static uint16_t temp; uint16_t ret; if (pas16->dma >= 5) { if (pas16->dma8_ff) - temp >>= 8; + pas16->dma8_dat >>= 8; else - temp = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16, 1); pas16->dma8_ff = !pas16->dma8_ff; } else - temp = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16, 1); - ret = ((temp & 0xff) ^ 0x80) << 8; + ret = ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; return ret; } @@ -844,8 +884,9 @@ static uint16_t pas16_readdmaw_stereo(pas16_t *pas16) { uint16_t ret; + uint16_t ticks = (pas16->sys_conf_1 & 0x02) ? (1 + (pas16->dma < 5)) : 2; - ret = pas16_dma_readw(pas16, 2); + ret = pas16_dma_readw(pas16, ticks); return ret; } @@ -895,17 +936,17 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16_t *pas16 = (pas16_t *) pit->dev_priv; uint16_t temp; - pas16_update(pas16); + if (!pas16->pit->counters[0].gate) + return; + + if (!dma_channel_readable(pas16->dma)) + return; + pas16_update_irq(pas16); - pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) { - pas16_log("INT SAMP.\n"); - picint(1 << pas16->irq); - } + if (((pas16->pcm_ctrl & PAS16_PCM_ENA) == PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + pas16->ticks = 0; - if (((pas16->pcm_ctrl & PAS16_PCM_AND_DMA_ENA) == PAS16_PCM_AND_DMA_ENA) && - dma_channel_readable(pas16->dma) && (pit->counters[1].m & 2) && new_out) { if (pas16->pcm_ctrl & PAS16_PCM_MONO) { temp = pas16_readdma_mono(pas16); @@ -929,7 +970,22 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16->irq_stat = (pas16->irq_stat & 0xdf) | (pas16->stereo_lr << 5); } } - } + + if (pas16->ticks) { + for (uint8_t i = 0; i < pas16->ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + pas16->ticks = 0; + } + + pas16->irq_stat |= PAS16_INT_SAMP; + if (pas16->irq_ena & PAS16_INT_SAMP) { + pas16_log("INT SAMP.\n"); + picint(1 << pas16->irq); + } + + pas16_update(pas16); + } } static void @@ -938,16 +994,15 @@ pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) pitf_t *pit = (pitf_t * )priv; pas16_t *pas16 = (pas16_t *) pit->dev_priv; + if (!pas16->pit->counters[1].gate) + return; + /* At new_out = 0, it's in the counter reload phase. */ if ((pas16->pcm_ctrl & PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { if (pas16->irq_ena & PAS16_INT_PCM) { pas16->irq_stat |= PAS16_INT_PCM; pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); picint(1 << pas16->irq); - - pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; - pas16->dma8_ff = 0; } } } @@ -1019,14 +1074,19 @@ pas16_update(pas16_t *pas16) for (; pas16->pos < sound_pos_global; pas16->pos++) { pas16->pcm_buffer[0][pas16->pos] = 0; pas16->pcm_buffer[1][pas16->pos] = 0; +#ifdef CROSS_CHANNEL if (pas16->pcm_ctrl & 0x08) - pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_l; + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; if (pas16->pcm_ctrl & 0x04) - pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_r; + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_r; if (pas16->pcm_ctrl & 0x02) - pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_l; if (pas16->pcm_ctrl & 0x01) - pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_r; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; +#else + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; +#endif } } } @@ -1039,11 +1099,11 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c++) { - buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; + buffer[c] += (int32_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; if (pas16->filter) - buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1])) / 2.0; + buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1]) / 1.3) / 2.0; else - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); + buffer[c] += ((pas16->pcm_buffer[c & 1][c >> 1] / 1.3) / 2); } pas16->pos = 0; @@ -1086,9 +1146,11 @@ pas16_init(const device_t *info) sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); - mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + mpu401_init(pas16->mpu, 0, 0, M_INTELLIGENT, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); + pas16->sb_compat_base = 0x0000; + io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pas16->this_id = 0xbc + pas16_next; From d52b606cec97e70f428dc1593e68da0a44c7dcc3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Apr 2024 03:10:29 +0200 Subject: [PATCH 412/690] SiS PCI flags corrections. --- src/machine/m_at_386dx_486.c | 2 +- src/machine/m_at_slot1.c | 4 ++-- src/machine/m_at_socket4.c | 4 ++-- src/machine/m_at_socket5.c | 8 ++++---- src/machine/m_at_socket7.c | 6 +++--- src/machine/m_at_socket7_3v.c | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b89f77b18..ea7e00ddc 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -992,7 +992,7 @@ machine_at_sis_85c496_common_init(UNUSED(const machine_t *model)) { device_add(&ide_pci_2ch_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a3c25d12b..c199be2e9 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -821,7 +821,7 @@ machine_at_p6f99_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -854,7 +854,7 @@ machine_at_m747_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 02018949c..f7aad92ec 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -65,7 +65,7 @@ machine_at_sp4_common_init(const machine_t *model) { machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Excluded: 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14 */ @@ -422,7 +422,7 @@ machine_at_excaliburpci2_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 916f8490b..773f8d980 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -465,7 +465,7 @@ machine_at_sq588_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Correct: 0D (01), 0F (02), 11 (03), 13 (04) */ @@ -496,7 +496,7 @@ machine_at_p54sps_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -526,7 +526,7 @@ machine_at_ms5109_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_IDE, 0, 0, 0, 0); @@ -557,7 +557,7 @@ machine_at_torino_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_VIDEO, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index ce21c6437..6ba7cb41d 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1312,7 +1312,7 @@ machine_at_sp97xv_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1341,7 +1341,7 @@ machine_at_sq578_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -1368,7 +1368,7 @@ machine_at_ms5172_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 676f50fb1..fdf155894 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -872,7 +872,7 @@ machine_at_5sbm2_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); From b674619894817cebf3d6a0c4039a3b5237313f53 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 5 Apr 2024 14:11:49 +0200 Subject: [PATCH 413/690] Video7/Radius fixes. And cleanups as well. Htotal/hblankstart are now applicable to the HT216-32 card only. Re-apply the Radius ISA SVGA extensions port workaround until a proper ISA bios is found/dumped (warning: the HT209 may not work properly on the PS/1 2121 machine). --- src/video/vid_ht216.c | 83 ++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index b87d93665..213cf9ed4 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -313,7 +313,8 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) break; case 0xca: - svga_recalctimings(svga); + if (ht216->id == 0x7861) + svga_recalctimings(svga); break; case 0xc9: @@ -481,12 +482,14 @@ ht216_in(uint16_t addr, void *priv) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - if ((ht216->id == 0x7152) && ht216->isabus) { - if (addr == 0x105) - return ht216->extensions; - } - switch (addr) { + case 0x105: + if (ht216->isabus && (ht216->id == 0x7152)) { + ret &= ~0x03; + return ret; + } + break; + case 0x3c4: return svga->seqaddr; @@ -624,6 +627,16 @@ ht216_recalctimings(svga_t *svga) ht216_t *ht216 = (ht216_t *) svga->priv; int high_res_256 = 0; + + if (ht216->id == 0x7861) { + if (ht216->ht_regs[0xe0] & 0x20) { + if (ht216->ht_regs[0xca] & 0x01) + svga->htotal |= 0x200; + if (ht216->ht_regs[0xca] & 0x04) + svga->hblankstart |= 0x200; + } + } + switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | ((ht216->ht_regs[0xf8] << 1) & 8)) { case 0: case 1: @@ -644,12 +657,15 @@ ht216_recalctimings(svga_t *svga) svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); - svga->interlace = ht216->ht_regs[0xe0] & 1; + if (ht216->ht_regs[0xf6] & 0x80) + svga->ma_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12); + + svga->interlace = ht216->ht_regs[0xe0] & 0x01; if (svga->interlace) - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + high_res_256 = (svga->htotal << 3) > (svga->vtotal << 2); else - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + high_res_256 = (svga->htotal << 3) > (svga->vtotal << 1); ht216->adjust_cursor = 0; @@ -706,15 +722,10 @@ ht216_recalctimings(svga_t *svga) } } - svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14); - if (svga->crtc[0x17] == 0xeb) /*Looks like 1024x768 mono mode expects 512K of video memory*/ svga->vram_display_mask = 0x7ffff; else svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; - - if (ht216->ht_regs[0xe0] & 0x20) - svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4]; } static void @@ -737,9 +748,9 @@ ht216_hwcursor_draw(svga_t *svga, int displine) for (int x = 0; x < width; x++) { if (!(dat[0] & 0x80000000)) - (buffer32->line[displine])[svga->x_add + offset + x] = 0; + svga->monitor->target_buffer->line[displine][svga->x_add + offset + x] = 0; if (dat[1] & 0x80000000) - (buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; + svga->monitor->target_buffer->line[displine][svga->x_add + offset + x] ^= 0xffffff; dat[0] <<= shift; dat[1] <<= shift; @@ -1530,12 +1541,13 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) } break; case 4: - if ((info->local == 0x7152) && (info->flags & DEVICE_ISA)) - ht216->extensions = device_get_config_int("extensions"); - else if ((info->local == 0x7152) && (info->flags & DEVICE_MCA)) { - ht216->pos_regs[0] = 0xb7; - ht216->pos_regs[1] = 0x80; - mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + if (info->local == 0x7152) { + if (info->flags & DEVICE_MCA) { + ht216->pos_regs[0] = 0xb7; + ht216->pos_regs[1] = 0x80; + mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + } else + io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, NULL, NULL, NULL, ht216); } rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; @@ -1723,31 +1735,6 @@ static const device_config_t ht216_32_standalone_config[] = { .type = CONFIG_END } }; - -static const device_config_t radius_svga_multiview_config[] = { - { - .name = "extensions", - .description = "Extensions", - .type = CONFIG_SELECTION, - .default_int = 0x00, - .selection = { - { - .description = "Extensions Enabled", - .value = 0x00 - }, - { - .description = "Extensions Disabled", - .value = 0x02 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } -}; // clang-format on const device_t g2_gc205_device = { @@ -1817,7 +1804,7 @@ const device_t radius_svga_multiview_isa_device = { { .available = radius_svga_multiview_available }, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, - .config = radius_svga_multiview_config + .config = NULL }; const device_t radius_svga_multiview_mca_device = { From bc6aacec71e4535e6577b8bc320a102ac6926357 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 6 Apr 2024 02:44:50 +0200 Subject: [PATCH 414/690] PASPlus fix for PoP1 Okay, turns out bit 5 (for the board revision) is for all PAS2-based cards, which includes both Plus and 16. This should fix the PCM IRQ on PoP1 and board detection on Plus DOS drivers. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 9812ced64..4530bda86 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -309,7 +309,7 @@ pas16_in(uint16_t port, void *priv) ret = pas16->audiofilt; break; case 0x0803: - ret = pas16->irq_ena | (pas16->type ? 0x20 : 0x00); + ret = pas16->irq_ena | 0x20; pas16_log("IRQ Mask read=%02x.\n", ret); break; From b6ae0a0e5b91e331e6669469ae72c47e208f0211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Mon, 8 Apr 2024 17:28:53 +0200 Subject: [PATCH 415/690] Create SECURITY.md --- SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..fe8394883 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| --------- | ------------------ | +| >= master | :white_check_mark: | +| < master | :x: | + +Each version is supported in the form of patch releases until the next version is merged into master. + +## Reporting a Vulnerability + +To report a vulnerability, either open an issue here on GitHub or join our Discord server. If it is +accepted, that means we have begun working on it and it will be fixed if it is at all possible. If it +is declined, then that means we have either determined it to not actually be a vulnerability or we +have determined it is not feasible to fix it. On GitHub, we are going to notify you when a decision +taken, and if accepted, when it is fixed. On Discord, you get live updates. From da1ededb9383ae14ee72eed3ed5b809242ec31a6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 10 Apr 2024 17:27:30 +0200 Subject: [PATCH 416/690] SCSI CD-ROM and 5380 fixes. CD-ROM side: fixed a mode sense page (0x08 Sony, used by both Sony and Texel drives) as well as corrected the Toshiba specific drive speeds (bytes_per_second). NCR 5380 side: split the work into the generic 5380 core and the ASICs into separate sources (53c400 and T128) and added the T228 MCA adapter based on the 128. --- src/include/86box/scsi_device.h | 4 +- src/include/86box/scsi_ncr5380.h | 114 ++- src/scsi/CMakeLists.txt | 4 +- src/scsi/scsi.c | 1 + src/scsi/scsi_cdrom.c | 2 +- src/scsi/scsi_ncr5380.c | 1595 +++--------------------------- src/scsi/scsi_ncr53c400.c | 998 +++++++++++++++++++ src/scsi/scsi_t128.c | 631 ++++++++++++ 8 files changed, 1865 insertions(+), 1484 deletions(-) create mode 100644 src/scsi/scsi_ncr53c400.c create mode 100644 src/scsi/scsi_t128.c diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 09f9ee2d9..216fdb2ad 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -173,8 +173,8 @@ #define GPMODEP_RIGID_DISK_PAGE 0x0000000000000010LL #define GPMODEP_FLEXIBLE_DISK_PAGE 0x0000000000000020LL #define GPMODEP_CACHING_PAGE 0x0000000000000100LL -#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000200LL -#define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000400LL +#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000100LL +#define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000200LL #define GPMODEP_CDROM_PAGE 0x0000000000002000LL #define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL #define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index ecf5660ef..a213e299d 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -6,9 +6,8 @@ * * This file is part of the 86Box distribution. * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for - * the ISA bus. + * Implementation of the NCR 5380 chip made by NCR + * and used in various controllers. * * * @@ -17,21 +16,128 @@ * Fred N. van Kempen, * * Copyright 2017-2018 Sarah Walker. - * Copyright 2017-2018 TheCollector1995. * Copyright 2017-2018 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. */ #ifndef SCSI_NCR5380_H #define SCSI_NCR5380_H +#define NCR_CURDATA 0 /* current SCSI data (read only) */ +#define NCR_OUTDATA 0 /* output data (write only) */ +#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ +#define NCR_MODE 2 /* mode (read/write) */ +#define NCR_TARGETCMD 3 /* target command (read/write) */ +#define NCR_SELENABLE 4 /* select enable (write only) */ +#define NCR_BUSSTATUS 4 /* bus status (read only) */ +#define NCR_STARTDMA 5 /* start DMA send (write only) */ +#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ +#define NCR_DMATARGET 6 /* DMA target (write only) */ +#define NCR_INPUTDATA 6 /* input data (read only) */ +#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ +#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ + +#define ICR_DBP 0x01 +#define ICR_ATN 0x02 +#define ICR_SEL 0x04 +#define ICR_BSY 0x08 +#define ICR_ACK 0x10 +#define ICR_ARB_LOST 0x20 +#define ICR_ARB_IN_PROGRESS 0x40 + +#define MODE_ARBITRATE 0x01 +#define MODE_DMA 0x02 +#define MODE_MONITOR_BUSY 0x04 +#define MODE_ENA_EOP_INT 0x08 + +#define STATUS_ACK 0x01 +#define STATUS_BUSY_ERROR 0x04 +#define STATUS_PHASE_MATCH 0x08 +#define STATUS_INT 0x10 +#define STATUS_DRQ 0x40 +#define STATUS_END_OF_DMA 0x80 + +#define TCR_IO 0x01 +#define TCR_CD 0x02 +#define TCR_MSG 0x04 +#define TCR_REQ 0x08 +#define TCR_LAST_BYTE_SENT 0x80 + + +#define STATE_IDLE 0 +#define STATE_COMMAND 1 +#define STATE_DATAIN 2 +#define STATE_DATAOUT 3 +#define STATE_STATUS 4 +#define STATE_MESSAGEIN 5 +#define STATE_SELECT 6 +#define STATE_MESSAGEOUT 7 +#define STATE_MESSAGE_ID 8 + +#define DMA_IDLE 0 +#define DMA_SEND 1 +#define DMA_INITIATOR_RECEIVE 2 + +typedef struct ncr_t { + uint8_t icr; + uint8_t mode; + uint8_t tcr; + uint8_t data_wait; + uint8_t isr; + uint8_t output_data; + uint8_t target_id; + uint8_t tx_data; + uint8_t msglun; + + uint8_t command[20]; + uint8_t msgout[4]; + uint8_t bus; + + int msgout_pos; + int is_msgout; + + int dma_mode; + int cur_bus; + int bus_in; + int new_phase; + int state; + int clear_req; + int wait_data; + int wait_complete; + int command_pos; + int data_pos; + + int irq; + + double period; + + void *priv; + void (*dma_mode_ext)(void *priv, void *ext_priv); + int (*dma_send_ext)(void *priv, void *ext_priv); + int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); + void (*timer)(void *ext_priv, double period); +} ncr_t; + +extern int ncr5380_cmd_len[8]; + +extern void ncr5380_irq(ncr_t *ncr, int set_irq); +extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); +extern void ncr5380_bus_read(ncr_t *ncr); +extern void ncr5380_bus_update(ncr_t *ncr, int bus); +extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); +extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); + +#ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; +extern const device_t scsi_t228_device; extern const device_t scsi_t130b_device; extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif +#endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt index addde844e..01e20b929 100644 --- a/src/scsi/CMakeLists.txt +++ b/src/scsi/CMakeLists.txt @@ -14,5 +14,5 @@ # add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c - scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c - scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) + scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c scsi_ncr53c400.c + scsi_t128.c scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 94c9048ef..328810a2f 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -82,6 +82,7 @@ static SCSI_CARD scsi_cards[] = { { &scsi_rt1000b_device, }, { &scsi_rt1000mc_device, }, { &scsi_t128_device, }, + { &scsi_t228_device, }, { &scsi_t130b_device, }, { &aha1640_device, }, { &buslogic_640a_device, }, diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index a6420fb01..3a49085ec 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1001,7 +1001,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_TOSHIBA_XM3301TA_0272: case CDROM_TYPE_TOSHIBA_XM5701TA_3136: case CDROM_TYPE_TOSHIBA_SDM1401_1008: - bytes_per_second = 176.0 * 1024.0; + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index e9ebe8504..d113d2cb3 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -6,8 +6,8 @@ * * This file is part of the 86Box distribution. * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for the ISA bus. + * Implementation of the NCR 5380 chip made by NCR + * and used in various controllers. * * * @@ -16,8 +16,8 @@ * Fred N. van Kempen, * * Copyright 2017-2019 Sarah Walker. - * Copyright 2017-2019 TheCollector1995. * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. */ #include #include @@ -42,156 +42,13 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" -#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" -#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" -#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" - -#define NCR_CURDATA 0 /* current SCSI data (read only) */ -#define NCR_OUTDATA 0 /* output data (write only) */ -#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ -#define NCR_MODE 2 /* mode (read/write) */ -#define NCR_TARGETCMD 3 /* target command (read/write) */ -#define NCR_SELENABLE 4 /* select enable (write only) */ -#define NCR_BUSSTATUS 4 /* bus status (read only) */ -#define NCR_STARTDMA 5 /* start DMA send (write only) */ -#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ -#define NCR_DMATARGET 6 /* DMA target (write only) */ -#define NCR_INPUTDATA 6 /* input data (read only) */ -#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ -#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ - -#define ICR_DBP 0x01 -#define ICR_ATN 0x02 -#define ICR_SEL 0x04 -#define ICR_BSY 0x08 -#define ICR_ACK 0x10 -#define ICR_ARB_LOST 0x20 -#define ICR_ARB_IN_PROGRESS 0x40 - -#define MODE_ARBITRATE 0x01 -#define MODE_DMA 0x02 -#define MODE_MONITOR_BUSY 0x04 -#define MODE_ENA_EOP_INT 0x08 - -#define STATUS_ACK 0x01 -#define STATUS_BUSY_ERROR 0x04 -#define STATUS_PHASE_MATCH 0x08 -#define STATUS_INT 0x10 -#define STATUS_DRQ 0x40 -#define STATUS_END_OF_DMA 0x80 - -#define TCR_IO 0x01 -#define TCR_CD 0x02 -#define TCR_MSG 0x04 -#define TCR_REQ 0x08 -#define TCR_LAST_BYTE_SENT 0x80 - -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_53C80_ACCESSIBLE 0x80 - -typedef struct ncr_t { - uint8_t icr; - uint8_t mode; - uint8_t tcr; - uint8_t data_wait; - uint8_t isr; - uint8_t output_data; - uint8_t target_id; - uint8_t tx_data; - uint8_t msglun; - - uint8_t command[20]; - uint8_t msgout[4]; - int msgout_pos; - int is_msgout; - - int dma_mode; - int cur_bus; - int bus_in; - int new_phase; - int state; - int clear_req; - int wait_data; - int wait_complete; - int command_pos; - int data_pos; -} ncr_t; - -typedef struct t128_t { - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - int bios_enabled; -} t128_t; - -typedef struct ncr5380_t { - ncr_t ncr; - t128_t t128; - - const char *name; - - uint8_t buffer[128]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; - - uint32_t rom_addr; - uint16_t base; - - int8_t irq; - int8_t type; - int8_t bios_ver; - uint8_t block_count; - uint8_t status_ctrl; - uint8_t bus, pad; - - rom_t bios_rom; - mem_mapping_t mapping; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int dma_enabled; - - pc_timer_t timer; - double period; - - int ncr_busy; - uint8_t pos_regs[8]; -} ncr5380_t; - -#define STATE_IDLE 0 -#define STATE_COMMAND 1 -#define STATE_DATAIN 2 -#define STATE_DATAOUT 3 -#define STATE_STATUS 4 -#define STATE_MESSAGEIN 5 -#define STATE_SELECT 6 -#define STATE_MESSAGEOUT 7 -#define STATE_MESSAGE_ID 8 - -#define DMA_IDLE 0 -#define DMA_SEND 1 -#define DMA_INITIATOR_RECEIVE 2 - -static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; +int ncr5380_cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; static void -ncr_log(const char *fmt, ...) +ncr5380_log(const char *fmt, ...) { va_list ap; @@ -202,28 +59,27 @@ ncr_log(const char *fmt, ...) } } #else -# define ncr_log(fmt, ...) +# define ncr5380_log(fmt, ...) #endif #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) -static void -ncr_callback(void *priv); - -static void -ncr_irq(ncr5380_t *ncr_dev, ncr_t *ncr, int set_irq) +void +ncr5380_irq(ncr_t *ncr, int set_irq) { if (set_irq) { ncr->isr |= STATUS_INT; - picint(1 << ncr_dev->irq); + if (ncr->irq != -1) + picint(1 << ncr->irq); } else { ncr->isr &= ~STATUS_INT; - picintc(1 << ncr_dev->irq); + if (ncr->irq != 1) + picintc(1 << ncr->irq); } } static int -get_dev_id(uint8_t data) +ncr5380_get_dev_id(uint8_t data) { for (uint8_t c = 0; c < SCSI_ID_MAX; c++) { if (data & (1 << c)) @@ -234,7 +90,7 @@ get_dev_id(uint8_t data) } static int -getmsglen(uint8_t *msgp, int len) +ncr5380_getmsglen(uint8_t *msgp, int len) { uint8_t msg = msgp[0]; if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) || msg >= 0x80) @@ -247,21 +103,32 @@ getmsglen(uint8_t *msgp, int len) } static void -ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) +ncr5380_reset(ncr_t *ncr) { - memset(ncr, 0x00, sizeof(ncr_t)); - ncr_log("NCR Reset\n"); + ncr->command_pos = 0; + ncr->data_pos = 0; + ncr->state = STATE_IDLE; + ncr->clear_req = 0; + ncr->cur_bus = 0; + ncr->tx_data = 0; + ncr->output_data = 0; + ncr->data_wait = 0; + ncr->mode = 0; + ncr->tcr = 0; + ncr->icr = 0; + ncr->dma_mode = DMA_IDLE; + ncr5380_log("NCR Reset\n"); - timer_stop(&ncr_dev->timer); + ncr->timer(ncr->priv, 0.0); for (int i = 0; i < 8; i++) - scsi_device_reset(&scsi_devices[ncr_dev->bus][i]); + scsi_device_reset(&scsi_devices[ncr->bus][i]); - ncr_irq(ncr_dev, ncr, 0); + ncr5380_irq(ncr, 0); } -static uint32_t -get_bus_host(ncr_t *ncr) +uint32_t +ncr5380_get_bus_host(ncr_t *ncr) { uint32_t bus_host = 0; @@ -298,10 +165,9 @@ get_bus_host(ncr_t *ncr) return (bus_host | BUS_SETDATA(ncr->output_data)); } -static void -ncr_bus_read(ncr5380_t *ncr_dev) +void +ncr5380_bus_read(ncr_t *ncr) { - ncr_t *ncr = &ncr_dev->ncr; const scsi_device_t *dev; int phase; @@ -309,7 +175,7 @@ ncr_bus_read(ncr5380_t *ncr_dev) if (ncr->clear_req) { ncr->clear_req--; if (!ncr->clear_req) { - ncr_log("Prelude to command data\n"); + ncr5380_log("Prelude to command data\n"); SET_BUS_STATE(ncr, ncr->new_phase); ncr->cur_bus |= BUS_REQ; } @@ -318,7 +184,7 @@ ncr_bus_read(ncr5380_t *ncr_dev) if (ncr->wait_data) { ncr->wait_data--; if (!ncr->wait_data) { - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; SET_BUS_STATE(ncr, ncr->new_phase); phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN); @@ -354,12 +220,10 @@ ncr_bus_read(ncr5380_t *ncr_dev) } } -static void -ncr_bus_update(void *priv, int bus) +void +ncr5380_bus_update(ncr_t *ncr, int bus) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; double p; uint8_t sel_data; int msglen; @@ -368,25 +232,25 @@ ncr_bus_update(void *priv, int bus) if (bus & BUS_ARB) ncr->state = STATE_IDLE; - ncr_log("State = %i\n", ncr->state); + ncr5380_log("State = %i\n", ncr->state); switch (ncr->state) { case STATE_IDLE: ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { - ncr_log("Selection phase\n"); + ncr5380_log("Selection phase\n"); sel_data = BUS_GETDATA(bus); - ncr->target_id = get_dev_id(sel_data); + ncr->target_id = ncr5380_get_dev_id(sel_data); - ncr_log("Select - target ID = %i\n", ncr->target_id); + ncr5380_log("Select - target ID = %i\n", ncr->target_id); /*Once the device has been found and selected, mark it as busy*/ - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { ncr->cur_bus |= BUS_BSY; ncr->state = STATE_SELECT; } else { - ncr_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + ncr5380_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); ncr->cur_bus = 0; } } @@ -394,11 +258,11 @@ ncr_bus_update(void *priv, int bus) case STATE_SELECT: if (!(bus & BUS_SEL)) { if (!(bus & BUS_ATN)) { - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { + ncr5380_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); ncr->state = STATE_COMMAND; ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr->command_pos = 0; SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); } else { @@ -406,7 +270,7 @@ ncr_bus_update(void *priv, int bus) ncr->cur_bus = 0; } } else { - ncr_log("Set to SCSI Message Out\n"); + ncr5380_log("Set to SCSI Message Out\n"); ncr->new_phase = SCSI_PHASE_MESSAGE_OUT; ncr->wait_data = 4; ncr->msgout_pos = 0; @@ -422,9 +286,9 @@ ncr_bus_update(void *priv, int bus) ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; ncr->cur_bus &= ~BUS_REQ; - ncr_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); + ncr5380_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); - if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { + if (ncr->command_pos == ncr5380_cmd_len[(ncr->command[0] >> 5) & 7]) { if (ncr->is_msgout) { ncr->is_msgout = 0; #if 0 @@ -435,23 +299,23 @@ ncr_bus_update(void *priv, int bus) /*Reset data position to default*/ ncr->data_pos = 0; - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; - ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); + ncr5380_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); dev->buffer_length = -1; scsi_device_command_phase0(dev, ncr->command); - ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); + ncr5380_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); - ncr_dev->period = 1.0; + ncr->period = 1.0; ncr->wait_data = 4; ncr->data_wait = 0; if (dev->status == SCSI_STATUS_OK) { /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ - if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { + if (dev->buffer_length && ((dev->phase == SCSI_PHASE_DATA_IN) || (dev->phase == SCSI_PHASE_DATA_OUT))) { p = scsi_device_get_callback(dev); - ncr_dev->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); - ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr_dev->period, dev->buffer_length, ncr->dma_mode); + ncr->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); + ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } ncr->new_phase = dev->phase; @@ -459,7 +323,7 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_DATAIN: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { if (ncr->data_pos >= dev->buffer_length) { ncr->cur_bus &= ~BUS_REQ; @@ -472,10 +336,10 @@ ncr_bus_update(void *priv, int bus) ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; - ncr_log("DMA mode idle in\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); + ncr5380_log("DMA mode idle in\n"); + ncr->timer(ncr->priv, ncr->period); } else { - ncr_log("DMA mode IN.\n"); + ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; } @@ -485,7 +349,7 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_DATAOUT: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); @@ -499,20 +363,20 @@ ncr_bus_update(void *priv, int bus) /*More data is to be transferred, place a request*/ if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; - ncr_log("DMA mode idle out\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); + ncr5380_log("DMA mode idle out\n"); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; ncr->cur_bus &= ~BUS_REQ; - ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); } } break; case STATE_STATUS: if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { /*All transfers done, wait until next transfer*/ - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB); + scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], SCSI_LUN_USE_CDB); ncr->cur_bus &= ~BUS_REQ; ncr->new_phase = SCSI_PHASE_MESSAGE_IN; ncr->wait_data = 4; @@ -527,10 +391,10 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_MESSAGEOUT: - ncr_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); + ncr5380_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { ncr->msgout[ncr->msgout_pos++] = BUS_GETDATA(bus); - msglen = getmsglen(ncr->msgout, ncr->msgout_pos); + msglen = ncr5380_getmsglen(ncr->msgout, ncr->msgout_pos); if (ncr->msgout_pos >= msglen) { if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) ncr->msglun = ncr->msgout[0] & 7; @@ -540,12 +404,12 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_MESSAGE_ID: - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], ncr->msglun); + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { + ncr5380_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], ncr->msglun); ncr->state = STATE_COMMAND; ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr->command_pos = 0; SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); } @@ -558,33 +422,30 @@ ncr_bus_update(void *priv, int bus) ncr->bus_in = bus; } -static void -ncr_write(uint16_t port, uint8_t val, void *priv) +void +ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; int bus_host = 0; - ncr_log("NCR5380 write(%04x,%02x)\n", port & 7, val); + ncr5380_log("NCR5380 write(%04x,%02x)\n", port & 7, val); switch (port & 7) { case 0: /* Output data register */ - ncr_log("Write: Output data register, val = %02x\n", val); + ncr5380_log("Write: Output data register, val = %02x\n", val); ncr->output_data = val; break; case 1: /* Initiator Command Register */ - ncr_log("Write: Initiator command register\n"); + ncr5380_log("Write: Initiator command register\n"); if ((val & 0x80) && !(ncr->icr & 0x80)) { - ncr_log("Resetting the 5380\n"); - ncr_reset(ncr_dev, &ncr_dev->ncr); + ncr5380_log("Resetting the 5380\n"); + ncr5380_reset(ncr); } ncr->icr = val; break; case 2: /* Mode register */ - ncr_log("Write: Mode register, val=%02x.\n", val); + ncr5380_log("Write: Mode register, val=%02x.\n", val); if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { ncr->icr &= ~ICR_ARB_LOST; ncr->icr |= ICR_ARB_IN_PROGRESS; @@ -592,132 +453,85 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr->mode = val; - if (ncr_dev->type == 3) { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { - ncr_log("Continuing DMA mode\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); - } - - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->t128.block_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } else { - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } + ncr->dma_mode_ext(ncr, ncr->priv); break; case 3: /* Target Command Register */ - ncr_log("Write: Target Command register\n"); + ncr5380_log("Write: Target Command register\n"); ncr->tcr = val; break; case 4: /* Select Enable Register */ - ncr_log("Write: Select Enable register\n"); + ncr5380_log("Write: Select Enable register\n"); break; case 5: /* start DMA Send */ - ncr_log("Write: start DMA send register\n"); + ncr5380_log("Write: start DMA send register\n"); /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; - if (ncr_dev->type == 3) { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.status |= 0x04; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; - - ncr_dev->t128.block_loaded = 1; - } - } + if (ncr->dma_send_ext) + ncr->dma_send_ext(ncr, ncr->priv); break; case 7: /* start DMA Initiator Receive */ - ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); + ncr5380_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); /*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) { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.status |= 0x04; - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; - - ncr_dev->t128.block_loaded = 1; - timer_on_auto(&ncr_dev->timer, 0.02); - } - } + if (ncr->dma_initiator_receive_ext) + ncr->dma_initiator_receive_ext(ncr, ncr->priv); break; default: - ncr_log("NCR5380: bad write %04x %02x\n", port, val); + ncr5380_log("NCR5380: bad write %04x %02x\n", port, val); break; } - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); + bus_host = ncr5380_get_bus_host(ncr); + ncr5380_bus_update(ncr, bus_host); } -static uint8_t -ncr_read(uint16_t port, void *priv) +uint8_t +ncr5380_read(uint16_t port, ncr_t *ncr) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - uint8_t ret = 0xff; + uint8_t ret = 0xff; int bus; int bus_state; switch (port & 7) { case 0: /* Current SCSI data */ - ncr_log("Read: Current SCSI data register\n"); + ncr5380_log("Read: Current SCSI data register\n"); if (ncr->icr & ICR_DBP) { /*Return the data from the output register if on data bus phase from ICR*/ - ncr_log("Data Bus Phase, ret = %02x\n", ncr->output_data); + ncr5380_log("Data Bus Phase, ret = %02x\n", ncr->output_data); ret = ncr->output_data; } else { /*Return the data from the SCSI bus*/ - ncr_bus_read(ncr_dev); - ncr_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); + ncr5380_bus_read(ncr); + ncr5380_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); ret = BUS_GETDATA(ncr->cur_bus); } break; case 1: /* Initiator Command Register */ - ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); + ncr5380_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); ret = ncr->icr; break; case 2: /* Mode register */ - ncr_log("Read: Mode register = %02x.\n", ncr->mode); + ncr5380_log("Read: Mode register = %02x.\n", ncr->mode); ret = ncr->mode; break; case 3: /* Target Command Register */ - ncr_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); + ncr5380_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); ret = ncr->tcr; break; case 4: /* Current SCSI Bus status */ - ncr_log("Read: SCSI bus status register\n"); + ncr5380_log("Read: SCSI bus status register\n"); ret = 0; - ncr_bus_read(ncr_dev); - ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); + ncr5380_bus_read(ncr); + ncr5380_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); ret |= (ncr->cur_bus & 0xff); if (ncr->icr & ICR_SEL) ret |= BUS_SEL; @@ -726,19 +540,19 @@ ncr_read(uint16_t port, void *priv) break; case 5: /* Bus and Status register */ - ncr_log("Read: Bus and Status register\n"); + ncr5380_log("Read: Bus and Status register\n"); ret = 0; - bus = get_bus_host(ncr); - ncr_log("Get host from Interrupt\n"); + bus = ncr5380_get_bus_host(ncr); + ncr5380_log("Get host from Interrupt\n"); /*Check if the phase in process matches with TCR's*/ if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { - ncr_log("Phase match\n"); + ncr5380_log("Phase match\n"); ret |= STATUS_PHASE_MATCH; } - ncr_bus_read(ncr_dev); + ncr5380_bus_read(ncr); bus = ncr->cur_bus; if ((bus & BUS_ACK) || (ncr->icr & ICR_ACK)) @@ -747,7 +561,7 @@ ncr_read(uint16_t port, void *priv) ret |= 0x02; if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { - ncr_log("Entering DMA mode\n"); + ncr5380_log("Entering DMA mode\n"); ret |= STATUS_DRQ; bus_state = 0; @@ -759,12 +573,12 @@ ncr_read(uint16_t port, void *priv) if (bus & BUS_MSG) bus_state |= TCR_MSG; if ((ncr->tcr & 7) != bus_state) { - ncr_irq(ncr_dev, ncr, 1); - ncr_log("IRQ issued\n"); + ncr5380_irq(ncr, 1); + ncr5380_log("IRQ issued\n"); } } if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Busy error\n"); + ncr5380_log("Busy error\n"); ret |= STATUS_BUSY_ERROR; } ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); @@ -776,1185 +590,16 @@ ncr_read(uint16_t port, void *priv) case 7: /* reset Parity/Interrupt */ ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20); - ncr_irq(ncr_dev, ncr, 0); - ncr_log("Reset Interrupt\n"); + ncr5380_irq(ncr, 0); + ncr5380_log("Reset Interrupt\n"); break; default: - ncr_log("NCR5380: bad read %04x\n", port); + ncr5380_log("NCR5380: bad read %04x\n", port); break; } - ncr_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); + ncr5380_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); return ret; } - -/* Memory-mapped I/O READ handler. */ -static uint8_t -memio_read(uint32_t addr, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; - - addr &= 0x3fff; - - if (addr < 0x2000) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if (addr < 0x3800) - ret = 0xff; - else if (addr >= 0x3a00) - ret = ncr_dev->ext_ram[addr - 0x3a00]; - else - switch (addr & 0x3f80) { - case 0x3800: -#if ENABLE_NCR5380_LOG - ncr_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr_dev->int_ram[addr & 0x3f]); -#endif - ret = ncr_dev->int_ram[addr & 0x3f]; - break; - - case 0x3880: -#if ENABLE_NCR5380_LOG - ncr_log("Read 53c80 %04x\n", addr); -#endif - ret = ncr_read(addr, ncr_dev); - break; - - case 0x3900: - if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr_dev->status_ctrl & CTRL_DATA_DIR))) { - ret = 0xff; - ncr_log("No Read.\n"); - } else { - ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; - ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret); - - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_log("Transfer busy read, status = %02x\n", ncr_dev->status_ctrl); - } - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* status */ - ret = ncr_dev->status_ctrl; - ncr_log("NCR status ctrl read=%02x\n", ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY); - if (!ncr_dev->ncr_busy) - ret |= STATUS_53C80_ACCESSIBLE; - if (ncr->mode & 0x30) { /*Parity bits*/ - if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/ - ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/ - ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ - } - } - ncr_log("NCR 53c400 status = %02x.\n", ret); - break; - - case 0x3981: /* block counter register*/ - ret = ncr_dev->block_count; - break; - - case 0x3982: /* switch register read */ - ret = 0xf8; - ret |= (ncr_dev->irq & 0x07); - ncr_log("Switches read=%02x.\n", ret); - break; - - default: - break; - } - break; - - default: - break; - } - -#if ENABLE_NCR5380_LOG - if (addr >= 0x3880) - ncr_log("memio_read(%08x)=%02x\n", addr, ret); -#endif - - return ret; -} - -/* Memory-mapped I/O WRITE handler. */ -static void -memio_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - - addr &= 0x3fff; - - if (addr >= 0x3a00) - ncr_dev->ext_ram[addr - 0x3a00] = val; - else - switch (addr & 0x3f80) { - case 0x3800: - ncr_dev->int_ram[addr & 0x3f] = val; - break; - - case 0x3880: - ncr_write(addr, val, ncr_dev); - break; - - case 0x3900: - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR) && ncr_dev->buffer_host_pos < MIN(128, dev->buffer_length)) { - ncr_dev->buffer[ncr_dev->buffer_host_pos++] = val; - - ncr_log("Write host pos = %i, val = %02x\n", ncr_dev->buffer_host_pos, val); - - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 1; - } - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* Control */ - ncr_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - if ((val & CTRL_DATA_DIR) && !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else if (!(val & CTRL_DATA_DIR) && (ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - ncr_dev->status_ctrl = (ncr_dev->status_ctrl & 0x87) | (val & 0x78); - break; - - case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr_dev->period); - ncr_dev->block_count = val; - ncr_dev->block_count_loaded = 1; - - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA timer on\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } - break; - - default: - break; - } - break; - - default: - break; - } -} - -/* Memory-mapped I/O READ handler for the Trantor T130B. */ -static uint8_t -t130b_read(uint32_t addr, void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - uint8_t ret = 0xff; - - addr &= 0x3fff; - if (addr < 0x1800) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if (addr >= 0x1800 && addr < 0x1880) - ret = ncr_dev->ext_ram[addr & 0x7f]; - - ncr_log("MEM: Reading %02X from %08X\n", ret, addr); - return ret; -} - -/* Memory-mapped I/O WRITE handler for the Trantor T130B. */ -static void -t130b_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - addr &= 0x3fff; - ncr_log("MEM: Writing %02X to %08X\n", val, addr); - if (addr >= 0x1800 && addr < 0x1880) - ncr_dev->ext_ram[addr & 0x7f] = val; -} - -static uint8_t -t130b_in(uint16_t port, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - uint8_t ret = 0xff; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - ret = memio_read((port & 7) | 0x3980, ncr_dev); - break; - - case 0x04: - case 0x05: - ret = memio_read(0x3900, ncr_dev); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ret = ncr_read(port, ncr_dev); - break; - - default: - break; - } - - ncr_log("I/O: Reading %02X from %04X\n", ret, port); - return ret; -} - -static void -t130b_out(uint16_t port, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - ncr_log("I/O: Writing %02X to %04X\n", val, port); - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - memio_write((port & 7) | 0x3980, val, ncr_dev); - break; - - case 0x04: - case 0x05: - memio_write(0x3900, val, ncr_dev); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ncr_write(port, val, ncr_dev); - break; - - default: - break; - } -} - -static void -ncr_callback(void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - int bus; - int bytes_tx = 0; - int limit = 100; - uint8_t temp; - - if (ncr_dev->type != 3) { - if (ncr->dma_mode != DMA_IDLE) - timer_on_auto(&ncr_dev->timer, 1.0); - } else { - if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { - if ((ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) && ncr_dev->t128.block_count) - ncr_dev->t128.status |= 0x04; - - timer_on_auto(&ncr_dev->timer, ncr_dev->period / 55.0); - } - } - - if (ncr->data_wait & 1) { - ncr->clear_req = 3; - ncr->data_wait &= ~1; - if (ncr_dev->type == 3) { - if (ncr->dma_mode == DMA_IDLE) - return; - } - } - - if (ncr_dev->type != 3) { - if (ncr->dma_mode == DMA_IDLE) - return; - } - - switch (ncr->dma_mode) { - case DMA_SEND: - if (ncr_dev->type != 3) { - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_log("DMA_SEND with DMA direction set wrong\n"); - break; - } - - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Write buffer status ready\n"); - break; - } - - if (!ncr_dev->block_count_loaded) - break; - - while (bytes_tx < limit) { - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - temp = ncr_dev->buffer[ncr_dev->buffer_pos]; - - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(temp); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->buffer_pos++; - bytes_tx++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - bytes_tx = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } - } - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Write status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); - break; - } - - if (!ncr_dev->t128.block_loaded) { - ncr_log("Write block not loaded\n"); - break; - } - - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - -write_again: - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - temp = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(temp); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->t128.pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->t128.pos); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->ncr_busy = 0; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } else - goto write_again; - } - break; - - case DMA_INITIATOR_RECEIVE: - if (ncr_dev->type != 3) { - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); - break; - } - - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Read buffer status ready\n"); - break; - } - - if (!ncr_dev->block_count_loaded) - break; - - while (bytes_tx < limit) { - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - bytes_tx++; - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - bytes_tx = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } - } - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); - break; - } - - if (!ncr_dev->t128.block_loaded) { - ncr_log("Read block not loaded\n"); - break; - } - - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - -read_again: - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; - ncr_log("Buffer pos for reading=%d, temp=%02x, len=%d.\n", ncr_dev->t128.pos, temp, dev->buffer_length); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } else - goto read_again; - } - break; - - default: - break; - } - - ncr_bus_read(ncr_dev); - - if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Updating DMA\n"); - ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; - if (ncr_dev->type == 3) - timer_on_auto(&ncr_dev->timer, 10.0); - } -} - -static uint8_t -t128_read(uint32_t addr, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - const ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; - - addr &= 0x3fff; - if (ncr_dev->t128.bios_enabled && (addr >= 0) && (addr < 0x1800)) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if ((addr >= 0x1800) && (addr < 0x1880)) - ret = ncr_dev->t128.ext_ram[addr & 0x7f]; - else if ((addr >= 0x1c00) && (addr < 0x1c20)) { - ret = ncr_dev->t128.ctrl; - ncr_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); - } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { - ret = ncr_dev->t128.status; - ncr_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); - } else if ((addr >= 0x1d00) && (addr < 0x1e00)) - ret = ncr_read((addr - 0x1d00) >> 5, ncr_dev); - else if (addr >= 0x1e00 && addr < 0x2000) { - if ((ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length)) || - (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) - ret = 0xff; - else { - ret = ncr_dev->t128.buffer[ncr_dev->t128.host_pos++]; - - ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, - ncr_dev->t128.host_pos); - - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_log("Transfer busy read, status = %02x, period = %lf\n", - ncr_dev->t128.status, ncr_dev->period); - if ((ncr_dev->period == 0.2) || (ncr_dev->period == 0.02)) - timer_on_auto(&ncr_dev->timer, 40.2); - } else if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && - (scsi_device_get_callback(dev) > 100.0)) - cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ - } - } - - return ret; -} - -static void -t128_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - const ncr_t *ncr = &ncr_dev->ncr; - const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - - addr &= 0x3fff; - if ((addr >= 0x1800) && (addr < 0x1880)) - ncr_dev->t128.ext_ram[addr & 0x7f] = val; - else if ((addr >= 0x1c00) && (addr < 0x1c20)) { - if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) - ncr_dev->t128.status |= 0x02; - - ncr_dev->t128.ctrl = val; - ncr_log("T128 ctrl write=%02x\n", val); - } else if ((addr >= 0x1d00) && (addr < 0x1e00)) - ncr_write((addr - 0x1d00) >> 5, val, ncr_dev); - else if ((addr >= 0x1e00) && (addr < 0x2000)) { - if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && - (ncr->dma_mode == DMA_SEND)) { - ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; - ncr_dev->t128.host_pos++; - - ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", - addr & 0x1ff, ncr_dev->t128.host_pos, val); - - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_dev->ncr_busy = 1; - ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); - timer_on_auto(&ncr_dev->timer, 0.02); - } - } - } -} - -static uint8_t -rt1000b_mc_read(int port, void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - return (ncr_dev->pos_regs[port & 7]); -} - -static void -rt1000b_mc_write(int port, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) - return; - - mem_mapping_disable(&ncr_dev->bios_rom.mapping); - mem_mapping_disable(&ncr_dev->mapping); - - /* Save the MCA register value. */ - ncr_dev->pos_regs[port & 7] = val; - - if (ncr_dev->pos_regs[2] & 1) { - switch (ncr_dev->pos_regs[2] & 0xe0) { - case 0: - ncr_dev->rom_addr = 0xd4000; - break; - case 0x20: - ncr_dev->rom_addr = 0xd0000; - break; - case 0x40: - ncr_dev->rom_addr = 0xcc000; - break; - case 0x60: - ncr_dev->rom_addr = 0xc8000; - break; - case 0xc0: - ncr_dev->rom_addr = 0xdc000; - break; - case 0xe0: - ncr_dev->rom_addr = 0xd8000; - break; - - default: - break; - } - - mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000); - mem_mapping_set_addr(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000); - } -} - -static uint8_t -rt1000b_mc_feedb(void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - return ncr_dev->pos_regs[2] & 1; -} - -static void * -ncr_init(const device_t *info) -{ - const char *fn = NULL; - char temp[128]; - ncr5380_t *ncr_dev; - - ncr_dev = malloc(sizeof(ncr5380_t)); - memset(ncr_dev, 0x00, sizeof(ncr5380_t)); - ncr_dev->name = info->name; - ncr_dev->type = info->local; - - ncr_dev->bus = scsi_get_bus(); - - switch (ncr_dev->type) { - case 0: /* Longshine LCS6821N */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, LCS6821N_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - case 1: /* Rancho RT1000B/MC */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->bios_ver = device_get_config_int("bios_ver"); - if (info->flags & DEVICE_MCA) { - ncr_dev->rom_addr = 0xd8000; - ncr_dev->bios_ver = 1; - } - - switch (ncr_dev->bios_ver) { - case 0: - fn = RT1000B_810R_ROM; - break; - case 1: - fn = RT1000B_820R_ROM; - break; - } - - rom_init(&ncr_dev->bios_rom, fn, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - if (info->flags & DEVICE_MCA) { - mem_mapping_add(&ncr_dev->mapping, 0, 0, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - ncr_dev->pos_regs[0] = 0x8d; - ncr_dev->pos_regs[1] = 0x70; - mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev); - } else { - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } - break; - - case 2: /* Trantor T130B */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->base = device_get_config_hex16("base"); - ncr_dev->irq = device_get_config_int("irq"); - - if (ncr_dev->rom_addr > 0x00000) { - rom_init(&ncr_dev->bios_rom, T130B_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } - - io_sethandler(ncr_dev->base, 16, - t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr_dev); - break; - - case 3: /* Trantor T128 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->t128.bios_enabled = device_get_config_int("boot"); - - if (ncr_dev->t128.bios_enabled) - rom_init(&ncr_dev->bios_rom, T128_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t128_read, NULL, NULL, - t128_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - case 4: /* Corel LS2000 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, COREL_LS2000_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - default: - break; - } - - sprintf(temp, "%s: BIOS=%05X", ncr_dev->name, ncr_dev->rom_addr); - if (ncr_dev->base != 0) - sprintf(&temp[strlen(temp)], " I/O=%04x", ncr_dev->base); - if (ncr_dev->irq != 0) - sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); - ncr_log("%s\n", temp); - - if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) { - ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_host_pos = 128; - } else { - ncr_dev->t128.status = 0x04; - ncr_dev->t128.host_pos = 512; - if (!ncr_dev->t128.bios_enabled) - ncr_dev->t128.status |= 0x80; - } - timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0); - - scsi_bus_set_speed(ncr_dev->bus, 5000000.0); - - return ncr_dev; -} - -static void -ncr_close(void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - if (ncr_dev) { - /* Tell the timer to terminate. */ - timer_stop(&ncr_dev->timer); - - free(ncr_dev); - ncr_dev = NULL; - } -} - -static int -lcs6821n_available(void) -{ - return (rom_present(LCS6821N_ROM)); -} - -static int -rt1000b_available(void) -{ - return (rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM)); -} - -static int -rt1000b_820_available(void) -{ - return (rom_present(RT1000B_820R_ROM)); -} - -static int -t130b_available(void) -{ - return (rom_present(T130B_ROM)); -} - -static int -t128_available(void) -{ - return (rom_present(T128_ROM)); -} - -static int -corel_ls2000_available(void) -{ - return (rom_present(COREL_LS2000_ROM)); -} - -// clang-format off -static const device_config_t ncr5380_mmio_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t rancho_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "8.20R", .value = 1 }, - { .description = "8.10R", .value = 0 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t rancho_mc_config[] = { - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t t130b_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Disabled", .value = 0 }, - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0350, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "240H", .value = 0x0240 }, - { .description = "250H", .value = 0x0250 }, - { .description = "340H", .value = 0x0340 }, - { .description = "350H", .value = 0x0350 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t t128_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner ={ 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { - .name = "boot", - .description = "Enable Boot ROM", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t scsi_lcs6821n_device = { - .name = "Longshine LCS-6821N", - .internal_name = "lcs6821n", - .flags = DEVICE_ISA, - .local = 0, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = lcs6821n_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config -}; - -const device_t scsi_rt1000b_device = { - .name = "Rancho RT1000B", - .internal_name = "rt1000b", - .flags = DEVICE_ISA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = rt1000b_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_config -}; - -const device_t scsi_rt1000mc_device = { - .name = "Rancho RT1000B-MC", - .internal_name = "rt1000mc", - .flags = DEVICE_MCA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = rt1000b_820_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_mc_config -}; - -const device_t scsi_t130b_device = { - .name = "Trantor T130B", - .internal_name = "t130b", - .flags = DEVICE_ISA, - .local = 2, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = t130b_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = t130b_config -}; - -const device_t scsi_t128_device = { - .name = "Trantor T128", - .internal_name = "t128", - .flags = DEVICE_ISA, - .local = 3, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = t128_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = t128_config -}; - -const device_t scsi_ls2000_device = { - .name = "Corel LS2000", - .internal_name = "ls2000", - .flags = DEVICE_ISA, - .local = 4, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = corel_ls2000_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config -}; diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c new file mode 100644 index 000000000..d605f1bdb --- /dev/null +++ b/src/scsi/scsi_ncr53c400.c @@ -0,0 +1,998 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NCR 53c400 series of SCSI Host Adapters + * made by NCR. These controllers were designed for the ISA and MCA bus. + * + * + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/pic.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/nvr.h> +#include <86box/plat.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/scsi_ncr5380.h> + +#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" +#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" +#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" +#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" +#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" + +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + +enum { + ROM_LCS6821N = 0, + ROM_LS2000, + ROM_RT1000B, + ROM_T130B +}; + +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + +#ifdef ENABLE_NCR53C400_LOG +int ncr53c400_do_log = ENABLE_NCR53C400_LOG; + +static void +ncr53c400_log(const char *fmt, ...) +{ + va_list ap; + + if (ncr53c400_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ncr53c400_log(fmt, ...) +#endif + +/* Memory-mapped I/O WRITE handler. */ +static void +ncr53c400_write(uint32_t addr, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + addr &= 0x3fff; + + if (addr >= 0x3a00) + ncr400->ext_ram[addr - 0x3a00] = val; + else { + switch (addr & 0x3f80) { + case 0x3800: + ncr400->int_ram[addr & 0x3f] = val; + break; + + case 0x3880: + ncr5380_write(addr, val, ncr); + break; + + case 0x3900: + if (!(ncr400->status_ctrl & CTRL_DATA_DIR) && (ncr400->buffer_host_pos < MIN(128, dev->buffer_length))) { + ncr400->buffer[ncr400->buffer_host_pos++] = val; + + ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + + if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr400->busy = 1; + } + } + break; + + case 0x3980: + switch (addr) { + case 0x3980: /* Control */ + ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + if ((val & CTRL_DATA_DIR) && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr400->buffer_host_pos = MIN(128, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else if (!(val & CTRL_DATA_DIR) && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); + break; + + case 0x3981: /* block counter register */ + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr->period); + ncr400->block_count = val; + ncr400->block_count_loaded = 1; + + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr400->buffer_host_pos = MIN(128, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr400->timer) && (dev->buffer_length > 0)) { + memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); + ncr53c400_log("DMA timer on\n"); + timer_on_auto(&ncr400->timer, ncr->period); + } + break; + + default: + break; + } + break; + + default: + break; + } + } +} + +/* Memory-mapped I/O READ handler. */ +static uint8_t +ncr53c400_read(uint32_t addr, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + addr &= 0x3fff; + + if (addr < 0x2000) + ret = ncr400->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x3800) + ret = 0xff; + else if (addr >= 0x3a00) + ret = ncr400->ext_ram[addr - 0x3a00]; + else { + switch (addr & 0x3f80) { + case 0x3800: + ncr53c400_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); + ret = ncr400->int_ram[addr & 0x3f]; + break; + + case 0x3880: + ncr53c400_log("Read 5380 %04x\n", addr); + ret = ncr5380_read(addr, ncr); + break; + + case 0x3900: + if (ncr400->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr400->status_ctrl & CTRL_DATA_DIR))) { + ret = 0xff; + ncr53c400_log("No Read.\n"); + } else { + ret = ncr400->buffer[ncr400->buffer_host_pos++]; + ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + + if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + } + } + break; + + case 0x3980: + switch (addr) { + case 0x3980: /* status */ + ret = ncr400->status_ctrl; + ncr53c400_log("NCR status ctrl read=%02x\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); + if (!ncr400->busy) + ret |= STATUS_5380_ACCESSIBLE; + if (ncr->mode & 0x30) { /*Parity bits*/ + if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/ + ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/ + ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ + } + } + ncr53c400_log("NCR 53c400 status = %02x.\n", ret); + break; + + case 0x3981: /* block counter register*/ + ret = ncr400->block_count; + break; + + case 0x3982: /* switch register read */ + ret = 0xf8; + ret |= (ncr->irq & 0x07); + ncr53c400_log("Switches read=%02x.\n", ret); + break; + + default: + break; + } + break; + + default: + break; + } + } + + if (addr >= 0x3880) + ncr53c400_log("memio_read(%08x)=%02x\n", addr, ret); + + return ret; +} + + +/* Memory-mapped I/O WRITE handler for the Trantor T130B. */ +static void +t130b_write(uint32_t addr, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + addr &= 0x3fff; + ncr53c400_log("MEM: Writing %02X to %08X\n", val, addr); + if (addr >= 0x1800 && addr < 0x1880) + ncr400->ext_ram[addr & 0x7f] = val; +} + +/* Memory-mapped I/O READ handler for the Trantor T130B. */ +static uint8_t +t130b_read(uint32_t addr, void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x3fff; + if (addr < 0x1800) + ret = ncr400->bios_rom.rom[addr & 0x1fff]; + else if (addr >= 0x1800 && addr < 0x1880) + ret = ncr400->ext_ram[addr & 0x7f]; + + ncr53c400_log("MEM: Reading %02X from %08X\n", ret, addr); + return ret; +} + +static void +t130b_out(uint16_t port, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + + ncr53c400_log("I/O: Writing %02X to %04X\n", val, port); + + switch (port & 0x0f) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + ncr53c400_write((port & 7) | 0x3980, val, ncr400); + break; + + case 0x04: + case 0x05: + ncr53c400_write(0x3900, val, ncr400); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ncr5380_write(port, val, ncr); + break; + + default: + break; + } +} + +static uint8_t +t130b_in(uint16_t port, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + uint8_t ret = 0xff; + + switch (port & 0x0f) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + ret = ncr53c400_read((port & 7) | 0x3980, ncr400); + break; + + case 0x04: + case 0x05: + ret = ncr53c400_read(0x3900, ncr400); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = ncr5380_read(port, ncr); + break; + + default: + break; + } + + ncr53c400_log("I/O: Reading %02X from %04X\n", ret, port); + return ret; +} + +static void +ncr53c400_dma_mode_ext(void *priv, void *ext_priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!ncr400->block_count_loaded && !(ncr->mode & MODE_DMA)) { + ncr53c400_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static void +ncr53c400_timer_on_auto(void *ext_priv, double period) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + + ncr53c400_log("53c400: PERIOD=%lf.\n", period); + if (period == 0.0) + timer_stop(&ncr400->timer); + else + timer_on_auto(&ncr400->timer, period); +} + +static void +ncr53c400_callback(void *priv) +{ + ncr53c400_t *ncr400 = (void *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int bus; + uint8_t c; + uint8_t temp; + + if (ncr->dma_mode != DMA_IDLE) + timer_on_auto(&ncr400->timer, 1.0); + + if (ncr->data_wait & 1) { + ncr->clear_req = 3; + ncr->data_wait &= ~1; + if (ncr->dma_mode == DMA_IDLE) { + timer_stop(&ncr400->timer); + return; + } + } + + if (ncr->dma_mode == DMA_IDLE) { + timer_stop(&ncr400->timer); + return; + } + + switch (ncr->dma_mode) { + case DMA_SEND: + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); + break; + } + + if (!(ncr400->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr53c400_log("Write buffer status ready\n"); + break; + } + + if (!ncr400->block_count_loaded) { + ncr53c400_log("Write block count not loaded.\n"); + break; + } + + while (1) { + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = ncr400->buffer[ncr400->buffer_pos]; + + bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + ncr400->buffer_pos++; + ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); + + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr400->buffer_pos = 0; + ncr400->buffer_host_pos = 0; + ncr400->busy = 0; + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { + ncr400->block_count_loaded = 0; + ncr53c400_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr400->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr53c400_log("NCR 53c400 write irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } + } + break; + + case DMA_INITIATOR_RECEIVE: + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); + break; + } + + if (!(ncr400->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr53c400_log("Read buffer status ready\n"); + break; + } + + if (!ncr400->block_count_loaded) + break; + + while (1) { + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr5380_bus_read(ncr); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = ncr5380_get_bus_host(ncr); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + ncr400->buffer[ncr400->buffer_pos++] = temp; + ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); + + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr400->buffer_pos = 0; + ncr400->buffer_host_pos = 0; + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { + ncr400->block_count_loaded = 0; + ncr53c400_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr400->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr53c400_log("NCR read irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } + } + break; + + default: + break; + } + + ncr5380_bus_read(ncr); + + if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + ncr53c400_log("Updating DMA\n"); + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static uint8_t +rt1000b_mc_read(int port, void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + return (ncr400->pos_regs[port & 7]); +} + +static void +rt1000b_mc_write(int port, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) + return; + + mem_mapping_disable(&ncr400->bios_rom.mapping); + mem_mapping_disable(&ncr400->mapping); + + /* Save the MCA register value. */ + ncr400->pos_regs[port & 7] = val; + + if (ncr400->pos_regs[2] & 1) { + switch (ncr400->pos_regs[2] & 0xe0) { + case 0: + ncr400->rom_addr = 0xd4000; + break; + case 0x20: + ncr400->rom_addr = 0xd0000; + break; + case 0x40: + ncr400->rom_addr = 0xcc000; + break; + case 0x60: + ncr400->rom_addr = 0xc8000; + break; + case 0xc0: + ncr400->rom_addr = 0xdc000; + break; + case 0xe0: + ncr400->rom_addr = 0xd8000; + break; + + default: + break; + } + + mem_mapping_set_addr(&ncr400->bios_rom.mapping, ncr400->rom_addr, 0x4000); + mem_mapping_set_addr(&ncr400->mapping, ncr400->rom_addr, 0x4000); + } +} + +static uint8_t +rt1000b_mc_feedb(void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + return ncr400->pos_regs[2] & 1; +} + +static void * +ncr53c400_init(const device_t *info) +{ + const char *bios_ver = NULL; + const char *fn; + ncr53c400_t *ncr400; + ncr_t *ncr; + + ncr400 = malloc(sizeof(ncr53c400_t)); + memset(ncr400, 0x00, sizeof(ncr53c400_t)); + ncr = &ncr400->ncr; + + ncr400->type = info->local; + + ncr->bus = scsi_get_bus(); + + switch (ncr400->type) { + case ROM_LCS6821N: /* Longshine LCS6821N */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + + rom_init(&ncr400->bios_rom, LCS6821N_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + break; + + + case ROM_LS2000: /* Corel LS2000 */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + + rom_init(&ncr400->bios_rom, COREL_LS2000_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + break; + + case ROM_RT1000B: /* Rancho RT1000B/MC */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + if (info->flags & DEVICE_MCA) { + rom_init(&ncr400->bios_rom, RT1000B_820R_ROM, + 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&ncr400->mapping, 0xd8000, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + mem_mapping_disable(&ncr400->bios_rom.mapping); + ncr400->pos_regs[0] = 0x8d; + ncr400->pos_regs[1] = 0x70; + mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr400); + } else { + bios_ver = (char *) device_get_config_bios("bios_ver"); + fn = (char *) device_get_bios_file(info, bios_ver, 0); + rom_init(&ncr400->bios_rom, fn, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + } + break; + + case ROM_T130B: /* Trantor T130B */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr400->base = device_get_config_hex16("base"); + ncr->irq = device_get_config_int("irq"); + + if (ncr400->rom_addr > 0x00000) { + rom_init(&ncr400->bios_rom, T130B_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + t130b_read, NULL, NULL, + t130b_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + } + + io_sethandler(ncr400->base, 16, + t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); + break; + + default: + break; + } + + ncr->priv = ncr400; + ncr->dma_mode_ext = ncr53c400_dma_mode_ext; + ncr->dma_send_ext = NULL; + ncr->dma_initiator_receive_ext = NULL; + ncr->timer = ncr53c400_timer_on_auto; + ncr400->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr400->buffer_host_pos = 128; + timer_add(&ncr400->timer, ncr53c400_callback, ncr400, 0); + + scsi_bus_set_speed(ncr->bus, 5000000.0); + + return ncr400; +} + +static void +ncr53c400_close(void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + if (ncr400) { + /* Tell the timer to terminate. */ + timer_stop(&ncr400->timer); + + free(ncr400); + ncr400 = NULL; + } +} + +static int +lcs6821n_available(void) +{ + return (rom_present(LCS6821N_ROM)); +} + +static int +rt1000b_mc_available(void) +{ + return (rom_present(RT1000B_820R_ROM)); +} + +static int +t130b_available(void) +{ + return (rom_present(T130B_ROM)); +} + +static int +corel_ls2000_available(void) +{ + return (rom_present(COREL_LS2000_ROM)); +} + +// clang-format off +static const device_config_t ncr53c400_mmio_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t rt1000b_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v8_10r", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 8.10R", .internal_name = "v8_10r", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { RT1000B_810R_ROM, "" } }, + { .name = "Version 8.20R", .internal_name = "v8_20r", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { RT1000B_820R_ROM, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t rt1000b_mc_config[] = { + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t t130b_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0350, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "240H", .value = 0x0240 }, + { .description = "250H", .value = 0x0250 }, + { .description = "340H", .value = 0x0340 }, + { .description = "350H", .value = 0x0350 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t scsi_lcs6821n_device = { + .name = "Longshine LCS-6821N", + .internal_name = "lcs6821n", + .flags = DEVICE_ISA, + .local = ROM_LCS6821N, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = lcs6821n_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ncr53c400_mmio_config +}; + +const device_t scsi_rt1000b_device = { + .name = "Rancho RT1000B", + .internal_name = "rt1000b", + .flags = DEVICE_ISA, + .local = ROM_RT1000B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rt1000b_config +}; + +const device_t scsi_rt1000mc_device = { + .name = "Rancho RT1000B-MC", + .internal_name = "rt1000mc", + .flags = DEVICE_MCA, + .local = ROM_RT1000B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = rt1000b_mc_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rt1000b_mc_config +}; + +const device_t scsi_t130b_device = { + .name = "Trantor T130B", + .internal_name = "t130b", + .flags = DEVICE_ISA, + .local = ROM_T130B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = t130b_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = t130b_config +}; + +const device_t scsi_ls2000_device = { + .name = "Corel LS2000", + .internal_name = "ls2000", + .flags = DEVICE_ISA, + .local = ROM_LS2000, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = corel_ls2000_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ncr53c400_mmio_config +}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c new file mode 100644 index 000000000..b13511eac --- /dev/null +++ b/src/scsi/scsi_t128.c @@ -0,0 +1,631 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Trantor 128/228 series of SCSI Host Adapters + * made by Trantor. These controllers were designed for the ISA and MCA bus. + * + * + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/pic.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/nvr.h> +#include <86box/plat.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/scsi_ncr5380.h> + +#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" + +typedef struct t128_t { + ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; + uint8_t buffer[512]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; + + uint32_t rom_addr; + + int bios_enabled; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} t128_t; + +#ifdef ENABLE_T128_LOG +int t128_do_log = ENABLE_T128_LOG; + +static void +t128_log(const char *fmt, ...) +{ + va_list ap; + + if (t128_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define t128_log(fmt, ...) +#endif + +/* Memory-mapped I/O WRITE handler. */ +static void +t128_write(uint32_t addr, uint8_t val, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + const scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + addr &= 0x3fff; + if ((addr >= 0x1800) && (addr < 0x1880)) + t128->ext_ram[addr & 0x7f] = val; + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { + if ((val & 0x02) && !(t128->ctrl & 0x02)) + t128->status |= 0x02; + + t128->ctrl = val; + t128_log("T128 ctrl write=%02x\n", val); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) + ncr5380_write((addr - 0x1d00) >> 5, val, ncr); + else if ((addr >= 0x1e00) && (addr < 0x2000)) { + if ((t128->host_pos < MIN(512, dev->buffer_length)) && + (ncr->dma_mode == DMA_SEND)) { + t128->buffer[t128->host_pos] = val; + t128->host_pos++; + + t128_log("T128 Write transfer, addr = %i, pos = %i, val = %02x\n", + addr & 0x1ff, t128->host_pos, val); + + if (t128->host_pos == MIN(512, dev->buffer_length)) { + t128->status &= ~0x04; + t128_log("Transfer busy write, status = %02x\n", t128->status); + timer_on_auto(&t128->timer, 0.02); + } + } + } +} + +/* Memory-mapped I/O READ handler. */ +static uint8_t +t128_read(uint32_t addr, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + addr &= 0x3fff; + if (t128->bios_enabled && (addr >= 0) && (addr < 0x1800)) + ret = t128->bios_rom.rom[addr & 0x1fff]; + else if ((addr >= 0x1800) && (addr < 0x1880)) + ret = t128->ext_ram[addr & 0x7f]; + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { + ret = t128->ctrl; + t128_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { + ret = t128->status; + t128_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) + ret = ncr5380_read((addr - 0x1d00) >> 5, ncr); + else if (addr >= 0x1e00 && addr < 0x2000) { + if ((t128->host_pos >= MIN(512, dev->buffer_length)) || + (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) + ret = 0xff; + else { + ret = t128->buffer[t128->host_pos++]; + + t128_log("T128 Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, + t128->host_pos); + + if (t128->host_pos == MIN(512, dev->buffer_length)) { + t128->status &= ~0x04; + t128_log("T128 Transfer busy read, status = %02x, period = %lf\n", + t128->status, ncr->period); + if ((ncr->period == 0.2) || (ncr->period == 0.02)) + timer_on_auto(&t128->timer, 40.2); + } else if ((t128->host_pos < MIN(512, dev->buffer_length)) && + (scsi_device_get_callback(dev) > 100.0)) + cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ + } + } + + return ret; +} + +static void +t128_dma_mode_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + + /*Don't stop the timer until it finishes the transfer*/ + if (t128->block_loaded && (ncr->mode & MODE_DMA)) { + t128_log("Continuing DMA mode\n"); + timer_on_auto(&t128->timer, ncr->period + 1.0); + } + + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!t128->block_loaded && !(ncr->mode & MODE_DMA)) { + t128_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static int +t128_dma_send_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { + memset(t128->buffer, 0, MIN(512, dev->buffer_length)); + t128->status |= 0x04; + t128->host_pos = 0; + t128->block_count = dev->buffer_length >> 9; + + if (dev->buffer_length < 512) + t128->block_count = 1; + + t128->block_loaded = 1; + } + return 1; +} + +static int +t128_dma_initiator_receive_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { + memset(t128->buffer, 0, MIN(512, dev->buffer_length)); + t128->status |= 0x04; + t128->host_pos = MIN(512, dev->buffer_length); + t128->block_count = dev->buffer_length >> 9; + + if (dev->buffer_length < 512) + t128->block_count = 1; + + t128->block_loaded = 1; + timer_on_auto(&t128->timer, 0.02); + } + return 1; +} + +static void +t128_timer_on_auto(void *ext_priv, double period) +{ + t128_t *t128 = (t128_t *) ext_priv; + + if (period == 0.0) + timer_stop(&t128->timer); + else + timer_on_auto(&t128->timer, period); +} + +static void +t128_callback(void *priv) +{ + t128_t *t128 = (void *) priv; + ncr_t *ncr = &t128->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int bus; + uint8_t c; + uint8_t temp; + + if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && t128->block_loaded) { + if ((t128->host_pos == MIN(512, dev->buffer_length)) && t128->block_count) + t128->status |= 0x04; + + timer_on_auto(&t128->timer, ncr->period / 55.0); + } + + if (ncr->data_wait & 1) { + ncr->clear_req = 3; + ncr->data_wait &= ~1; + if (ncr->dma_mode == DMA_IDLE) + return; + } + + switch (ncr->dma_mode) { + case DMA_SEND: + if (!(t128->status & 0x04)) { + t128_log("Write status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); + break; + } + + if (!t128->block_loaded) { + t128_log("Write block not loaded\n"); + break; + } + + if (t128->host_pos < MIN(512, dev->buffer_length)) + break; + +write_again: + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = t128->buffer[t128->pos]; + + bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + t128->pos++; + t128_log("T128 Buffer pos for writing = %d\n", t128->pos); + + if (t128->pos == MIN(512, dev->buffer_length)) { + t128->pos = 0; + t128->host_pos = 0; + t128->status &= ~0x02; + t128->block_count = (t128->block_count - 1) & 0xff; + t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count); + if (!t128->block_count) { + t128->block_loaded = 0; + t128_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&t128->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + t128_log("T128 write irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } else + goto write_again; + break; + + case DMA_INITIATOR_RECEIVE: + if (!(t128->status & 0x04)) { + t128_log("Read status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); + break; + } + + if (!t128->block_loaded) { + t128_log("Read block not loaded\n"); + break; + } + + if (t128->host_pos < MIN(512, dev->buffer_length)) + break; + +read_again: + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr5380_bus_read(ncr); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = ncr5380_get_bus_host(ncr); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + t128->buffer[t128->pos++] = temp; + t128_log("T128 Buffer pos for reading=%d, temp=%02x, len=%d.\n", t128->pos, temp, dev->buffer_length); + + if (t128->pos == MIN(512, dev->buffer_length)) { + t128->pos = 0; + t128->host_pos = 0; + t128->status &= ~0x02; + t128->block_count = (t128->block_count - 1) & 0xff; + t128_log("T128 Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", t128->block_count, t128->status, dev->buffer_length, ncr->command[0]); + if (!t128->block_count) { + t128->block_loaded = 0; + t128_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&t128->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + t128_log("NCR read irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } else + goto read_again; + break; + + default: + break; + } + + ncr5380_bus_read(ncr); + + if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + t128_log("Updating DMA\n"); + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + timer_on_auto(&t128->timer, 10.0); + } +} + +static uint8_t +t228_read(int port, void *priv) +{ + const t128_t *t128 = (t128_t *) priv; + + return (t128->pos_regs[port & 7]); +} + +static void +t228_write(int port, uint8_t val, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) + return; + + mem_mapping_disable(&t128->bios_rom.mapping); + mem_mapping_disable(&t128->mapping); + + /* Save the MCA register value. */ + t128->pos_regs[port & 7] = val; + + if (t128->pos_regs[2] & 1) { + switch (t128->pos_regs[2] & 6) { + case 0: + t128->rom_addr = 0xcc000; + break; + case 2: + t128->rom_addr = 0xc8000; + break; + case 4: + t128->rom_addr = 0xdc000; + break; + case 6: + t128->rom_addr = 0xd8000; + break; + + default: + break; + } + + t128->bios_enabled = !(t128->pos_regs[2] & 8); + + switch (t128->pos_regs[2] & 0x70) { + case 0: + ncr->irq = -1; + break; + case 0x10: + ncr->irq = 3; + break; + case 0x20: + ncr->irq = 5; + break; + case 0x30: + ncr->irq = 7; + break; + case 0x40: + ncr->irq = 10; + break; + case 0x50: + ncr->irq = 12; + break; + case 0x60: + ncr->irq = 14; + break; + case 0x70: + ncr->irq = 15; + break; + + default: + break; + } + + if (t128->bios_enabled) { + t128->status &= ~0x80; + mem_mapping_set_addr(&t128->bios_rom.mapping, t128->rom_addr, 0x4000); + mem_mapping_set_addr(&t128->mapping, t128->rom_addr, 0x4000); + } else + t128->status |= 0x80; + } +} + +static uint8_t +t228_feedb(void *priv) +{ + const t128_t *t128 = (t128_t *) priv; + + return t128->pos_regs[2] & 1; +} + +static void * +t128_init(const device_t *info) +{ + t128_t *t128; + ncr_t *ncr; + + t128 = malloc(sizeof(t128_t)); + memset(t128, 0x00, sizeof(t128_t)); + ncr = &t128->ncr; + + ncr->bus = scsi_get_bus(); + + if (info->flags & DEVICE_MCA) { + rom_init(&t128->bios_rom, T128_ROM, + 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&t128->mapping, 0xd8000, 0x4000, + t128_read, NULL, NULL, + t128_write, NULL, NULL, + t128->bios_rom.rom, MEM_MAPPING_EXTERNAL, t128); + mem_mapping_disable(&t128->bios_rom.mapping); + t128->pos_regs[0] = 0x8c; + t128->pos_regs[1] = 0x50; + mca_add(t228_read, t228_write, t228_feedb, NULL, t128); + } else { + ncr->irq = device_get_config_int("irq"); + t128->rom_addr = device_get_config_hex20("bios_addr"); + t128->bios_enabled = device_get_config_int("boot"); + if (t128->bios_enabled) + rom_init(&t128->bios_rom, T128_ROM, + t128->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&t128->mapping, t128->rom_addr, 0x4000, + t128_read, NULL, NULL, + t128_write, NULL, NULL, + t128->bios_rom.rom, MEM_MAPPING_EXTERNAL, t128); + } + + ncr->priv = t128; + ncr->dma_mode_ext = t128_dma_mode_ext; + ncr->dma_send_ext = t128_dma_send_ext; + ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; + ncr->timer = t128_timer_on_auto; + t128->status = 0x04; + t128->host_pos = 512; + if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) + t128->status |= 0x80; + + timer_add(&t128->timer, t128_callback, t128, 0); + + scsi_bus_set_speed(ncr->bus, 5000000.0); + + return t128; +} + +static void +t128_close(void *priv) +{ + t128_t *t128 = (t128_t *) priv; + + if (t128) { + /* Tell the timer to terminate. */ + timer_stop(&t128->timer); + + free(t128); + t128 = NULL; + } +} + +static int +t128_available(void) +{ + return (rom_present(T128_ROM)); +} + +// clang-format off +static const device_config_t t128_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "boot", + .description = "Enable Boot ROM", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t scsi_t128_device = { + .name = "Trantor T128", + .internal_name = "t128", + .flags = DEVICE_ISA, + .local = 0, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = t128_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = t128_config +}; + +const device_t scsi_t228_device = { + .name = "Trantor T228", + .internal_name = "t228", + .flags = DEVICE_MCA, + .local = 0, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = t128_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; From e5d1f3804923dbcfbba8485361da631f76fb6121 Mon Sep 17 00:00:00 2001 From: flama12333 <143599905+flama12333@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:42:55 -0500 Subject: [PATCH 417/690] fix Error initializing Hard disK Controller in Siemens Nixdorf D824 since this machine has an internal ide controller --- src/machine/m_at_386dx_486.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ea7e00ddc..b9f6b8cc8 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -400,7 +400,8 @@ machine_at_d824_init(const machine_t *model) device_add(&keyboard_ps2_device); device_add(&fdc37c651_device); - + device_add(&ide_isa_device); + return ret; } @@ -2293,4 +2294,4 @@ machine_at_atc1762_init(const machine_t *model) return ret; -} \ No newline at end of file +} From 5f846c348fa01304bf03a5fa4838af4940aea66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 11 Apr 2024 02:32:57 +0200 Subject: [PATCH 418/690] Update m_at_386dx_486.c Move IDE initialization before the Super I/O chip initialization. --- src/machine/m_at_386dx_486.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b9f6b8cc8..41fa3c946 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -399,8 +399,9 @@ machine_at_d824_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_device); - device_add(&fdc37c651_device); + device_add(&ide_isa_device); + device_add(&fdc37c651_device); return ret; } From 85c3eae1eeff53c83f85e2acdfd778d6028fab02 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:20:21 -0400 Subject: [PATCH 419/690] qt: Make sure voodoo is only enabled for pci machines --- src/qt/qt_settingsdisplay.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 631e3b966..6969a1c2c 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -148,10 +148,6 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) else ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0); bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; - ui->checkBoxVoodoo->setEnabled(machineHasPci); - if (machineHasPci) { - ui->checkBoxVoodoo->setChecked(voodoo_enabled); - } ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); bool machineHasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; @@ -225,7 +221,10 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) } ui->checkBoxVoodoo->setDisabled(true); } else { - ui->checkBoxVoodoo->setDisabled(false); + ui->checkBoxVoodoo->setEnabled(machineHasPci); + if (machineHasPci) { + ui->checkBoxVoodoo->setChecked(voodoo_enabled); + } } } From 2b15d7c0e63f842b0a6acd09cec2cb3a28b43666 Mon Sep 17 00:00:00 2001 From: flama12333 <143599905+flama12333@users.noreply.github.com> Date: Sat, 13 Apr 2024 00:46:21 -0500 Subject: [PATCH 420/690] Rename dtk 386 clone to DTK PM-1630C the motherboard is listed https://theretroweb.com/motherboards/s/dtk-pm-1630c user in vcfed uploaded bios post pictures https://forum.vcfed.org/index.php?threads/getting-a-dtk-peer-2030-computer-running.1238827/page-4 --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c2bb3925b..5020f3498 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4416,7 +4416,7 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[NEAT] DTK 386SX clone", + .name = "[NEAT] DTK PM-1630C", .internal_name = "dtk386", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_NEAT, From e4c8fef511a46a2c2c8d087caf7398087677f9dc Mon Sep 17 00:00:00 2001 From: The Dax Date: Tue, 16 Apr 2024 00:43:32 -0400 Subject: [PATCH 421/690] Fix missing machines on Linux: -pravetz16: capitalization of BIOS_IMKO4_FE00.BIN corrected to BIOS_IMKO4_FE00.bin -s76p: capitalization of s76p.rom corrected to S76P.ROM -dellplato: capitalization of 1016AX1J.bio and 1016AX1J.bi1 corrected to .BIO and .BI1 respectively -pb450: capitalization of OPTI802.BIN corrected to OPTI802.bin --- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/m_at_socket5.c | 4 ++-- src/machine/m_xt.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 41fa3c946..d4cd5fe16 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -687,7 +687,7 @@ machine_at_pb450_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pb450/OPTI802.BIN", + ret = bios_load_linear("roms/machines/pb450/OPTI802.bin", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1367,7 +1367,7 @@ machine_at_amis76_init(const machine_t *model) { int ret; - ret = bios_load_linear_inverted("roms/machines/s76p/s76p.rom", + ret = bios_load_linear_inverted("roms/machines/s76p/S76P.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 773f8d980..ff59ec65f 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -64,8 +64,8 @@ machine_at_dellplato_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined("roms/machines/dellplato/1016AX1J.bio", - "roms/machines/dellplato/1016AX1J.bi1", + ret = bios_load_linear_combined("roms/machines/dellplato/1016AX1J.BIO", + "roms/machines/dellplato/1016AX1J.BI1", 0x1d000, 128); if (bios_only || !ret) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 9a0b39a89..ded68f5dc 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -339,7 +339,7 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN", + ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin", 0x000fe000, 65536, 0); if (ret) { bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN", From 880abcb582ef11547b08b40e67e469a51f1ce91c Mon Sep 17 00:00:00 2001 From: The Dax Date: Tue, 16 Apr 2024 02:57:17 -0400 Subject: [PATCH 422/690] Fix capitalization of VideoMagic-BioS-HXIRTW32PWSRL.BIN to VideoMagic-BioS-HXIRTW32PWSRL.bin --- src/video/vid_et4000w32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 39b5b9ecc..2f086f3c7 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -42,7 +42,7 @@ #define BIOS_ROM_PATH_W32 "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" #define BIOS_ROM_PATH_W32I_ISA "roms/video/et4000w32/ET4KW32I.VBI" #define BIOS_ROM_PATH_W32I_VLB "roms/video/et4000w32/tseng.u41.bin" -#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.BIN" +#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.bin" #define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN" #define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN" From 22441a2302decc667870b5e4af0a68c00734af42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:18:50 +0200 Subject: [PATCH 423/690] Add sanity check to Voodoo 3/Banshee hardware cursor drawing Fixes #4351. --- src/video/vid_voodoo_banshee.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index a333062e1..bbd14a4a0 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -2109,10 +2109,12 @@ banshee_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 8) { if (x_off > -8) { for (xx = 0; xx < 8; xx++) { - if (!(plane0[x >> 3] & (1 << 7))) - (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - else if (plane1[x >> 3] & (1 << 7)) - (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + if (((x_off + xx + svga->x_add) >= 0) && ((x_off + xx + svga->x_add) <= 2047)) { + if (!(plane0[x >> 3] & (1 << 7))) + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + } plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; From b92995b0395cc31ce4fcedda465c2c0bfaa48106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:34:06 +0200 Subject: [PATCH 424/690] Sanity check on reading NEAT registers. --- src/chipset/neat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 3b00b4ffd..97c4b8f1a 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -646,7 +646,8 @@ neat_read(uint16_t port, void *priv) break; case 0x23: - ret = dev->regs[dev->indx]; + if ((dev->indx >= 0x60) && (dev->indx <= 0x6f)) + ret = dev->regs[dev->indx]; break; default: From 8756a70e38ea47816dd5e7a661a0ff3e34eb11e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:40:21 +0200 Subject: [PATCH 425/690] Sanity check on reading SCAT registers. --- src/chipset/scat.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/chipset/scat.c b/src/chipset/scat.c index aa0c5511a..fe6c033cf 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -66,15 +66,17 @@ typedef struct ems_page_t { } ems_page_t; typedef struct scat_t { - int type; + uint8_t max_reg; + uint8_t reg_2xA; - int indx; - uint8_t regs[256]; - uint8_t reg_2xA; + uint8_t regs[256]; uint32_t xms_bound; - int external_is_RAS; + int type; + int indx; + + int external_is_RAS; ems_page_t null_page; ems_page_t page[32]; @@ -1233,7 +1235,8 @@ scat_in(uint16_t port, void *priv) break; default: - ret = dev->regs[dev->indx]; + if (dev->index <= dev->max_reg) + ret = dev->regs[dev->indx]; break; } break; @@ -1393,6 +1396,8 @@ scat_init(const device_t *info) sx = (dev->type == 32) ? 1 : 0; + dev->max_reg = sx ? 0x64 : 0x4f; + for (uint32_t i = 0; i < sizeof(dev->regs); i++) dev->regs[i] = 0xff; From b2000913223e612b9fa99fa58b80e350572e516c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 21:49:24 +0200 Subject: [PATCH 426/690] Fixed a compile-breaking type in chipset/scat.c. --- src/chipset/scat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/scat.c b/src/chipset/scat.c index fe6c033cf..02610efa2 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -1235,7 +1235,7 @@ scat_in(uint16_t port, void *priv) break; default: - if (dev->index <= dev->max_reg) + if (dev->indx <= dev->max_reg) ret = dev->regs[dev->indx]; break; } From 9947af00d4d3c58fb797c497a55f02d82901e029 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:47:49 +0200 Subject: [PATCH 427/690] Fixed the FORMAT command on almost every emulated hard disk controller. --- src/disk/hdc_esdi_at.c | 37 ++++++++++++++++++++- src/disk/hdc_esdi_mca.c | 15 ++++----- src/disk/hdc_ide.c | 64 ++++++++++++++++++++++++++++++++++--- src/disk/hdc_st506_at.c | 35 ++++++++++++++++++-- src/disk/hdc_st506_xt.c | 33 ++++++++++++++++++- src/include/86box/hdc_ide.h | 2 ++ 6 files changed, 169 insertions(+), 17 deletions(-) diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 042a6020a..e16d4d729 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -214,6 +214,41 @@ get_sector(esdi_t *esdi, off64_t *addr) return 0; } +static int +get_sector_format(esdi_t *esdi, off64_t *addr) +{ + const drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + int c; + int h; + int s; + + if (esdi->head > heads) { + esdi_at_log("esdi_get_sector: past end of configured heads\n"); + return 1; + } + + if (drive->cfg_spt == drive->real_spt && drive->cfg_hpc == drive->real_hpc) { + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors); + } else { + /* + * When performing translation, the firmware seems to leave 1 + * sector per track inaccessible (spare sector) + */ + + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors); + + s = *addr % (drive->real_spt - 1); + h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; + c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; + + *addr = ((((off64_t) c * drive->real_hpc) + h) * drive->real_spt) + s; + } + + return 0; +} + /* Move to the next sector using CHS addressing. */ static void next_sector(esdi_t *esdi) @@ -655,7 +690,7 @@ esdi_callback(void *priv) irq_raise(esdi); break; } else { - if (get_sector(esdi, &addr)) { + if (get_sector_format(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 3714f93d4..c906c7ca1 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -831,14 +831,12 @@ esdi_callback(void *priv) switch (dev->cmd_state) { case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + dev->rba = hdd_image_get_last_sector(drive->hdd_num); - dev->sector_count = dev->cmd_data[1]; - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } + if (dev->command == CMD_FORMAT_UNIT) + dev->sector_count = dev->cmd_data[1]; + else + dev->sector_count = 0; dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; @@ -855,7 +853,8 @@ esdi_callback(void *priv) return; } - hdd_image_zero(drive->hdd_num, dev->rba, dev->sector_count); + if (dev->command == CMD_FORMAT_UNIT) + hdd_image_zero(drive->hdd_num, 0, hdd_image_get_last_sector(drive->hdd_num) + 1); dev->status = STATUS_CMD_IN_PROGRESS; dev->cmd_state = 2; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index a14f54e7d..428804b5a 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -738,6 +738,22 @@ ide_get_sector(ide_t *ide) } } +static off64_t +ide_get_sector_format(ide_t *ide) +{ + uint32_t heads; + uint32_t sectors; + + if (ide->tf->lba) + return (off64_t) ide->lba_addr; + else { + heads = ide->cfg_hpc; + sectors = ide->cfg_spt; + + return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->tf->head) * sectors); + } +} + /** * Move to the next sector using CHS addressing */ @@ -2147,8 +2163,9 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) atapi_error_no_ready(ide); else { - if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc) || - !ide->tf->sector || (ide->tf->sector > ide->spt))) + /* The J-Bond PCI400C-A Phoenix BIOS implies that this command is supposed to + ignore the sector number. */ + if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc))) err = IDNF_ERR; else { ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2434,7 +2451,7 @@ ide_callback(void *priv) else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->tf->secount); + hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount); ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2628,6 +2645,15 @@ ide_set_base_addr(int board, int base, uint16_t port) ide_boards[board]->base[base] = port; } +void +ide_set_irq(int board, int irq) +{ + ide_log("ide_set_irq(%i, %i)\n", board, irq); + + if (ide_boards[board] != NULL) + ide_boards[board]->irq = irq; +} + static void ide_clear_bus_master(int board) { @@ -2803,6 +2829,36 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type, int b ide_boards[board]->inited = 1; } +/* Needed for ESS ES1688/968 PnP. */ +void +ide_pnp_config_changed_1addr(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + intptr_t board = (intptr_t) priv; + + if (ld) + return; + + if (ide_boards[board]->base[0] || ide_boards[board]->base[1]) { + ide_remove_handlers(board); + ide_boards[board]->base[0] = ide_boards[board]->base[1] = 0; + } + + ide_boards[board]->irq = -1; + + if (config->activate) { + ide_boards[board]->base[0] = (config->io[0].base != ISAPNP_IO_DISABLED) ? + config->io[0].base : 0x0000; + ide_boards[board]->base[1] = (config->io[0].base != ISAPNP_IO_DISABLED) ? + (config->io[0].base + 0x0206) : 0x0000; + + if (ide_boards[board]->base[0] && ide_boards[board]->base[1]) + ide_set_handlers(board); + + if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) + ide_boards[board]->irq = config->irq[0].irq; + } +} + void ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -3526,5 +3582,5 @@ const device_t ide_qua_pnp_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = ide_qua_config + .config = NULL }; diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index c8c35d7d5..67bea6a8e 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -187,7 +187,7 @@ get_sector(mfm_t *mfm, off64_t *addr) return 1; } - if (mfm->sector >= drive->cfg_spt + 1) { + if (mfm->sector >= (drive->cfg_spt + 1)) { st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n", mfm->drvsel); return 1; @@ -199,7 +199,7 @@ get_sector(mfm_t *mfm, off64_t *addr) return 1; } - if (mfm->sector >= drive->spt + 1) { + if (mfm->sector >= (drive->spt + 1)) { st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); return 1; } @@ -209,6 +209,35 @@ get_sector(mfm_t *mfm, off64_t *addr) return 0; } +static int +get_sector_format(mfm_t *mfm, off64_t *addr) +{ + const drive_t *drive = &mfm->drives[mfm->drvsel]; + + /* FIXME: See if this is even needed - if the code is present, IBM AT + diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ + if (drive->curcyl != mfm->cylinder) { + st506_at_log("WD1003(%d) sector: wrong cylinder\n"); + return 1; + } + + if (mfm->head > drive->cfg_hpc) { + st506_at_log("WD1003(%d) get_sector: past end of configured heads\n", + mfm->drvsel); + return 1; + } + + /* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */ + if (mfm->head > drive->hpc) { + st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); + return 1; + } + + *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * drive->cfg_spt); + + return 0; +} + /* Move to the next sector using CHS addressing. */ static void next_sector(mfm_t *mfm) @@ -634,7 +663,7 @@ do_callback(void *priv) st506_at_log("WD1003(%d) format(%d,%d)\n", mfm->drvsel, mfm->cylinder, mfm->head); do_seek(mfm); - if (get_sector(mfm, &addr)) { + if (get_sector_format(mfm, &addr)) { mfm->error = ERR_ID_NOT_FOUND; mfm->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(mfm); diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index fc20350b0..f3ac48a36 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -457,6 +457,37 @@ get_chs(hdc_t *dev, drive_t *drive) return 1; } +static int +get_chs_format(hdc_t *dev, drive_t *drive) +{ + dev->err_bv = 0x80; + + dev->head = dev->command[1] & 0x1f; + /* 6 bits are used for the sector number even on the IBM PC controller. */ + dev->sector = 1; + dev->count = dev->command[4]; + if (((dev->type == ST506_XT_TYPE_ST11M) || (dev->type == ST506_XT_TYPE_ST11R)) && (dev->command[0] >= 0xf0)) + dev->cylinder = 0; + else { + dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); + dev->cylinder += dev->cyl_off; /* for ST-11 */ + } + + if (dev->cylinder >= drive->cfg_cyl) { + /* + * This really is an error, we cannot move + * past the end of the drive, which should + * result in an ERR_ILLEGAL_ADDR. --FvK + */ + drive->cylinder = drive->cfg_cyl - 1; + return 0; + } + + drive->cylinder = dev->cylinder; + + return 1; +} + static void st506_callback(void *priv) { @@ -628,7 +659,7 @@ st506_callback(void *priv) case CMD_FORMAT_BAD_TRACK: switch (dev->state) { case STATE_START_COMMAND: - (void) get_chs(dev, drive); + (void) get_chs_format(dev, drive); st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n", (dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "", dev->drive_sel, dev->cylinder, dev->head); diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 1f7a78c9f..4ee808d69 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -205,12 +205,14 @@ extern void win_cdrom_eject(uint8_t id); extern void win_cdrom_reload(uint8_t id); extern void ide_set_base_addr(int board, int base, uint16_t port); +extern void ide_set_irq(int board, int irq); extern void ide_handlers(uint8_t board, int set); extern void ide_board_set_force_ata3(int board, int force_ata3); #ifdef EMU_ISAPNP_H extern void ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); +extern void ide_pnp_config_changed_1addr(uint8_t ld, isapnp_device_config_t *config, void *priv); #endif extern double ide_atapi_get_period(uint8_t channel); From 75919a1cb97e425a8f0741eadb1416d30e051333 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:49:47 +0200 Subject: [PATCH 428/690] Fixed the SM(S)C) FDC37C93x NVR handling and make any non-PIIX4 machine that uses it, use its full NVR capabilities. --- src/include/86box/sio.h | 1 + src/machine/m_at_slot1.c | 3 +- src/machine/m_at_socket370.c | 28 ++++---- src/machine/m_at_socket7.c | 17 ++--- src/machine/m_at_socket7_3v.c | 10 +-- src/machine/m_at_socket8.c | 6 +- src/machine/machine_table.c | 18 ++--- src/nvr_at.c | 3 +- src/sio/sio_fdc37c93x.c | 129 ++++++++++++++++++++++++++++------ 9 files changed, 143 insertions(+), 72 deletions(-) diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 31d5d12ae..c7098cfdb 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,7 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37c935_no_nvr_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; extern const device_t it8661f_device; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index c199be2e9..d1486b579 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -143,8 +143,7 @@ machine_at_spitfire_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_no_nvr_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&lm78_device); /* no reporting in BIOS */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index dce0034ff..9e686ae8b 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -127,13 +127,13 @@ machine_at_p6bap_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ device_add(&w83977ef_device); @@ -162,13 +162,13 @@ machine_at_p6bat_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 6ba7cb41d..7bbf49edf 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -73,9 +73,7 @@ machine_at_acerv35n_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c932fr_device); - device_add(&sst_flash_29ee010_device); return ret; @@ -155,7 +153,7 @@ machine_at_m7shi_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); @@ -166,7 +164,6 @@ machine_at_m7shi_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); @@ -574,7 +571,6 @@ machine_at_presario2240_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932qf_device); device_add(&sst_flash_29ee020_device); @@ -605,7 +601,6 @@ machine_at_presario4500_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c931apm_compaq_device); device_add(&sst_flash_29ee020_device); @@ -623,7 +618,7 @@ machine_at_p55va_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -634,7 +629,6 @@ machine_at_p55va_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_device); @@ -652,7 +646,7 @@ machine_at_brio80xx_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); @@ -663,7 +657,6 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee020_device); @@ -719,7 +712,7 @@ machine_at_pb810_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -733,7 +726,6 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); @@ -1469,7 +1461,6 @@ machine_at_thunderbolt_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 0, 1, 2); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index fdf155894..bd66c9a66 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -534,7 +534,7 @@ machine_at_acerm3a_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -546,7 +546,6 @@ machine_at_acerm3a_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); @@ -686,7 +685,7 @@ machine_at_dellhannibalp_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -698,7 +697,6 @@ machine_at_dellhannibalp_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_ami_device); @@ -720,7 +718,7 @@ machine_at_gw2kte_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -732,7 +730,6 @@ machine_at_gw2kte_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_ami_device); @@ -850,7 +847,6 @@ machine_at_vectra54_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&s3_phoenix_trio64_onboard_pci_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c931apm_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e1dad68e7..e8262a6f4 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -175,7 +175,7 @@ machine_at_acerv60n_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model,2 ); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -187,7 +187,6 @@ machine_at_acerv60n_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); @@ -366,7 +365,7 @@ machine_at_m6mi_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -377,7 +376,6 @@ machine_at_m6mi_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5020f3498..f7d46cec9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10513,7 +10513,7 @@ const machine_t machines[] = { .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10678,7 +10678,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10760,7 +10760,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10967,7 +10967,7 @@ const machine_t machines[] = { .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11616,7 +11616,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11656,7 +11656,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11738,7 +11738,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -13217,7 +13217,7 @@ const machine_t machines[] = { .max = 524288, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -13541,7 +13541,7 @@ const machine_t machines[] = { .max = 786432, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, diff --git a/src/nvr_at.c b/src/nvr_at.c index 4ddec729f..9465839a7 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -309,7 +309,6 @@ typedef struct local_t { uint8_t irq_state; uint8_t smi_status; - uint8_t addr[8]; uint8_t wp[2]; uint8_t bank[8]; uint8_t *lock; @@ -317,6 +316,8 @@ typedef struct local_t { int16_t count; int16_t state; + uint16_t addr[8]; + int32_t smi_enable; uint64_t ecount; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 4acbfeff5..7d8e12795 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -31,6 +31,7 @@ #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/keyboard.h> #include <86box/nvr.h> #include <86box/apm.h> #include <86box/acpi.h> @@ -51,11 +52,13 @@ typedef struct access_bus_t { typedef struct fdc37c93x_t { uint8_t chip_id; uint8_t is_apm; + uint8_t has_nvr; uint8_t tries; uint8_t gpio_regs[2]; uint8_t auxio_reg; uint8_t regs[48]; uint8_t ld_regs[11][256]; + uint16_t superio_base; uint16_t gpio_base; /* Set to EA */ uint16_t auxio_base; uint16_t nvr_sec_base; @@ -66,8 +69,23 @@ typedef struct fdc37c93x_t { access_bus_t *access_bus; nvr_t *nvr; acpi_t *acpi; + void *kbc; } fdc37c93x_t; +static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv); +static uint8_t fdc37c93x_read(uint16_t port, void *priv); + +static uint16_t +make_port_superio(fdc37c93x_t *dev) +{ + uint16_t r0 = dev->regs[0x26]; + uint16_t r1 = dev->regs[0x27]; + + uint16_t p = (r1 << 8) + r0; + + return p; +} + static uint16_t make_port(fdc37c93x_t *dev, uint8_t ld) { @@ -126,6 +144,16 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); } +static void +fdc37c93x_superio_handler(fdc37c93x_t *dev) +{ + io_removehandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); + dev->superio_base = make_port_superio(dev); + io_sethandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); +} + static void fdc37c93x_fdc_handler(fdc37c93x_t *dev) { @@ -180,7 +208,9 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, int uart) static void fdc37c93x_nvr_pri_handler(fdc37c93x_t *dev) { - uint8_t local_enable = !!dev->ld_regs[6][0x30]; + uint8_t local_enable = !!dev->ld_regs[6][0x30]; + + local_enable &= ((dev->ld_regs[6][0xf0] & 0x90) != 0x80); nvr_at_handler(0, 0x70, dev->nvr); if (local_enable) @@ -193,6 +223,9 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) uint16_t ld_port = 0; uint8_t local_enable = !!dev->ld_regs[6][0x30]; + local_enable &= (((dev->ld_regs[6][0xf0] & 0xe0) == 0x80) || + ((dev->ld_regs[6][0xf0] & 0xe0) == 0xe0)); + nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr); if (local_enable) { dev->nvr_sec_base = ld_port = make_port_sec(dev, 6) & 0xFFFE; @@ -203,6 +236,14 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) } } +static void +fdc37c93x_kbc_handler(fdc37c93x_t *dev) +{ + uint8_t local_enable = !!dev->ld_regs[7][0x30]; + + kbc_at_handler(local_enable, dev->kbc); +} + static void fdc37c93x_auxio_handler(fdc37c93x_t *dev) { @@ -401,10 +442,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) switch (dev->regs[7]) { case 0x01: case 0x02: - case 0x07: return; case 0x06: - if (dev->chip_id != 0x30) + if (!dev->has_nvr) return; /* Bits 0 to 3 of logical device 6 (RTC) register F0h must stay set once they are set. */ @@ -453,6 +493,10 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) fdc37c93x_access_bus_handler(dev); break; + case 0x27: + fdc37c93x_superio_handler(dev); + break; + default: break; } @@ -566,12 +610,15 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) break; case 6: /* RTC/NVR */ - if (dev->chip_id != 0x30) - break; + if (!dev->has_nvr) + return; switch (dev->cur_reg) { case 0x30: - if (valxor) + if (valxor) { fdc37c93x_nvr_pri_handler(dev); + fdc37c93x_nvr_sec_handler(dev); + } + break; case 0x62: case 0x63: if (valxor) @@ -617,6 +664,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); } + + fdc37c93x_nvr_pri_handler(dev); + fdc37c93x_nvr_sec_handler(dev); } break; @@ -624,6 +674,18 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) break; } break; + case 7: + /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + if (valxor) + fdc37c93x_kbc_handler(dev); + break; + + default: + break; + } + break; case 8: /* Auxiliary I/O */ switch (dev->cur_reg) { @@ -730,7 +792,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) memset(dev->ld_regs[i], 0, 256); /* Logical device 0: FDD */ - dev->ld_regs[0][0x30] = 1; + dev->ld_regs[0][0x30] = 0; dev->ld_regs[0][0x60] = 3; dev->ld_regs[0][0x61] = 0xF0; dev->ld_regs[0][0x70] = 6; @@ -756,7 +818,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[2][0x70] = 0xF; /* Logical device 3: Parallel Port */ - dev->ld_regs[3][0x30] = 1; + dev->ld_regs[3][0x30] = 0; dev->ld_regs[3][0x60] = 3; dev->ld_regs[3][0x61] = 0x78; dev->ld_regs[3][0x70] = 7; @@ -764,7 +826,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[3][0xF0] = 0x3C; /* Logical device 4: Serial Port 1 */ - dev->ld_regs[4][0x30] = 1; + dev->ld_regs[4][0x30] = 0; dev->ld_regs[4][0x60] = 3; dev->ld_regs[4][0x61] = 0xf8; dev->ld_regs[4][0x70] = 4; @@ -772,7 +834,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) serial_setup(dev->uart[0], COM1_ADDR, dev->ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ - dev->ld_regs[5][0x30] = 1; + dev->ld_regs[5][0x30] = 0; dev->ld_regs[5][0x60] = 2; dev->ld_regs[5][0x61] = 0xf8; dev->ld_regs[5][0x70] = 3; @@ -782,12 +844,13 @@ fdc37c93x_reset(fdc37c93x_t *dev) serial_setup(dev->uart[1], COM2_ADDR, dev->ld_regs[5][0x70]); /* Logical device 6: RTC */ - dev->ld_regs[6][0x30] = 1; - dev->ld_regs[6][0x63] = (dev->chip_id == 0x30) ? 0x70 : 0x00; + dev->ld_regs[6][0x30] = 0; + dev->ld_regs[6][0x63] = (dev->has_nvr) ? 0x70 : 0x00; + dev->ld_regs[6][0xF0] = 0; dev->ld_regs[6][0xF4] = 3; /* Logical device 7: Keyboard */ - dev->ld_regs[7][0x30] = 1; + dev->ld_regs[7][0x30] = 0; dev->ld_regs[7][0x61] = 0x60; dev->ld_regs[7][0x70] = 1; @@ -810,13 +873,22 @@ fdc37c93x_reset(fdc37c93x_t *dev) fdc_reset(dev->fdc); fdc37c93x_fdc_handler(dev); - if (dev->chip_id == 0x30) { + if (dev->has_nvr) { fdc37c93x_nvr_pri_handler(dev); fdc37c93x_nvr_sec_handler(dev); nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); + + nvr_lock_set(0x80, 0x20, 0, dev->nvr); + nvr_lock_set(0xa0, 0x20, 0, dev->nvr); + nvr_lock_set(0xc0, 0x20, 0, dev->nvr); + nvr_lock_set(0xe0, 0x20, 0, dev->nvr); } + fdc37c93x_kbc_handler(dev); + + fdc37c93x_superio_handler(dev); + dev->locked = 0; } @@ -874,6 +946,7 @@ fdc37c93x_init(const device_t *info) dev->chip_id = info->local & 0xff; dev->is_apm = (info->local >> 8) & 0x01; is_compaq = (info->local >> 8) & 0x02; + dev->has_nvr = !((info->local >> 8) & 0x04); dev->gpio_regs[0] = 0xff; #if 0 @@ -881,7 +954,7 @@ fdc37c93x_init(const device_t *info) #endif dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; - if (dev->chip_id == 0x30) { + if (dev->has_nvr) { dev->nvr = device_add(&at_nvr_device); nvr_bank_set(0, 0, dev->nvr); @@ -901,20 +974,17 @@ fdc37c93x_init(const device_t *info) fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0fb, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); - } else { - io_sethandler(FDC_SECONDARY_ADDR, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); - io_sethandler(FDC_PRIMARY_ADDR, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); } + dev->kbc = device_add(&keyboard_ps2_ami_pci_device); + fdc37c93x_reset(dev); return dev; } const device_t fdc37c931apm_device = { - .name = "SMC FDC37C932QF Super I/O", + .name = "SMC FDC37C931APM Super I/O", .internal_name = "fdc37c931apm", .flags = 0, .local = 0x130, /* Share the same ID with the 932QF. */ @@ -928,7 +998,7 @@ const device_t fdc37c931apm_device = { }; const device_t fdc37c931apm_compaq_device = { - .name = "SMC FDC37C932QF Super I/O (Compaq Presario 4500)", + .name = "SMC FDC37C931APM Super I/O (Compaq Presario 4500)", .internal_name = "fdc37c931apm_compaq", .flags = 0, .local = 0x330, /* Share the same ID with the 932QF. */ @@ -982,3 +1052,18 @@ const device_t fdc37c935_device = { .force_redraw = NULL, .config = NULL }; + +const device_t fdc37c935_no_nvr_device = { + .name = "SMC FDC37C935 Super I/O", + .internal_name = "fdc37c935", + .flags = 0, + .local = 0x402, + .init = fdc37c93x_init, + .close = fdc37c93x_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + From fed171ff4d93dd3f8df15e70b8a6e8c9479f0350 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:50:48 +0200 Subject: [PATCH 429/690] IBM PS/1 Model 2121 FDC fix. --- src/floppy/fdc.c | 16 +++++++++++++++- src/include/86box/fdc.h | 3 +++ src/machine/m_ps1.c | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 491df2f47..1a0aa2f10 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -780,7 +780,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (!(fdc->flags & FDC_FLAG_PS1)) { + if (!(fdc->flags & FDC_FLAG_NO_DSR_RESET)) { if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); fdc->interrupt = -6; @@ -2608,6 +2608,20 @@ const device_t fdc_at_ps1_device = { .config = NULL }; +const device_t fdc_at_ps1_2121_device = { + .name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", + .internal_name = "fdc_at_ps1", + .flags = 0, + .local = FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc_at_smc_device = { .name = "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)", .internal_name = "fdc_at_smc", diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 00de511f3..9529fde5c 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -55,6 +55,8 @@ extern int fdc_type; #define FDC_FLAG_SEC 0x1000 /* Is Secondary */ #define FDC_FLAG_TER 0x2000 /* Is Tertiary */ #define FDC_FLAG_QUA 0x3000 /* Is Quaternary */ +#define FDC_FLAG_CHANNEL 0x3000 /* Channel mask */ +#define FDC_FLAG_NO_DSR_RESET 0x4000 /* Has no DSR reset */ typedef struct fdc_t { uint8_t dor; @@ -251,6 +253,7 @@ extern const device_t fdc_at_ter_device; extern const device_t fdc_at_qua_device; extern const device_t fdc_at_actlow_device; extern const device_t fdc_at_ps1_device; +extern const device_t fdc_at_ps1_2121_device; extern const device_t fdc_at_smc_device; extern const device_t fdc_at_ali_device; extern const device_t fdc_at_winbond_device; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index e0a15126e..34691773f 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -378,7 +378,7 @@ ps1_setup(int model) if (gfxcard[0] == VID_INTERNAL) device_add(&ibm_ps1_2121_device); - device_add(&fdc_at_ps1_device); + device_add(&fdc_at_ps1_2121_device); device_add(&ide_isa_device); From d98751e40faf3ae9121aa722fc41b0457f000b6e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:51:56 +0200 Subject: [PATCH 430/690] Added the ability to enable/disable the KBC (used by the FDC37C93x Super I/O chips). --- src/device/kbc_at.c | 15 +++++++++++++-- src/include/86box/keyboard.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index bc4a1f366..d8b308d6b 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1986,6 +1986,18 @@ kbc_at_close(void *priv) free(dev); } +void +kbc_at_handler(int set, void *priv) +{ + io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + + if (set) { + io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + } +} + static void * kbc_at_init(const device_t *info) { @@ -2003,8 +2015,7 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; - io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); - io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); + kbc_at_handler(1, dev); timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); timer_add(&dev->pulse_cb, pulse_poll, dev, 0); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 759fad714..0d8b2e745 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -276,6 +276,7 @@ extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); +extern void kbc_at_handler(int set, void *priv); extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); From 8e0da9ef211fce049d50b3c142231245feec40d4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:52:41 +0200 Subject: [PATCH 431/690] ISA PNP ROM parsing fixes (fixed DMA flags and added support for fixed-sized 10-bit I/O address). --- src/device/isapnp.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index f9d10b380..da9e623c1 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -737,7 +737,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]); const char *df_priority[] = { "good", "acceptable", "sub-optimal", "unknown priority" }; const char *mem_control[] = { "8-bit", "16-bit", "8/16-bit", "32-bit" }; - const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "unknown" }; + const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "Reserved" }; const char *dma_speed[] = { "compatibility", "Type A", "Type B", "Type F" }; #endif uint16_t i = 9; @@ -937,9 +937,9 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) case 0x05: /* DMA */ isapnp_log("ISAPnP: >>%s DMA index %d with mask %02X, %s, %sbus master, %scount by byte, %scount by word, %s speed\n", in_df ? ">" : "", dma++, card->rom[i + 1], dma_transfer[card->rom[i + 2] & 3], - (card->rom[i + 2] & 0x04) ? "not " : "", - (card->rom[i + 2] & 0x08) ? "not " : "", - (card->rom[i + 2] & 0x10) ? "not " : "", + (card->rom[i + 2] & 0x04) ? "" : "not ", + (card->rom[i + 2] & 0x08) ? "" : "not ", + (card->rom[i + 2] & 0x10) ? "" : "not ", dma_speed[(card->rom[i + 2] >> 5) & 3]); break; #endif @@ -1004,6 +1004,29 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; + case 0x09: /* Fixed I/O port */ + if (!ld) { + isapnp_log("ISAPnP: >>%s Fixed I/O descriptor with no logical device\n", in_df ? ">" : ""); + break; + } + + if (io > 7) { + isapnp_log("ISAPnP: >>%s Fixed I/O descriptor overflow (%d)\n", in_df ? ">" : "", io++); + break; + } + + isapnp_log("ISAPnP: >>%s Fixed I/O range %d with %d ports at %04X\n", in_df ? ">" : "", io, card->rom[i + 3], *((uint16_t *) &card->rom[i + 1])); + + /* Fixed I/O port ranges of this kind are always 10-bit. */ + ld->io_16bit &= ~(1 << io); + + if (card->rom[i + 3] > ld->io_len[io]) + ld->io_len[io] = card->rom[i + 3]; + + io++; + + break; + case 0x0f: /* end tag */ /* Calculate checksum. */ res = 0x00; From a2b3c4c8dc78c733cb534eb48b1c4d1d02338a28 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:54:12 +0200 Subject: [PATCH 432/690] ALi M1543(C) IDE fixes, fixes Windows 95 IDE driver. --- src/chipset/ali1543.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index fe3a0fda3..6f080b15b 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -197,6 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0xdf; soft_reset_pci = !!(val & 0x80); + pci_set_mirq_level(PCI_MIRQ0, !(val & 0x10)); pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10)); ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); @@ -417,6 +418,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0x1f; + pci_set_mirq_level(PCI_MIRQ1, !(val & 0x10)); pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10)); ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); @@ -704,7 +706,7 @@ ali5229_chip_reset(ali1543_t *dev) ali5229_write(0, 0x09, 0xfa, dev); ali5229_write(0, 0x52, 0x00, dev); - ali5229_write(0, 0x50, 0x00, dev); + ali5229_write(0, 0x50, 0x02, dev); sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); @@ -717,7 +719,7 @@ static void ali5229_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; - ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val); + ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val); if (func > 0) return; @@ -756,6 +758,10 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) ali5229_ide_irq_handler(dev); break; + case 0x0d: /* LT - Latency Timer */ + dev->ide_conf[addr] = val; + break; + /* Primary Base Address */ case 0x10: case 0x11: @@ -887,13 +893,15 @@ ali5229_read(int func, int addr, void *priv) if (dev->ide_dev_enable && (func == 0)) { ret = dev->ide_conf[addr]; if ((addr == 0x09) && !(dev->ide_conf[0x50] & 0x02)) - ret &= 0x0f; + ret = (ret & 0x0f) | 0x80; else if (addr == 0x50) ret = (ret & 0xfe) | (dev->ide_dev_enable ? 0x01 : 0x00); else if (addr == 0x75) ret = ide_read_ali_75(); else if (addr == 0x76) ret = ide_read_ali_76(); + + ali1543_log("M5229: [R] dev->ide_conf[%02x] = %02x\n", addr, ret); } return ret; From 1e5800d5487e8ed980fd6a845593191cbe472c29 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:54:42 +0200 Subject: [PATCH 433/690] Intel 420TX-430TX cache control fixes. --- src/chipset/intel_4x0.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a1f923e49..f2fa7aac2 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -493,16 +493,41 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x52: /* Cache Control Register */ switch (dev->type) { default: + /* + 420TX/ZX: + Bit 7-6: 0, 0 = 64 kB, + 0, 1 = 128 kB, + 1, 0 = 256 kB, + 1, 1 = 512 kB. + Bit 5: 1 = L2 cache present, 0 = L2 cache absent. + Bit 1: 1 = Write back cache, 0 = write through cache. + Bit 0: 1 = L2 cache enable, 0 = L2 cache disable. + */ case INTEL_420TX: case INTEL_420ZX: + case INTEL_430NX: + pclog("52 = %02X\n", val); + regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f); + cpu_cache_ext_enabled = val & 0x01; + cpu_update_waitstates(); + break; case INTEL_430LX: + regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1b); + cpu_cache_ext_enabled = val & 0x01; + cpu_update_waitstates(); + break; case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - regs[0x52] = (val & 0xfb); + regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0b); + cpu_cache_ext_enabled = ((val & 0x03) == 0x01); + cpu_update_waitstates(); break; - case INTEL_430NX: case INTEL_430HX: + regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0f); + cpu_cache_ext_enabled = ((val & 0x03) == 0x01); + cpu_update_waitstates(); + break; case INTEL_440FX: regs[0x52] = val; break; @@ -1630,7 +1655,7 @@ i4x0_init(const device_t *info) 0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB, If bit 0 is set, then if bit 2 is also set, the cache is write back, otherwise it's write through. */ - regs[0x52] = 0xc3; /* 512 kB writeback cache */ + regs[0x52] = 0xe0; /* 512 kB writeback cache */ regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02; From ae834c1a2df50a87ca19b48e1f7f8b86af515dd3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:21:01 +0200 Subject: [PATCH 434/690] AT MFM/RLL: The SET DRIVE PARAMETERS and RESTORE commands no longer finish instantly, fixes MFM/RLL drives on the Arche AMA-2010. --- src/disk/hdc_st506_at.c | 86 +++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 67bea6a8e..d5bbf24d0 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -277,13 +277,9 @@ mfm_cmd(mfm_t *mfm, uint8_t val) switch (val & 0xf0) { case CMD_RESTORE: drive->steprate = (val & 0x0f); - st506_at_log("WD1003(%d) restore, step=%d\n", - mfm->drvsel, drive->steprate); - drive->curcyl = 0; - mfm->cylinder = 0; - mfm->status = STAT_READY | STAT_DSC; mfm->command &= 0xf0; - irq_raise(mfm); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; case CMD_SEEK: @@ -340,38 +336,8 @@ mfm_cmd(mfm_t *mfm, uint8_t val) break; case CMD_SET_PARAMETERS: - /* - * NOTE: - * - * We currently just set these parameters, and - * never bother to check if they "fit within" - * the actual parameters, as determined by the - * image loader. - * - * The difference in parameters is OK, and - * occurs when the BIOS or operating system - * decides to use a different translation - * scheme, but either way, it SHOULD always - * fit within the actual parameters! - * - * We SHOULD check that here!! --FvK - */ - if (drive->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head + 1; - st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } else { - st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } - mfm->command = 0x00; - mfm->status = STAT_READY | STAT_DSC; - mfm->error = 1; - irq_raise(mfm); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; default: @@ -596,6 +562,15 @@ do_callback(void *priv) } switch (mfm->command) { + case CMD_RESTORE: + st506_at_log("WD1003(%d) restore, step=%d\n", + mfm->drvsel, drive->steprate); + drive->curcyl = 0; + mfm->cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + break; + case CMD_SEEK: st506_at_log("WD1003(%d) seek, step=%d\n", mfm->drvsel, drive->steprate); @@ -691,6 +666,41 @@ do_callback(void *priv) irq_raise(mfm); break; + case CMD_SET_PARAMETERS: + /* + * NOTE: + * + * We currently just set these parameters, and + * never bother to check if they "fit within" + * the actual parameters, as determined by the + * image loader. + * + * The difference in parameters is OK, and + * occurs when the BIOS or operating system + * decides to use a different translation + * scheme, but either way, it SHOULD always + * fit within the actual parameters! + * + * We SHOULD check that here!! --FvK + */ + if (drive->cfg_spt == 0) { + /* Only accept after RESET or DIAG. */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head + 1; + st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } else { + st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } + mfm->command = 0x00; + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + irq_raise(mfm); + break; + default: st506_at_log("WD1003(%d) callback on unknown command %02x\n", mfm->drvsel, mfm->command); From c74f168c29d84c6f090a223bce4e39e4d4170d84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:28:08 +0200 Subject: [PATCH 435/690] The AMA-932J now indicates it is an Arche machine and correctly uses the Acer/ALi M5105 Super I/O chip. --- src/machine/m_at_286_386sx.c | 4 +++- src/machine/machine_table.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 53df7f628..b2470bae2 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -70,7 +70,7 @@ machine_at_headland_common_init(int type) { device_add(&keyboard_at_ami_device); - if (fdc_type == FDC_INTERNAL) + if ((type != 2) && (fdc_type == FDC_INTERNAL)) device_add(&fdc_at_device); if (type == 2) @@ -117,6 +117,8 @@ machine_at_ama932j_init(const machine_t *model) machine_at_headland_common_init(2); + device_add(&ali5105_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f7d46cec9..3aafe237c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4253,7 +4253,7 @@ const machine_t machines[] = { for me to read what's on the KBC chip, so I'm going to assume AMI 'F' based on the other known HT18 AMI BIOS strings. */ { - .name = "[HT18] AMA-932J", + .name = "[HT18] Arche AMA-932J", .internal_name = "ama932j", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_HT18, From 955297b9c44e01364ec20efaef145c43770d944d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:33:20 +0200 Subject: [PATCH 436/690] Removed excess logging from the Intel 4x0 chipset emulation. --- src/chipset/intel_4x0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index f2fa7aac2..8abbe50c1 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -506,7 +506,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_420TX: case INTEL_420ZX: case INTEL_430NX: - pclog("52 = %02X\n", val); regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f); cpu_cache_ext_enabled = val & 0x01; cpu_update_waitstates(); From 373fe0f258a726bf616961a47e3b2e76da031aa0 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sun, 24 Mar 2024 12:07:58 -0400 Subject: [PATCH 437/690] qt: Disable bus channels that are currently in use --- src/qt/qt_harddiskdialog.cpp | 2 +- src/qt/qt_harddrive_common.cpp | 24 +++++++++++++++++- src/qt/qt_harddrive_common.hpp | 3 ++- src/qt/qt_settings.cpp | 4 +++ src/qt/qt_settings_bus_tracking.cpp | 39 +++++++++++++++++++++++++++++ src/qt/qt_settings_bus_tracking.hpp | 2 ++ src/qt/qt_settingsfloppycdrom.cpp | 22 +++++++++++++++- src/qt/qt_settingsfloppycdrom.hpp | 4 +++ src/qt/qt_settingsharddisks.cpp | 26 ++++++++++++++++++- src/qt/qt_settingsharddisks.hpp | 5 ++++ 10 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 5efd895dc..df10a6d38 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -746,7 +746,7 @@ HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) ui->lineEditHeads->setValidator(new QIntValidator(1, max_heads, this)); ui->lineEditSectors->setValidator(new QIntValidator(1, max_sectors, this)); - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); switch (ui->comboBoxBus->currentData().toInt()) { diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index dda36917f..213ebf07b 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -24,6 +24,7 @@ extern "C" { } #include +#include void Harddrives::populateBuses(QAbstractItemModel *model) @@ -96,7 +97,7 @@ Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) } void -Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) +Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt) { model->removeRows(0, model->rowCount()); @@ -104,6 +105,8 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) int shifter = 1; int orer = 1; int subChannelWidth = 1; + QList busesToCheck; + QList channelsInUse; switch (bus) { case HDD_BUS_MFM: case HDD_BUS_XTA: @@ -111,15 +114,29 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) busRows = 2; break; case HDD_BUS_IDE: + busRows = 8; + busesToCheck.append(HDD_BUS_ATAPI); + busesToCheck.append(HDD_BUS_IDE); + break; case HDD_BUS_ATAPI: busRows = 8; + busesToCheck.append(HDD_BUS_IDE); + busesToCheck.append(HDD_BUS_ATAPI); break; case HDD_BUS_SCSI: shifter = 4; orer = 15; busRows = 64; subChannelWidth = 2; + busesToCheck.append(HDD_BUS_SCSI); break; + default: + break; + } + if(sbt != nullptr && !busesToCheck.empty()) { + for (auto const &checkBus : busesToCheck) { + channelsInUse.append(sbt->busChannelsInUse(checkBus)); + } } model->insertRows(0, busRows); @@ -127,6 +144,11 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) auto idx = model->index(i, 0); model->setData(idx, QString("%1:%2").arg(i >> shifter).arg(i & orer, subChannelWidth, 10, QChar('0'))); model->setData(idx, ((i >> shifter) << shifter) | (i & orer), Qt::UserRole); + const auto *channelModel = qobject_cast(model); + auto *channelItem = channelModel->item(i); + if(channelItem) { + channelItem->setEnabled(!channelsInUse.contains(i)); + } } } diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp index 2aca184b3..28189f328 100644 --- a/src/qt/qt_harddrive_common.hpp +++ b/src/qt/qt_harddrive_common.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "qt_settings_bus_tracking.hpp" class QString; class QAbstractItemModel; @@ -9,7 +10,7 @@ class SettingsBusTracking; namespace Harddrives { void populateBuses(QAbstractItemModel *model); void populateRemovableBuses(QAbstractItemModel *model); -void populateBusChannels(QAbstractItemModel *model, int bus); +void populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt = nullptr); void populateSpeeds(QAbstractItemModel *model, int bus); QString BusChannelName(uint8_t bus, uint8_t channel); inline SettingsBusTracking *busTrackClass = nullptr; diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index c7cb99086..a7e52c342 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -153,6 +153,10 @@ Settings::Settings(QWidget *parent) &SettingsStorageControllers::onCurrentMachineChanged); connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 4fe112627..064fbe0b4 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -198,6 +198,45 @@ SettingsBusTracking::scsi_bus_full() return (count == 64); } +QList SettingsBusTracking::busChannelsInUse(const int bus) { + + QList channelsInUse; + int element; + uint64_t mask; + switch (bus) { + case HDD_BUS_IDE: + for (uint8_t i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = ((uint64_t) DEV_HDD) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) { + channelsInUse.append(i); + } + } + break; + case HDD_BUS_ATAPI: + for (uint8_t i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = ((uint64_t) DEV_CDROM) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) { + channelsInUse.append(i); + } + } + break; + case HDD_BUS_SCSI: + for (uint8_t i = 0; i < 64; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (scsi_tracking[element] & mask) + channelsInUse.append(i); + } + break; + default: + break; + } + + return channelsInUse; +} + void SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel) { diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 3ec61dfb7..279d3247e 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -28,6 +28,8 @@ public: explicit SettingsBusTracking(); ~SettingsBusTracking() = default; + QList busChannelsInUse(int bus); + /* These return 0xff is none is free. */ uint8_t next_free_mfm_channel(); uint8_t next_free_esdi_channel(); diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 988f9e856..bb536e603 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -263,6 +263,7 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); ui->comboBoxCDROMType->setCurrentIndex(type); + enableCurrentlySelectedChannel(); } void @@ -288,6 +289,13 @@ SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) ui->tableViewFloppy->selectionModel()->currentIndex(), index); } +void SettingsFloppyCDROM::reloadBusChannels() { + auto selected = ui->comboBoxChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel(); +} + void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { @@ -298,7 +306,7 @@ SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus, Harddrives::busTrackClass); } } @@ -362,6 +370,17 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) ui->comboBoxCDROMType->currentData().toUInt()); } +void +SettingsFloppyCDROM::enableCurrentlySelectedChannel() +{ + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if(item) { + item->setEnabled(true); + } +} + void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { @@ -376,6 +395,7 @@ SettingsFloppyCDROM::on_comboBoxChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + emit cdromChannelChanged(); } void diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 3d6dd0e45..0a3424216 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -13,9 +13,12 @@ class SettingsFloppyCDROM : public QWidget { public: explicit SettingsFloppyCDROM(QWidget *parent = nullptr); ~SettingsFloppyCDROM(); + void reloadBusChannels(); void save(); +signals: + void cdromChannelChanged(); private slots: void on_comboBoxCDROMType_activated(int index); void on_comboBoxChannel_activated(int index); @@ -30,6 +33,7 @@ private slots: private: Ui::SettingsFloppyCDROM *ui; + void enableCurrentlySelectedChannel(); }; #endif // QT_SETTINGSFLOPPYCDROM_HPP diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index a66203406..3f02ffe54 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -166,6 +166,13 @@ SettingsHarddisks::save() } } +void SettingsHarddisks::reloadBusChannels() { + const auto selected = ui->comboBoxChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel(); +} + void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { @@ -184,7 +191,7 @@ SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBusPrevious); } - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); int chanIdx = 0; @@ -233,6 +240,18 @@ SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); Harddrives::busTrackClass->device_track(1, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toUInt()); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannelPrevious); + emit driveChannelChanged(); + } +} + +void +SettingsHarddisks::enableCurrentlySelectedChannel() +{ + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if(item) { + item->setEnabled(true); } } @@ -283,6 +302,7 @@ SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) { ui->comboBoxSpeed->setCurrentIndex(match.first().row()); } + reloadBusChannels(); } static void @@ -317,6 +337,7 @@ SettingsHarddisks::on_pushButtonNew_clicked() switch (dialog.exec()) { case QDialog::Accepted: addDriveFromDialog(ui, dialog); + reloadBusChannels(); break; } } @@ -328,6 +349,7 @@ SettingsHarddisks::on_pushButtonExisting_clicked() switch (dialog.exec()) { case QDialog::Accepted: addDriveFromDialog(ui, dialog); + reloadBusChannels(); break; } } @@ -341,6 +363,8 @@ SettingsHarddisks::on_pushButtonRemove_clicked() } auto *model = ui->tableView->model(); + const auto col = idx.siblingAtColumn(ColumnBus); + Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toInt()); model->removeRow(idx.row()); ui->pushButtonNew->setEnabled(true); ui->pushButtonExisting->setEnabled(true); diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp index 68d7ca3d6..4bd287d29 100644 --- a/src/qt/qt_settingsharddisks.hpp +++ b/src/qt/qt_settingsharddisks.hpp @@ -13,9 +13,13 @@ class SettingsHarddisks : public QWidget { public: explicit SettingsHarddisks(QWidget *parent = nullptr); ~SettingsHarddisks(); + void reloadBusChannels(); void save(); +signals: + void driveChannelChanged(); + private slots: void on_comboBoxChannel_currentIndexChanged(int index); void on_comboBoxSpeed_currentIndexChanged(int index); @@ -30,6 +34,7 @@ private slots: private: Ui::SettingsHarddisks *ui; + void enableCurrentlySelectedChannel(); bool buschangeinprogress = false; }; From 0a1888feec1f82ae82658e4f9bd40b419b9687f0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 18 Apr 2024 20:39:05 +0200 Subject: [PATCH 438/690] the DEC 21143-based NIC expects a SROM Format version of 3 This fixes detection under various operating systems, including NT-based ones. --- src/network/net_tulip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index ffc342e81..e34327eb5 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1530,6 +1530,9 @@ nic_init(const device_t *info) s->eeprom_data[40] = 0x00; s->eeprom_data[41] = 0x00; } else { + /*SROM Format Version 3*/ + s->eeprom_data[18] = 0x03; + /*Block Count*/ s->eeprom_data[32] = 0x01; @@ -1677,7 +1680,7 @@ static const device_config_t dec_tulip_21140_config[] = { // clang-format on const device_t dec_tulip_device = { - .name = "DE500A Fast Ethernet (DECchip 21143 \"Tulip\")", + .name = "DEC DE-500A Fast Ethernet (DECchip 21143 \"Tulip\")", .internal_name = "dec_21143_tulip", .flags = DEVICE_PCI, .local = 0, From 50ca61dfd45b301d1e98003c76ea832154752fda Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 20 Apr 2024 23:43:27 +0200 Subject: [PATCH 439/690] ATI/IBM mode changes in the Mach8/32. Reworked the way the mode changes work in said chips (and way less hacky than before). --- src/video/vid_ati_mach8.c | 138 ++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 71 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 2613de767..522df00a6 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2599,12 +2599,25 @@ mach_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; + dev->v_total = dev->v_total_reg + 1; + dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; + mach_log("VDISP=%d.\n", dev->vdisp); + if ((dev->hdisp == 800) || (dev->hdisp == 1280)) { + /*For VESA modes in ATI 8514/A mode.*/ + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + /*Default modes for 8514/A mode*/ + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = 1024; + dev->dispend = 768; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } if (dev->dispend == 766) dev->dispend += 2; @@ -2709,13 +2722,6 @@ mach_recalctimings(svga_t *svga) svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - - if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ - if (!(mach->accel.clock_sel & 0x01)) { - dev->h_disp = 640; - dev->dispend = 480; - } - } } if (dev->interlace) { @@ -3620,84 +3626,63 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x2e8: case 0x2e9: WRITE8(port, dev->htotal, val); + dev->htotal &= 0x1ff; break; case 0x6e8: - case 0x6e9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; - if ((dev->hdisp == 640) && ((mach->shadow_set & 0x03) == 0x02) && (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) - svga_recalctimings(svga); - else if ((dev->hdisp == 1024) && !(mach->accel.clock_sel & 0x01) && ((dev->disp_cntl & 0x60) == 0x40)) { - if (dev->accel.advfunc_cntl & 0x04) { - dev->hdisp = 1024; - dev->vdisp = 768; - } else { - dev->hdisp = 640; - dev->vdisp = 480; - } - svga_recalctimings(svga); - } - } - } + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hdisped = val; + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); + mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); + break; + case 0x6e9: + dev->hdisped = (dev->hdisp >> 3) - 1; + dev->v_disp = (dev->vdisp - 1) << 1; + mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); break; case 0xae8: - case 0xae9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - } - } + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07); mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; case 0xee8: - case 0xee9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - } - } + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_total_reg, val); dev->v_total_reg &= 0x1fff; - dev->vtotal = dev->v_total_reg; - dev->vtotal++; } break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; } dev->modechange = dev->accel.advfunc_cntl & 0x04; mach->compat_mode = mach->shadow_set & 0x03; - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); + mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); break; case 0x1ae8: case 0x1ae9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_sync_start, val); dev->v_sync_start &= 0x1fff; - dev->vsyncstart = dev->v_sync_start; - dev->vsyncstart++; } break; @@ -3709,7 +3694,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x22e8: dev->disp_cntl = val; dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); + mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); break; case 0x42e8: @@ -3747,7 +3732,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4, dev->hdisp); + dev->hdisp = (dev->hdisped + 1) << 3; + dev->vdisp = (dev->v_disp >> 1) + 1; + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; @@ -3825,7 +3813,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 else dev->ext_crt_pitch <<= 1; } - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); svga_recalctimings(svga); break; @@ -3864,39 +3852,46 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x46ee: case 0x46ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->shadow_cntl, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); break; case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); dev->on[port & 1] = mach->accel.clock_sel & 0x01; - mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]); + mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp); + mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); mach->ext_on[port & 1] = dev->on[port & 1]; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 1; + dev->hdisp = (dev->hdisped + 1) << 3; + dev->vdisp = (dev->v_disp >> 1) + 1; svga_recalctimings(svga); break; case 0x52ee: case 0x52ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); WRITE8(port, mach->accel.scratch0, val); break; case 0x56ee: case 0x56ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); WRITE8(port, mach->accel.scratch1, val); break; case 0x5aee: case 0x5aef: - if (!(mach->shadow_cntl & 0x3f)) { - WRITE8(port, mach->shadow_set, val); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - } + WRITE8(port, mach->shadow_set, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + if ((mach->shadow_set & 0x03) == 0x00) + mach_log("Primary CRT register set.\n"); + else if ((mach->shadow_set & 0x03) == 0x01) + mach_log("Shadow Set 1: 640x480.\n"); + else if ((mach->shadow_set & 0x03) == 0x02) + mach_log("Shadow Set 2: 1024x768.\n"); break; case 0x5eee: @@ -3938,7 +3933,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x76ef: WRITE8(port, mach->accel.ge_pitch, val); dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach_log("ATI 8514/A: (0x%04x) val = %04x, extpitch = %d.\n", port, val, dev->ext_pitch); + mach_log("ATI 8514/A: (0x%04x) val=%04x, extpitch=%d.\n", port, val, dev->ext_pitch); svga_recalctimings(svga); break; @@ -3971,7 +3966,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); dev->vendor_mode[port & 1] = 1; mach32_updatemapping(mach, svga); - mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); svga_recalctimings(svga); } else { if (mach->accel.ext_ge_config & 0x8080) @@ -4285,6 +4280,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in temp = dev->hdisped & 0xff; temp |= (dev->htotal << 8); } + mach_log("B2EE read=%02x.\n", temp & 0xff); break; case 0xb2ef: if (len == 1) @@ -4301,15 +4297,15 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xc2ee: if (len == 1) - temp = dev->vtotal & 0xff; + temp = dev->v_total_reg & 0xff; else { - temp = dev->vtotal; + temp = dev->v_total_reg; mach_log("VTOTAL read=%d.\n", temp); } break; case 0xc2ef: if (len == 1) - temp = dev->vtotal >> 8; + temp = dev->v_total_reg >> 8; break; case 0xc6ee: From 10fd8fb0041bd3703e4aba5763fe40389236fb18 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 22 Apr 2024 02:04:57 +0200 Subject: [PATCH 440/690] Assorted CD-ROM fixes, fixes #4386. --- src/cdrom/cdrom.c | 3 +- src/cdrom/cdrom_image_backend.c | 145 ++++++++++-------------- src/include/86box/cdrom_image_backend.h | 4 +- src/scsi/scsi_cdrom.c | 2 +- 4 files changed, 67 insertions(+), 87 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ea025de2a..e4e76ea66 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1524,8 +1524,9 @@ static void read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len) { uint8_t *bb = rbuf; + const int offset = (!!(mode2 & 0x03)) ? 24 : 16; - dev->ops->read_sector(dev, CD_READ_DATA, rbuf + 16, lba); + dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba); /* Sync bytes */ bb[0] = 0; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 1bc0fcf2d..482769799 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -70,12 +70,12 @@ cdrom_image_backend_log(const char *fmt, ...) static int bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) { - track_file_t *tf = (track_file_t *) priv; + track_file_t *tf; cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n", tf->fp, seek, count); - if (tf->fp == NULL) + if ((tf = (track_file_t *) priv)->fp == NULL) return 0; if (fseeko64(tf->fp, seek, SEEK_SET) == -1) { @@ -98,16 +98,15 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) static uint64_t bin_get_length(void *priv) { - off64_t len; - track_file_t *tf = (track_file_t *) priv; + track_file_t *tf; cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp); - if (tf->fp == NULL) + if ((tf = (track_file_t *) priv)->fp == NULL) return 0; fseeko64(tf->fp, 0, SEEK_END); - len = ftello64(tf->fp); + const off64_t len = ftello64(tf->fp); cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len); return len; @@ -248,26 +247,20 @@ cdi_set_device(cd_img_t *cdi, const char *path) return 0; } -/* TODO: This never returns anything other than 1, should it even be an int? */ -int +void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out) { *st_track = 1; *end = cdi->tracks_num - 1; FRAMES_TO_MSF(cdi->tracks[*end].start + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); - - return 1; } -/* TODO: This never returns anything other than 1, should it even be an int? */ -int +void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out) { *st_track = 1; *end = cdi->tracks_num - 1; *lead_out = cdi->tracks[*end].start; - - return 1; } int @@ -286,12 +279,11 @@ int cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { const track_t *trk = &cdi->tracks[track - 1]; - int pos = trk->start + 150; if ((track < 1) || (track > cdi->tracks_num)) return 0; - pos = trk->start + 150; + const int pos = trk->start + 150; FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); @@ -320,9 +312,6 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *tra int cdi_get_track(cd_img_t *cdi, uint32_t sector) { - const track_t *cur; - const track_t *next; - /* There must be at least two tracks - data and lead out. */ if (cdi->tracks_num < 2) return -1; @@ -330,8 +319,8 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) /* This has a problem - the code skips the last track, which is lead out - is that correct? */ for (int i = 0; i < (cdi->tracks_num - 1); i++) { - cur = &cdi->tracks[i]; - next = &cdi->tracks[i + 1]; + const track_t *cur = &cdi->tracks[i]; + const track_t *next = &cdi->tracks[i + 1]; /* Take into account cue sheets that do not start on sector 0. */ if ((i == 0) && (sector < cur->start)) @@ -348,16 +337,15 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - int cur_track = cdi_get_track(cdi, sector); - const track_t *trk; + const int cur_track = cdi_get_track(cdi, sector); if (cur_track < 1) return 0; - *track = (uint8_t) cur_track; - trk = &cdi->tracks[*track - 1]; - *attr = trk->attr; - *index = 1; + *track = (uint8_t) cur_track; + const track_t *trk = &cdi->tracks[*track - 1]; + *attr = trk->attr; + *index = 1; FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); @@ -370,16 +358,11 @@ cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) { - size_t length; - int track = cdi_get_track(cdi, sector) - 1; - uint64_t sect = (uint64_t) sector; - uint64_t seek; - track_t *trk; - int track_is_raw; - int ret; + const int track = cdi_get_track(cdi, sector) - 1; + const uint64_t sect = (uint64_t) sector; int raw_size; int cooked_size; - uint64_t offset = 0ULL; + uint64_t offset; int m = 0; int s = 0; int f = 0; @@ -387,10 +370,10 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) if (track < 0) return 0; - trk = &cdi->tracks[track]; - track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); + const track_t *trk = &cdi->tracks[track]; + const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); - seek = trk->skip + ((sect - trk->start) * trk->sector_size); + const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; @@ -405,7 +388,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) } else cooked_size = COOKED_SECTOR_SIZE; - length = (raw ? raw_size : cooked_size); + const size_t length = (raw ? raw_size : cooked_size); if (trk->mode2 && (trk->form >= 1)) offset = 24ULL; @@ -414,7 +397,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) if (raw && !track_is_raw) { memset(buffer, 0x00, 2448); - ret = trk->file->read(trk->file, buffer + offset, seek, length); + const int ret = trk->file->read(trk->file, buffer + offset, seek, length); if (!ret) return 0; /* Construct the rest of the raw sector. */ @@ -430,24 +413,20 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) return 1; } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); - else { + else return trk->file->read(trk->file, buffer, seek, length); - } } int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num) { - int sector_size; int success = 1; - uint8_t *buf; - uint32_t buf_len; /* TODO: This fails to account for Mode 2. Shouldn't we have a function to get sector size? */ - sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - buf_len = num * sector_size; - buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t)); + const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + const uint32_t buf_len = num * sector_size; + uint8_t *buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t)); for (uint32_t i = 0; i < num; i++) { success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i); @@ -455,7 +434,9 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3 break; /* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an audio track. */ - if (raw && sector < cdi->tracks[0].length && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[i * sector_size + 2068])) + if (raw && (sector < cdi->tracks[0].length) && + !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && + *(uint64_t *) &(buf[(i * sector_size) + 2068])) return 0; } @@ -470,16 +451,13 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3 int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - track_t *trk; - uint64_t s = (uint64_t) sector; - uint64_t seek; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; - seek = trk->skip + ((s - trk->start) * trk->sector_size); + const track_t *trk = &cdi->tracks[track]; + const uint64_t seek = trk->skip + (((uint64_t) sector - trk->start) * trk->sector_size); if (trk->sector_size != 2448) return 0; @@ -489,26 +467,24 @@ cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return trk->sector_size; } int cdi_is_mode2(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return !!(trk->mode2); } @@ -516,13 +492,12 @@ cdi_is_mode2(cd_img_t *cdi, uint32_t sector) int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return trk->form; } @@ -533,10 +508,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form) uint8_t pvd[COOKED_SECTOR_SIZE]; uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */ - if ((!mode2 || (form == 0)) && (sector_size == RAW_SECTOR_SIZE)) - seek += 16; - if (mode2 && (form >= 1)) - seek += 24; + if (sector_size == RAW_SECTOR_SIZE) { + if (!mode2 || (form == 0)) + seek += 16; + else + seek += 24; + } file->read(file, pvd, seek, COOKED_SECTOR_SIZE); @@ -591,7 +568,7 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) /* Try to detect ISO type. */ trk.form = 0; trk.mode2 = 0; - /* TODO: Merge the first and last cases since they result in the same thing. */ + if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0)) trk.sector_size = RAW_SECTOR_SIZE; else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) { @@ -601,9 +578,17 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) trk.sector_size = 2324; trk.mode2 = 1; trk.form = 2; + } else if (cdi_can_read_pvd(trk.file, 2328, 1, 2)) { + trk.sector_size = 2328; + trk.mode2 = 1; + trk.form = 2; } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) { trk.sector_size = RAW_SECTOR_SIZE; trk.mode2 = 1; + } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 1)) { + trk.sector_size = RAW_SECTOR_SIZE; + trk.mode2 = 1; + trk.form = 1; } else { /* We use 2048 mode 1 as the default. */ trk.sector_size = COOKED_SECTOR_SIZE; @@ -754,17 +739,12 @@ static int cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap) { /* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */ - uint64_t skip; - uint64_t temp; track_t *prev = NULL; /* Skip *MUST* be calculated even if prestart is 0. */ - if (prestart >= 0) { - if (prestart > cur->start) - return 0; - skip = cur->start - prestart; - } else - skip = 0ULL; + if (prestart > cur->start) + return 0; + const uint64_t skip = cur->start - prestart; if ((cdi->tracks != NULL) && (cdi->tracks_num != 0)) prev = &cdi->tracks[cdi->tracks_num - 1]; @@ -793,7 +773,7 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u *total_pregap += cur_pregap; cur->start += *total_pregap; } else { - temp = prev->file->get_length(prev->file) - (prev->skip); + const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip); prev->length = temp / ((uint64_t) prev->sector_size); if ((temp % prev->sector_size) != 0) prev->length++; @@ -823,8 +803,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) { track_t trk; char pathname[MAX_FILENAME_LENGTH]; - char filename[MAX_FILENAME_LENGTH]; - char temp[MAX_FILENAME_LENGTH]; uint64_t shift = 0ULL; uint64_t prestart = 0ULL; uint64_t cur_pregap = 0ULL; @@ -836,7 +814,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) int can_add_track = 0; FILE *fp; char buf[MAX_LINE_LENGTH]; - char ansi[MAX_FILENAME_LENGTH]; char *line; char *command; char *type; @@ -877,7 +854,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) } } - success = cdi_cue_get_keyword(&command, &line); + (void) cdi_cue_get_keyword(&command, &line); if (!strcmp(command, "TRACK")) { if (can_add_track) @@ -980,6 +957,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) break; } } else if (!strcmp(command, "FILE")) { + char filename[MAX_FILENAME_LENGTH]; + char ansi[MAX_FILENAME_LENGTH]; + if (can_add_track) success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap); else @@ -1002,7 +982,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) error = 1; if (!strcmp(type, "BINARY")) { - memset(temp, 0, MAX_FILENAME_LENGTH * sizeof(char)); path_append_filename(filename, pathname, ansi); trk.file = track_file_init(filename, &error); } diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index 39faf9f33..5222e8aa0 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -78,8 +78,8 @@ typedef struct cd_img_t { /* Binary file functions. */ extern void cdi_close(cd_img_t *cdi); extern int cdi_set_device(cd_img_t *cdi, const char *path); -extern int cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); -extern int cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); +extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); +extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr); extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr); diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 3a49085ec..8a9f72946 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1393,7 +1393,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch, int ven type = (dev->current_cdb[1] >> 2) & 7; flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); } else { - type = 8; + type = 8; /* Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. */ flags = 0x10; } From 3dbb0daa1742ea7c5bbe52f82a574af595285d2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 03:14:12 +0200 Subject: [PATCH 441/690] AD1848 clean-ups and fixed DMA over a 16-bit channel. --- src/sound/snd_ad1848.c | 226 ++++++++++++++++++++++++----------------- 1 file changed, 133 insertions(+), 93 deletions(-) diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index d2a05fd6f..4b7941959 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -63,46 +63,85 @@ ad1848_updatevolmask(ad1848_t *ad1848) ad1848->wave_vol_mask = 0x7f; } +static double +ad1848_get_default_freq(ad1848_t *ad1848) +{ + double freq = (ad1848->regs[8] & 1) ? 16934400.0 : 24576000.0; + + switch ((ad1848->regs[8] >> 1) & 7) { + default: + break; + + case 0: + freq /= 3072.0; + break; + case 1: + freq /= 1536.0; + break; + case 2: + freq /= 896.0; + break; + case 3: + freq /= 768.0; + break; + case 4: + freq /= 448.0; + break; + case 5: + freq /= 384.0; + break; + case 6: + freq /= 512.0; + break; + case 7: + freq /= 2560.0; + break; + } + + return freq; +} + static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq = 0.0; - uint8_t set = 0; + double freq; if (ad1848->type >= AD1848_TYPE_CS4235) { if (ad1848->xregs[11] & 0x20) { - freq = 16934400LL; + freq = 16934400.0; switch (ad1848->xregs[13]) { + default: + freq /= 16.0 * MAX(ad1848->xregs[13], 21); + break; case 1: - freq /= 353; + freq /= 353.0; break; case 2: - freq /= 529; + freq /= 529.0; break; case 3: - freq /= 617; + freq /= 617.0; break; case 4: - freq /= 1058; + freq /= 1058.0; break; case 5: - freq /= 1764; + freq /= 1764.0; break; case 6: - freq /= 2117; + freq /= 2117.0; break; case 7: - freq /= 2558; - break; - default: - freq /= 16 * MAX(ad1848->xregs[13], 21); + freq /= 2558.0; break; } - set = 1; } else if (ad1848->regs[22] & 0x80) { - freq = (ad1848->regs[22] & 1) ? 33868800LL : 49152000LL; - set = (ad1848->regs[22] >> 1) & 0x3f; + const uint8_t set = (ad1848->regs[22] >> 1) & 0x3f; + freq = (ad1848->regs[22] & 1) ? 33868800.0 : 49152000.0; switch (ad1848->regs[10] & 0x30) { + default: + break; + case 0x00: freq /= 128 * set; break; @@ -112,48 +151,13 @@ ad1848_updatefreq(ad1848_t *ad1848) case 0x20: freq /= 256 * set; break; - - default: - break; } - set = 1; - } - } + } else + freq = ad1848_get_default_freq(ad1848); + } else + freq = ad1848_get_default_freq(ad1848); - if (!set) { - freq = (ad1848->regs[8] & 1) ? 16934400LL : 24576000LL; - switch ((ad1848->regs[8] >> 1) & 7) { - case 0: - freq /= 3072; - break; - case 1: - freq /= 1536; - break; - case 2: - freq /= 896; - break; - case 3: - freq /= 768; - break; - case 4: - freq /= 448; - break; - case 5: - freq /= 384; - break; - case 6: - freq /= 512; - break; - case 7: - freq /= 2560; - break; - - default: - break; - } - } - - ad1848->freq = freq; + ad1848->freq = (int) trunc(freq); ad1848->timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ad1848->freq)); } @@ -251,6 +255,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 9: if (!ad1848->enable && (val & 0x41) == 0x01) { ad1848->adpcm_pos = 0; + ad1848->dma_ff = 0; if (ad1848->timer_latch) timer_set_delay_u64(&ad1848->timer_count, ad1848->timer_latch); else @@ -450,18 +455,32 @@ static int16_t ad1848_process_mulaw(uint8_t byte) { byte = ~byte; - int16_t dec = ((byte & 0x0f) << 3) + 0x84; - dec <<= (byte & 0x70) >> 4; - return (byte & 0x80) ? (0x84 - dec) : (dec - 0x84); + int temp = (((byte & 0x0f) << 3) + 0x84); + int16_t dec; + temp <<= ((byte & 0x70) >> 4); + temp = (byte & 0x80) ? (0x84 - temp) : (temp - 0x84); + if (temp > 32767) + dec = 32767; + else if (temp < -32768) + dec = -32768; + else + dec = (int16_t) temp; + + return dec; } static int16_t ad1848_process_alaw(uint8_t byte) { byte ^= 0x55; - int16_t dec = (byte & 0x0f) << 4; - int seg = (byte & 0x70) >> 4; + int dec = ((byte & 0x0f) << 4);; + const int seg = (int) ((byte & 0x70) >> 4); switch (seg) { + default: + dec |= 0x108; + dec <<= seg - 1; + break; + case 0: dec |= 0x8; break; @@ -469,13 +488,34 @@ ad1848_process_alaw(uint8_t byte) case 1: dec |= 0x108; break; - - default: - dec |= 0x108; - dec <<= seg - 1; - break; } - return (byte & 0x80) ? dec : -dec; + dec = (byte & 0x80) ? dec : -dec; + return (int16_t) dec; +} + +static uint32_t +ad1848_dma_channel_read(ad1848_t *ad1848, int channel) +{ + uint32_t ret; + + if (channel >= 4) { + if (ad1848->dma_ff) { + ret = (ad1848->dma_data & 0xff00) >> 8; + ret |= (ad1848->dma_data & 0xffff0000); + } else { + ad1848->dma_data = dma_channel_read(channel); + + if (ad1848->dma_data == DMA_NODATA) + return DMA_NODATA; + + ret = ad1848->dma_data & 0xff; + } + + ad1848->dma_ff = !ad1848->dma_ff; + } else + ret = dma_channel_read(channel); + + return ret; } static int16_t @@ -485,7 +525,7 @@ ad1848_process_adpcm(ad1848_t *ad1848) if (ad1848->adpcm_pos++ & 1) { temp = (ad1848->adpcm_data & 0x0f) + ad1848->adpcm_step; } else { - ad1848->adpcm_data = dma_channel_read(ad1848->dma); + ad1848->adpcm_data = (int) (ad1848_dma_channel_read(ad1848, ad1848->dma) & 0xffff); temp = (ad1848->adpcm_data >> 4) + ad1848->adpcm_step; } if (temp < 0) @@ -499,9 +539,9 @@ ad1848_process_adpcm(ad1848_t *ad1848) else if (ad1848->adpcm_ref < 0x00) ad1848->adpcm_ref = 0x00; - ad1848->adpcm_step = (ad1848->adpcm_step + adjustMap4[temp]) & 0xff; + ad1848->adpcm_step = (int8_t) ((ad1848->adpcm_step + adjustMap4[temp]) & 0xff); - return (ad1848->adpcm_ref ^ 0x80) << 8; + return (int16_t) ((ad1848->adpcm_ref ^ 0x80) << 8); } static void @@ -521,42 +561,42 @@ ad1848_poll(void *priv) switch (ad1848->regs[8] & ad1848->fmt_mask) { case 0x00: /* Mono, 8-bit PCM */ - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; + ad1848->out_l = ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); break; case 0x10: /* Stereo, 8-bit PCM */ - ad1848->out_l = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; - ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; + ad1848->out_l = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); + ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); break; case 0x20: /* Mono, 8-bit Mu-Law */ - ad1848->out_l = ad1848->out_r = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848->out_r = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x30: /* Stereo, 8-bit Mu-Law */ - ad1848->out_l = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); - ad1848->out_r = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); + ad1848->out_r = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x40: /* Mono, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); break; case 0x50: /* Stereo, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = (dma_channel_read(ad1848->dma) << 8) | temp; - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); break; case 0x60: /* Mono, 8-bit A-Law */ - ad1848->out_l = ad1848->out_r = ad1848_process_alaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848->out_r = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x70: /* Stereo, 8-bit A-Law */ - ad1848->out_l = ad1848_process_alaw(dma_channel_read(ad1848->dma)); - ad1848->out_r = ad1848_process_alaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); + ad1848->out_r = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; /* 0x80 and 0x90 reserved */ @@ -571,15 +611,15 @@ ad1848_poll(void *priv) break; case 0xc0: /* Mono, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = ad1848->out_r = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); break; case 0xd0: /* Stereo, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = dma_channel_read(ad1848->dma) | (temp << 8); - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_r = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); break; /* 0xe0 and 0xf0 reserved */ @@ -591,12 +631,12 @@ ad1848_poll(void *priv) if (ad1848->regs[6] & 0x80) ad1848->out_l = 0; else - ad1848->out_l = (ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16; + ad1848->out_l = (int16_t) ((ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16); if (ad1848->regs[7] & 0x80) ad1848->out_r = 0; else - ad1848->out_r = (ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16; + ad1848->out_r = (int16_t) ((ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16); if (ad1848->count < 0) { ad1848->count = ad1848->regs[15] | (ad1848->regs[14] << 8); From 15ad2c199283ed3939c46d800be370f139af881a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 03:19:24 +0200 Subject: [PATCH 442/690] NCR 53c8xx: Set correct SCSI speeds. --- src/scsi/scsi_ncr53c8xx.c | 57 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index ad1b31fe8..f640c49a6 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2567,28 +2567,39 @@ ncr53c8xx_init(const device_t *info) else pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); - if (dev->chip == CHIP_875) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c875.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_860) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c860.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_820) { - dev->nvr_path = "ncr53c820.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_825) { - dev->chip_rev = 0x26; - dev->nvr_path = "ncr53c825a.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_810) { - dev->nvr_path = "ncr53c810.nvr"; - dev->wide = 0; - } else if (dev->chip == CHIP_815) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c815.nvr"; - dev->wide = 0; + scsi_bus_set_speed(dev->bus, 10000000.0); + + switch (dev->chip) { + case CHIP_810: + dev->nvr_path = "ncr53c810.nvr"; + dev->wide = 0; + break; + case CHIP_815: + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c815.nvr"; + dev->wide = 0; + break; + case CHIP_820: + dev->nvr_path = "ncr53c820.nvr"; + dev->wide = 1; + break; + case CHIP_825: + dev->chip_rev = 0x26; + dev->nvr_path = "ncr53c825a.nvr"; + dev->wide = 1; + break; + case CHIP_860: + scsi_bus_set_speed(dev->bus, 20000000.0); + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c860.nvr"; + dev->wide = 1; + break; + case CHIP_875: + scsi_bus_set_speed(dev->bus, 40000000.0); + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c875.nvr"; + dev->wide = 1; + break; } ncr53c8xx_pci_bar[0].addr_regs[0] = 1; @@ -2629,8 +2640,6 @@ ncr53c8xx_init(const device_t *info) timer_add(&dev->timer, ncr53c8xx_callback, dev, 0); - scsi_bus_set_speed(dev->bus, 10000000.0); - return dev; } From 070c289562de474f4c389fa2052b1d766bb3ff8e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 12:06:59 +0200 Subject: [PATCH 443/690] The forgotten .h file. --- src/include/86box/snd_ad1848.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 6bdd2bf40..319f9bf24 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -61,6 +61,9 @@ typedef struct ad1848_t { int adpcm_data; int adpcm_pos; + uint8_t dma_ff; + uint32_t dma_data; + pc_timer_t timer_count; uint64_t timer_latch; From 7feb6f578df672550348d1269806b20d24a2d2f2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 20:38:48 +0200 Subject: [PATCH 444/690] Changed the internal device name of the MT32 New device, fixes #4394. --- src/sound/midi_mt32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 91d85e438..f38474ac8 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -435,7 +435,7 @@ const device_t mt32_old_device = { const device_t mt32_new_device = { .name = "Roland MT-32 (New) Emulation", - .internal_name = "mt32", + .internal_name = "mt32_new", .flags = 0, .local = 0, .init = mt32_new_init, From 15e3876e219b5448135740eabd97e926ab48f2bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 06:06:09 +0200 Subject: [PATCH 445/690] Prepare WD76C10 for 286/386 interpreter selection, exempt IBM 486BL and all Cyrix'es from the 286/386 interpreter. --- src/chipset/wd76c10.c | 86 ++++++++++++++++++++++++++++++++++------- src/cpu/cpu.c | 3 +- src/include/86box/mem.h | 2 + src/mem/mem.c | 3 +- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index ef076b606..5b6ea28d2 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -84,6 +84,7 @@ typedef struct uint8_t bios_states[8]; uint8_t high_bios_states[8]; uint8_t mem_pages[1024]; + uint8_t ram_state[4192]; uint16_t toggle, cpuclk, fpu_ctl, mem_ctl, split_sa, sh_wp, hmwpb, npmdmt, @@ -225,6 +226,34 @@ wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv) mem_write_ramw(addr, val, priv); } +static void +wd76c10_set_mem_state(wd76c10_t *dev, uint32_t base, uint32_t size, uint32_t access, uint8_t present) +{ + mem_set_mem_state_both(base, size, access); + + for (uint32_t i = base; i < (base + size); i += 4096) + dev->ram_state[i >> 12] = present; +} + +static void +wd76c10_recalc_exec(wd76c10_t *dev, uint32_t base, uint32_t size) +{ + uint32_t logical_addr = wd76c10_calc_addr(dev, base); + void *exec; + + if (logical_addr != WD76C10_ADDR_INVALID) + exec = &(ram[logical_addr]); + else + exec = NULL; + + for (uint32_t i = base; i < (base + size); i += 4096) + if (dev->ram_state[i >> 12]) + _mem_exec[i >> 12] = exec; + + if (cpu_use_exec) + flushmmucache_nopc(); +} + static void wd76c10_banks_recalc(wd76c10_t *dev) { @@ -235,6 +264,9 @@ wd76c10_banks_recalc(wd76c10_t *dev) bit = i + 12; rb->enable = (dev->split_sa >> bit) & 0x01; rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); } } @@ -245,8 +277,12 @@ wd76c10_split_recalc(wd76c10_t *dev) uint32_t split_size = ((sp_size - 1) * 65536); ram_bank_t *rb = &(dev->ram_banks[4]); - if (rb->enable && (rb->virt_size != 0x00000000)) - mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (rb->enable && (rb->virt_size != 0x00000000)) { + wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); + } rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19; switch (sp_size) { case 0x00: @@ -257,8 +293,12 @@ wd76c10_split_recalc(wd76c10_t *dev) break; } rb->enable = !!sp_size; - if (rb->enable && (rb->virt_size != 0x00000000)) - mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (rb->enable && (rb->virt_size != 0x00000000)) { + wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); + } } static void @@ -287,7 +327,7 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev) } static void -wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) +wd76c10_shadow_ram_do_recalc(wd76c10_t *dev, uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) { uint32_t base = 0x00000000; int flags = 0; @@ -300,7 +340,9 @@ wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint ((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL); flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL : ((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL); - mem_set_mem_state_both(base, 0x00004000, flags); + wd76c10_set_mem_state(dev, base, 0x00004000, flags, new_st[i] & 0x01); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, 0x000040000); } } } @@ -366,11 +408,11 @@ wd76c10_shadow_ram_recalc(wd76c10_t *dev) break; } - wd76c10_shadow_ram_do_recalc(vbios_states, dev->vbios_states, 0, 4, 0x000c0000); - wd76c10_shadow_ram_do_recalc(bios_states, dev->bios_states, 0, 8, 0x000e0000); + wd76c10_shadow_ram_do_recalc(dev, vbios_states, dev->vbios_states, 0, 4, 0x000c0000); + wd76c10_shadow_ram_do_recalc(dev, bios_states, dev->bios_states, 0, 8, 0x000e0000); /* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */ - wd76c10_shadow_ram_do_recalc(high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); + wd76c10_shadow_ram_do_recalc(dev, high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); flushmmucache_nopc(); } @@ -385,9 +427,15 @@ wd76c10_high_mem_wp_recalc(wd76c10_t *dev) /* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */ mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->hmwp_base, size); + size = 0x01000000 - base; mem_set_wp(base, size, ACCESS_NORMAL, hm_wp); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, size); + dev->hmwp_base = base; } @@ -399,7 +447,10 @@ wd76c10_pf_loc_reset(wd76c10_t *dev) for (uint8_t i = 0x031; i <= 0x03b; i++) { dev->mem_pages[i] = 0xff; base = ((uint32_t) i) << 14; - mem_set_mem_state(base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + wd76c10_set_mem_state(dev, base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, 0x00004000); } /* Re-apply any ROMCS#, etc. flags. */ @@ -419,9 +470,13 @@ wd76c10_pf_loc_recalc(wd76c10_t *dev) dev->mem_pages[i] = ems_page; base = ((uint32_t) i) << 14; dev->ems_pages[ems_page].virt = base; - if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) - mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) { + wd76c10_set_mem_state(dev, dev->ems_pages[ems_page].virt, + 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000); + } } } @@ -436,6 +491,9 @@ wd76c10_low_pages_recalc(wd76c10_t *dev) dev->mem_pages[i] = ems_page; base = ((uint32_t) i) << 14; dev->ems_pages[ems_page].virt = base; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000); } } @@ -948,6 +1006,8 @@ wd76c10_init(const device_t *info) mem_mapping_disable(&ram_high_mapping); mem_mapping_enable(&dev->ram_mapping); + memset(dev->ram_state, 0x00, sizeof(dev->ram_state)); + return dev; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4398df36c..459d41231 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1803,7 +1803,8 @@ cpu_set(void) } else #endif /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ - if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) { + if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) || + cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC)) { cpu_exec = exec386; cpu_use_exec = 1; } else diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index bc949834f..a130309c4 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -302,6 +302,8 @@ extern int memspeed[11]; extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ +extern uint8_t *_mem_exec[MEM_MAPPINGS_NO]; + extern uint32_t pages_sz; /* #pages in table */ extern int read_type; diff --git a/src/mem/mem.c b/src/mem/mem.c index 188aa49d0..1d373dafb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -123,6 +123,8 @@ uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; +uint8_t *_mem_exec[MEM_MAPPINGS_NO]; + /* FIXME: re-do this with a 'mem_ops' struct. */ static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ static uint8_t *readlookupp; @@ -131,7 +133,6 @@ static mem_mapping_t *base_mapping; static mem_mapping_t *last_mapping; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; -static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint8_t _mem_wp[MEM_MAPPINGS_NO]; static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; From 0f71a56edbec75ae41482db287bb45bebb245df7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 06:47:03 +0200 Subject: [PATCH 446/690] Some checks around a recalctimings check to fix some crashes. --- src/video/vid_mga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bbba9ca6f..aec571356 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -816,7 +816,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } } - svga_recalctimings(svga); + if (!((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE))) + svga_recalctimings(svga); + break; default: From d740a8c164019121e03d083b1cd21c3e74d1b8d8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 12:25:17 +0200 Subject: [PATCH 447/690] WD76C10: A forgotten call to recalc exec. --- src/chipset/wd76c10.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 5b6ea28d2..df8558b05 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -324,6 +324,9 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev) } dev->mem_top = mem_top; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, 128 * 1024, (640 - 128) * 1024); } static void From 0aa695c070174998af70a7b20dabb494252e55d1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 25 Apr 2024 10:55:07 +0200 Subject: [PATCH 448/690] Matrox FIFO status fix. --- src/video/vid_mga.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index aec571356..fdbb2e411 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1562,14 +1562,14 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) switch (addr & 0x3fff) { case REG_FIFOSTATUS: fifocount = FIFO_SIZE - FIFO_ENTRIES; - if (fifocount > 64) - fifocount = 64; + if (fifocount > (mystique->type <= MGA_1064SG ? 32 : 64)) + fifocount = (mystique->type <= MGA_1064SG ? 32 : 64); ret = fifocount; break; case REG_FIFOSTATUS + 1: if (FIFO_EMPTY) ret |= 2; - else if (FIFO_ENTRIES >= 64) + else if (FIFO_ENTRIES >= (mystique->type <= MGA_1064SG ? 32 : 64)) ret |= 1; break; case REG_FIFOSTATUS + 2: @@ -1583,6 +1583,10 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) ret |= REG_STATUS_VSYNCSTS; if (ret & 1) mystique->softrap_status_read = 1; + if (mystique->softrap_status_read == 0 && !(ret & 1)) { + mystique->softrap_status_read = 1; + ret |= 1; + } break; case REG_STATUS + 1: ret = (mystique->status >> 8) & 0xff; From 8928f5d771cf3b4dae6bf0e0c07f7d69fc04830d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:10:40 +0200 Subject: [PATCH 449/690] Variable to override the 286/386 interpreter. --- src/cpu/cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 459d41231..0f83a5e4b 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -187,6 +187,7 @@ int cpu_64bitbus; int cpu_cyrix_alignment; int cpu_cpurst_on_sr; int cpu_use_exec = 0; +int cpu_override_interpreter; int CPUID; int is186; @@ -1804,7 +1805,7 @@ cpu_set(void) #endif /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) || - cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC)) { + cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC) || cpu_override_interpreter) { cpu_exec = exec386; cpu_use_exec = 1; } else From 54178355b84ccaef580548ddd5f7dcea7f6959ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:11:25 +0200 Subject: [PATCH 450/690] And in cpu.h. --- src/cpu/cpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 16a9eba10..900d3d7e1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -830,6 +830,7 @@ extern int lock_legal_f6[8]; extern int lock_legal_fe[8]; extern int in_lock; +extern int cpu_override_interpreter; extern int is_lock_legal(uint32_t fetchdat); From 68ec5c53a1063752e5e2976b244cbb21b96afcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:14:51 +0200 Subject: [PATCH 451/690] And in config.c. --- src/config.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index 373ee130d..df0ae1c35 100644 --- a/src/config.c +++ b/src/config.c @@ -314,9 +314,10 @@ load_machine(void) } } - cpu_override = ini_section_get_int(cat, "cpu_override", 0); - cpu_f = NULL; - p = ini_section_get_string(cat, "cpu_family", NULL); + cpu_override = ini_section_get_int(cat, "cpu_override", 0); + cpu_override_interpreter = ini_section_get_int(cat, "cpu_override_interpreter", 0); + cpu_f = NULL; + p = ini_section_get_string(cat, "cpu_family", NULL); if (p) { /* Migrate CPU family changes. */ if ((!strcmp(machines[machine].internal_name, "deskpro386") || @@ -1626,6 +1627,8 @@ config_load(void) dpi_scale = 1; do_auto_pause = 0; + cpu_override_interpreter = 0; + fpu_type = fpu_get_type(cpu_f, cpu, "none"); gfxcard[0] = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); @@ -1948,6 +1951,10 @@ save_machine(void) ini_section_set_int(cat, "cpu_override", cpu_override); else ini_section_delete_var(cat, "cpu_override"); + if (cpu_override_interpreter) + ini_section_set_int(cat, "cpu_override_interpreter", cpu_override); + else + ini_section_delete_var(cat, "cpu_override_interpreter"); /* Downgrade compatibility with the previous CPU model system. */ ini_section_delete_var(cat, "cpu_manufacturer"); From c931e4d4601171fcac62b15c9953003404a4e648 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 19:28:03 +0200 Subject: [PATCH 452/690] Further fixes to the code related to the Mach8/32 mode changes. And 0x6e9 is an alias to 0x2e8 per the Mach32 manual (H_TOTAL). --- src/video/vid_ati_mach8.c | 44 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 522df00a6..29a687f24 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2597,15 +2597,13 @@ mach_recalctimings(svga_t *svga) if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; dev->v_total = dev->v_total_reg + 1; dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); - mach_log("VDISP=%d.\n", dev->vdisp); - if ((dev->hdisp == 800) || (dev->hdisp == 1280)) { - /*For VESA modes in ATI 8514/A mode.*/ + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04); + if ((dev->hdisp == 640) || (dev->hdisp == 800) || (dev->hdisp == 1280) || dev->bpp) { + /*For VESA/ATI modes in 8514/A mode.*/ dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; } else { @@ -3624,9 +3622,11 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 switch (port) { case 0x2e8: - case 0x2e9: - WRITE8(port, dev->htotal, val); - dev->htotal &= 0x1ff; + case 0x6e9: + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->htotal = val; + + svga_recalctimings(svga); break; case 0x6e8: @@ -3636,23 +3636,23 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); - break; - case 0x6e9: - dev->hdisped = (dev->hdisp >> 3) - 1; - dev->v_disp = (dev->vdisp - 1) << 1; - mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0xae8: - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hsync_start = val; + + mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_start=%d.\n", port, val, (val + 1) << 3); + svga_recalctimings(svga); break; case 0xee8: - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hsync_width = val; + + mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); + svga_recalctimings(svga); break; case 0x12e8: @@ -3662,6 +3662,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 WRITE8(port, dev->v_total_reg, val); dev->v_total_reg &= 0x1fff; } + svga_recalctimings(svga); break; case 0x16e8: @@ -3675,6 +3676,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ae8: @@ -3684,6 +3686,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 WRITE8(port, dev->v_sync_start, val); dev->v_sync_start &= 0x1fff; } + svga_recalctimings(svga); break; case 0x1ee8: @@ -4429,8 +4432,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) break; case 0x26e8: - case 0x26e9: - READ8(port, dev->htotal); + temp = dev->htotal; break; case 0x2ee8: From 20277f7090167e907d5e6ab9115693a9cea30578 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:05:54 +0200 Subject: [PATCH 453/690] Workaround to prevent timeouts with the T130B driver on NT 3.1. And more logging cleanups. This should make the T130B driver for NT 3.1 work normally, at least. --- src/scsi/scsi_ncr53c400.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index d605f1bdb..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -110,6 +110,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int actual_block = 0; addr &= 0x3fff; @@ -129,7 +130,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (!(ncr400->status_ctrl & CTRL_DATA_DIR) && (ncr400->buffer_host_pos < MIN(128, dev->buffer_length))) { ncr400->buffer[ncr400->buffer_host_pos++] = val; - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + ncr53c400_log("Write host pos=%i, val=%02x.\n", ncr400->buffer_host_pos, val); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -141,7 +142,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) case 0x3980: switch (addr) { case 0x3980: /* Control */ - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + ncr53c400_log("NCR 53c400 control=%02x, mode=%02x.\n", val, ncr->mode); if ((val & CTRL_DATA_DIR) && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr400->buffer_host_pos = MIN(128, dev->buffer_length); ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -153,7 +154,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr->period); + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf.\n", val, ncr->dma_mode, ncr->period); ncr400->block_count = val; ncr400->block_count_loaded = 1; @@ -164,10 +165,19 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr400->buffer_host_pos = 0; ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr400->timer) && (dev->buffer_length > 0)) { + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0) && !timer_is_on(&ncr400->timer)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - ncr53c400_log("DMA timer on\n"); - timer_on_auto(&ncr400->timer, ncr->period); + ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d.\n", scsi_device_get_callback(dev), dev->buffer_length); + actual_block = ncr400->block_count; + if (!actual_block) + actual_block = 256; + + /*Sometimes the actual block count doesn't match the SCSI buffer length / 128.*/ + if (actual_block != (dev->buffer_length / 128)) { + /*FIXME: To be improved further, this is just to workaround callback de-syncs when split transfers occur.*/ + timer_on_auto(&ncr400->timer, (ncr->period / ((double)(actual_block * 40.0)))); + } else + timer_on_auto(&ncr400->timer, ncr->period); } break; @@ -202,12 +212,12 @@ ncr53c400_read(uint32_t addr, void *priv) else { switch (addr & 0x3f80) { case 0x3800: - ncr53c400_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); + ncr53c400_log("Read intRAM %02x %02x.\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); ret = ncr400->int_ram[addr & 0x3f]; break; case 0x3880: - ncr53c400_log("Read 5380 %04x\n", addr); + ncr53c400_log("Read 5380 %04x.\n", addr); ret = ncr5380_read(addr, ncr); break; @@ -217,11 +227,11 @@ ncr53c400_read(uint32_t addr, void *priv) ncr53c400_log("No Read.\n"); } else { ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + ncr53c400_log("Read host pos=%i, ret=%02x.\n", ncr400->buffer_host_pos, ret); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); } } break; @@ -230,7 +240,7 @@ ncr53c400_read(uint32_t addr, void *priv) switch (addr) { case 0x3980: /* status */ ret = ncr400->status_ctrl; - ncr53c400_log("NCR status ctrl read=%02x\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); + ncr53c400_log("NCR status ctrl read=%02x.\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); if (!ncr400->busy) ret |= STATUS_5380_ACCESSIBLE; if (ncr->mode & 0x30) { /*Parity bits*/ @@ -239,11 +249,12 @@ ncr53c400_read(uint32_t addr, void *priv) ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ } } - ncr53c400_log("NCR 53c400 status = %02x.\n", ret); + ncr53c400_log("NCR 53c400 status=%02x.\n", ret); break; case 0x3981: /* block counter register*/ ret = ncr400->block_count; + ncr53c400_log("NCR 53c400 block count read=%02x.\n", ret); break; case 0x3982: /* switch register read */ @@ -394,7 +405,7 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) { ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr53c400_log("53c400: PERIOD=%lf.\n", period); + ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, !!timer_is_on(&ncr400->timer)); if (period == 0.0) timer_stop(&ncr400->timer); else From 738446fea60bdaad2453c04c07b3d718d46b7e09 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:52:58 +0200 Subject: [PATCH 454/690] Cleanup of the XGA mapping to be less messed up. As well as the cursor/sprite being finally fixed when the xoff goes from 0x20 onwards. This makes Win3.x' XGA cursor look normal and everything else as well. (as in, intact). --- src/video/vid_xga.c | 157 +++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index fad5e4124..e62a14a61 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -151,37 +151,50 @@ xga_updatemapping(svga_t *svga) xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on); - if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { - if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { - if (xga->aperture_cntl == 1) - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - else - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + switch (xga->op_mode & 7) { + case 0: + xga_log("XGA: VGA mode address decode disabled.\n"); + break; + case 1: + xga_log("XGA: VGA mode address decode enabled.\n"); + break; + case 2: + xga_log("XGA: 132-Column mode address decode disabled.\n"); + break; + case 3: + xga_log("XGA: 132-Column mode address decode enabled.\n"); + break; + default: + xga_log("XGA: Extended Graphics mode.\n"); + switch (xga->aperture_cntl) { + case 0: + xga_log("XGA: No 64KB aperture.\n"); + if (xga->base_addr_1mb) + mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); + else if (xga->linear_base) + mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); + else + mem_mapping_disable(&xga->linear_mapping); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (!xga->linear_endian_reverse) - mem_mapping_disable(&xga->linear_mapping); - } else if (xga->aperture_cntl == 0) { - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (xga->base_addr_1mb) - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - else - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - - if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { - xga->on = 0; - vga_on = 1; - xga_log("A5 test valid.\n"); + mem_mapping_disable(&xga->video_mapping); + break; + case 1: + xga_log("XGA: 64KB aperture at A0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + case 2: + xga_log("XGA: 64KB aperture at B0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + default: + break; } - } - - xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, - xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); + break; } - xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } void @@ -410,28 +423,6 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; - if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { - if ((xga->op_mode & 7) >= 5) - xga->cursor_data_on = 1; - else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) - xga->cursor_data_on = 1; - else if (!xga->aperture_cntl) { - if (xga->linear_endian_reverse && !(xga->access_mode & 8)) - xga->cursor_data_on = 0; - } - } - - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) { - if (xga->aperture_cntl) { - if (xga->sprite_pos & 0x0f) - xga->cursor_data_on = 1; - else - xga->cursor_data_on = 0; - } else - xga->cursor_data_on = 0; - } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) - xga->cursor_data_on = 0; - xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); @@ -515,13 +506,12 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga_t *xga = (xga_t *) svga->xga; xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); - switch (addr & 0x0f) { case 0: xga->op_mode = val; break; case 1: - xga->aperture_cntl = val; + xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; case 4: @@ -561,6 +551,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) case 0x0e: case 0x0f: xga->regs[xga->regs_idx] = val; + xga_log("EXT OUT Reg=%02x, val=%02x.\n", xga->regs_idx, val); xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]); break; @@ -801,6 +792,8 @@ xga_ext_inb(uint16_t addr, void *priv) default: ret = xga->regs[xga->regs_idx]; + if ((xga->regs_idx == 0x0c) || (xga->regs_idx == 0x0d)) + xga_log("EXT IN Reg=%02x, val=%02x.\n", xga->regs_idx, ret); break; } break; @@ -1760,6 +1753,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) switch (addr & 0x7f) { case 0x11: xga->accel.control = val; + xga_log("Control=%02x.\n", val); break; case 0x12: @@ -2303,6 +2297,12 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { + case 0x0c: + temp = xga->regs[0x0c]; + break; + case 0x0d: + temp = xga->regs[0x0d]; + break; case 0x11: temp = xga->accel.control; if (xga->accel.control & 0x08) @@ -2423,42 +2423,45 @@ xga_memio_readl(uint32_t addr, void *priv) static void xga_hwcursor_draw(svga_t *svga, int displine) { - xga_t *xga = (xga_t *) svga->xga; - uint8_t dat = 0; - int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; - int x_pos; - int y_pos; - int comb = 0; - uint32_t *p; - int idx = xga->cursor_data_on ? 32 : 0; + xga_t *xga = (xga_t *) svga->xga; + int comb; + uint8_t dat = 0; + int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; + int idx = 0; + int x_pos; + int y_pos; + uint32_t *p; + const uint8_t *cd; + + if (xga->hwcursor_latch.xoff & 0x20) + idx = 32; + + cd = (uint8_t *) xga->sprite_data; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - y_pos = displine; - x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { + dat = cd[xga->hwcursor_latch.addr & 0x3ff]; + + comb = (dat >> ((x & 0x03) << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; - for (int x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { if (x >= idx) { - if (!(x & 0x03)) - dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; - - comb = (dat >> ((x & 0x03) << 1)) & 0x03; - - x_pos = offset + svga->x_add + x; - switch (comb) { case 0x00: - /* Cursor Color 1 */ + /* Cursor Color 1 */ p[x_pos] = xga->hwc_color0; break; case 0x01: - /* Cursor Color 2 */ + /* Cursor Color 2 */ p[x_pos] = xga->hwc_color1; break; case 0x03: - /* Complement */ + /* Complement */ p[x_pos] ^= 0xffffff; break; @@ -2466,6 +2469,8 @@ xga_hwcursor_draw(svga_t *svga, int displine) break; } } + offset++; + xga_log("P=%08x, xpos=%d, comb=%x, ypos=%d, offset=%d, latchx=%d, latchxoff=%d.\n", p[x_pos], x_pos, comb, y_pos, offset, xga->hwcursor_latch.x, xga->hwcursor_latch.xoff); if ((x & 0x03) == 0x03) xga->hwcursor_latch.addr++; @@ -2927,12 +2932,12 @@ xga_poll(void *priv, svga_t *svga) if (!xga->linepos) { if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize; xga->hwcursor_oddeven = 0; } if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 33 : 1); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - 1; xga->hwcursor_oddeven = 1; } From 4325c78fa81700125c21db8617030fcb9e026b51 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 23:59:17 +0200 Subject: [PATCH 455/690] Just shut up the warning. See above. --- src/video/vid_xga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index e62a14a61..a908c3418 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2441,7 +2441,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { + for (int x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { dat = cd[xga->hwcursor_latch.addr & 0x3ff]; comb = (dat >> ((x & 0x03) << 1)) & 0x03; From f4d210273431338411588a8b57646645edaa076c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Apr 2024 16:47:32 +0200 Subject: [PATCH 456/690] Bochs VBE graphics card, originally by Cacodemon345, then extensively cleaned-up and improved. --- src/include/86box/video.h | 13 +- src/video/CMakeLists.txt | 3 +- src/video/vid_bochs_vbe.c | 941 ++++++++++++++++++++++++++++++++++++++ src/video/vid_table.c | 13 +- src/video/video.c | 2 +- 5 files changed, 959 insertions(+), 13 deletions(-) create mode 100644 src/video/vid_bochs_vbe.c diff --git a/src/include/86box/video.h b/src/include/86box/video.h index bf36bf7de..1c8b61015 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -223,7 +223,7 @@ extern void video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, in extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len); #ifdef _WIN32 -extern void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size); +extern void * (__cdecl *video_copy)(void *_Dst, const void *_Src, size_t _Size); extern void *__cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size); #else extern void *(*video_copy)(void *__restrict _Dst, const void *__restrict _Src, size_t _Size); @@ -334,6 +334,13 @@ extern const device_t compaq_ati28800_device; extern const device_t ati28800_wonderxl24_device; # endif +/* Bochs */ +extern const device_t bochs_svga_device; + +/* Chips & Technologies */ +extern const device_t chips_69000_device; +extern const device_t chips_69000_onboard_device; + /* Cirrus Logic GD54xx */ extern const device_t gd5401_isa_device; extern const device_t gd5402_isa_device; @@ -579,10 +586,6 @@ extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; -/* Chips & Technologies */ -extern const device_t chips_69000_device; -extern const device_t chips_69000_onboard_device; - #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 12ba34a02..c8fb7021d 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -26,7 +26,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c + vid_bochs_vbe.c) if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c new file mode 100644 index 000000000..c94049a1c --- /dev/null +++ b/src/video/vid_bochs_vbe.c @@ -0,0 +1,941 @@ +/* + * 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. + * + * Bochs VBE SVGA emulation. + * + * Uses code from libxcvt to calculate CRTC timings. + * + * Authors: Cacodemon345 + * The Bochs Project + * Fabrice Bellard + * The libxcvt authors + * + * Copyright 2024 Cacodemon345 + * Copyright 2003 Fabrice Bellard + * Copyright 2002-2024 The Bochs Project + * Copyright 2002-2003 Mike Nordell + * Copyright 2000-2021 The libxcvt authors + * + * See https://gitlab.freedesktop.org/xorg/lib/libxcvt/-/blob/master/COPYING for libxcvt license details + */ + +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/pci.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> + +#define VBE_DISPI_BANK_SIZE_KB 64 +#define VBE_DISPI_BANK_GRANULARITY_KB 32 + +#define VBE_DISPI_MAX_XRES 1920 +#define VBE_DISPI_MAX_YRES 1600 + +#define VBE_DISPI_IOPORT_INDEX 0x01CE +#define VBE_DISPI_IOPORT_DATA 0x01CF + +#define VBE_DISPI_INDEX_ID 0x0 +#define VBE_DISPI_INDEX_XRES 0x1 +#define VBE_DISPI_INDEX_YRES 0x2 +#define VBE_DISPI_INDEX_BPP 0x3 +#define VBE_DISPI_INDEX_ENABLE 0x4 +#define VBE_DISPI_INDEX_BANK 0x5 +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +#define VBE_DISPI_INDEX_X_OFFSET 0x8 +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 +#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa +#define VBE_DISPI_INDEX_DDC 0xb + +#define VBE_DISPI_ID0 0xB0C0 +#define VBE_DISPI_ID1 0xB0C1 +#define VBE_DISPI_ID2 0xB0C2 +#define VBE_DISPI_ID3 0xB0C3 +#define VBE_DISPI_ID4 0xB0C4 +#define VBE_DISPI_ID5 0xB0C5 + +#define VBE_DISPI_DISABLED 0x00 +#define VBE_DISPI_ENABLED 0x01 +#define VBE_DISPI_GETCAPS 0x02 +#define VBE_DISPI_BANK_GRANULARITY_32K 0x10 +#define VBE_DISPI_8BIT_DAC 0x20 +#define VBE_DISPI_LFB_ENABLED 0x40 +#define VBE_DISPI_NOCLEARMEM 0x80 + +#define VBE_DISPI_BANK_WR 0x4000 +#define VBE_DISPI_BANK_RD 0x8000 +#define VBE_DISPI_BANK_RW 0xc000 + + +typedef struct vbe_mode_info_t { + uint32_t hdisplay; + uint32_t vdisplay; + float vrefresh; + float hsync; + uint64_t dot_clock; + uint16_t hsync_start; + uint16_t hsync_end; + uint16_t htotal; + uint16_t vsync_start; + uint16_t vsync_end; + uint16_t vtotal; +} vbe_mode_info_t; + +static video_timings_t timing_bochs = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; + +typedef struct bochs_vbe_t { + svga_t svga; + + uint8_t pci_conf_status; + uint8_t pci_rom_enable; + uint8_t pci_line_interrupt; + uint8_t slot; + + uint8_t pci_regs[256]; + + uint16_t vbe_index; + uint16_t bank_gran; + uint16_t rom_addr; + uint16_t id5_val; + + uint16_t vbe_regs[16]; + + uint32_t vram_size; + + rom_t bios_rom; + + mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping_2; + + void * i2c; + void * ddc; +} bochs_vbe_t; + +static bochs_vbe_t *reset_state = NULL; + +static void +gen_mode_info(int hdisplay, int vdisplay, float vrefresh, vbe_mode_info_t* mode_info) +{ + int vsync; + int vsync_and_back_porch; + + mode_info->hdisplay = hdisplay; + mode_info->vdisplay = vdisplay; + mode_info->vrefresh = vrefresh; + + /* 1) top/bottom margin size (% of height) - default: 1.8 */ +#define CVT_MARGIN_PERCENTAGE 1.8 + + /* 2) character cell horizontal granularity (pixels) - default 8 */ +#define CVT_H_GRANULARITY 8 + + /* 4) Minimum vertical front porch (lines) - default 3 */ +#define CVT_MIN_V_PORCH_RND 3 + + /* 4) Minimum number of vertical back porch lines - default 6 */ +#define CVT_MIN_V_BPORCH 6 + + /* Pixel Clock step (kHz) */ +#define CVT_CLOCK_STEP 250 + + /* CVT default is 60.0Hz */ + if (!mode_info->vrefresh) + mode_info->vrefresh = 60.0; + + /* 1. Required field rate */ + const float vfield_rate = mode_info->vrefresh; + + /* 2. Horizontal pixels */ + const int hdisplay_rnd = mode_info->hdisplay - (mode_info->hdisplay % CVT_H_GRANULARITY); + + /* 3. Determine left and right borders */ + const int hmargin = 0; + + /* 4. Find total active pixels */ + mode_info->hdisplay = hdisplay_rnd + (2 * hmargin); + + /* 5. Find number of lines per field */ + const int vdisplay_rnd = mode_info->vdisplay; + + /* 6. Find top and bottom margins */ + const int vmargin = 0; + + mode_info->vdisplay = mode_info->vdisplay + 2 * vmargin; + + /* 7. interlace */ + /* Please rename this */ + const float interlace = 0.0; + + /* Determine vsync Width from aspect ratio */ + if (!(mode_info->vdisplay % 3) && ((mode_info->vdisplay * 4 / 3) == mode_info->hdisplay)) + vsync = 4; + else if (!(mode_info->vdisplay % 9) && + ((mode_info->vdisplay * 16 / 9) == mode_info->hdisplay)) + vsync = 5; + else if (!(mode_info->vdisplay % 10) && + ((mode_info->vdisplay * 16 / 10) == mode_info->hdisplay)) + vsync = 6; + else if (!(mode_info->vdisplay % 4) && + ((mode_info->vdisplay * 5 / 4) == mode_info->hdisplay)) + vsync = 7; + else if (!(mode_info->vdisplay % 9) && + ((mode_info->vdisplay * 15 / 9) == mode_info->hdisplay)) + vsync = 7; + else /* Custom */ + vsync = 10; + + /* Simplified GTF calculation. */ + + /* 4) Minimum time of vertical sync + back porch interval (µs) + * default 550.0 */ +#define CVT_MIN_VSYNC_BP 550.0 + + /* 3) Nominal HSync width (% of line period) - default 8 */ +#define CVT_HSYNC_PERCENTAGE 8 + + /* 8. Estimated Horizontal period */ + const float hperiod = ((float) (1000000.0 / vfield_rate - CVT_MIN_VSYNC_BP)) / + (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH_RND + interlace); + + /* 9. Find number of lines in sync + backporch */ + if (((int) (CVT_MIN_VSYNC_BP / hperiod) + 1) < (vsync + CVT_MIN_V_BPORCH)) + vsync_and_back_porch = vsync + CVT_MIN_V_BPORCH; + else + vsync_and_back_porch = (int) (CVT_MIN_VSYNC_BP / hperiod) + 1; + + /* 10. Find number of lines in back porch */ + + /* 11. Find total number of lines in vertical field */ + mode_info->vtotal = vdisplay_rnd + (2 * vmargin) + vsync_and_back_porch + interlace + + CVT_MIN_V_PORCH_RND; + + /* 5) Definition of Horizontal blanking time limitation */ + /* Gradient (%/kHz) - default 600 */ +#define CVT_M_FACTOR 600 + + /* Offset (%) - default 40 */ +#define CVT_C_FACTOR 40 + + /* Blanking time scaling factor - default 128 */ +#define CVT_K_FACTOR 128 + + /* Scaling factor weighting - default 20 */ +#define CVT_J_FACTOR 20 + +#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 +#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ + CVT_J_FACTOR + + /* 12. Find ideal blanking duty cycle from formula */ + float hblank_percentage = CVT_C_PRIME - CVT_M_PRIME * hperiod / 1000.0; + + /* 13. Blanking time */ + if (hblank_percentage < 20) + hblank_percentage = 20; + + int hblank = mode_info->hdisplay * hblank_percentage / (100.0 - hblank_percentage); + hblank -= hblank % (2 * CVT_H_GRANULARITY); + + /* 14. Find total number of pixels in a line. */ + mode_info->htotal = mode_info->hdisplay + hblank; + + /* Fill in HSync values */ + mode_info->hsync_end = mode_info->hdisplay + hblank / 2; + + int hsync_w = (mode_info->htotal * CVT_HSYNC_PERCENTAGE) / 100; + hsync_w -= hsync_w % CVT_H_GRANULARITY; + mode_info->hsync_start = mode_info->hsync_end - hsync_w; + + /* Fill in vsync values */ + mode_info->vsync_start = mode_info->vdisplay + CVT_MIN_V_PORCH_RND; + mode_info->vsync_end = mode_info->vsync_start + vsync; + + /* 15/13. Find pixel clock frequency (kHz for xf86) */ + mode_info->dot_clock = mode_info->htotal * 1000.0 / hperiod; + mode_info->dot_clock -= mode_info->dot_clock % CVT_CLOCK_STEP; + + /* 16/14. Find actual Horizontal Frequency (kHz) */ + mode_info->hsync = ((float) mode_info->dot_clock) / ((float) mode_info->htotal); + + /* 17/15. Find actual Field rate */ + mode_info->vrefresh = (1000.0 * ((float) mode_info->dot_clock)) / + ((float) (mode_info->htotal * mode_info->vtotal)); + + /* 18/16. Find actual vertical frame frequency */ + /* ignore - we don't do interlace here */ +} + +void +bochs_vbe_recalctimings(svga_t* svga) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) svga->priv; + + if (dev->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { + vbe_mode_info_t mode = { 0 }; + svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; + dev->vbe_regs[VBE_DISPI_INDEX_XRES] &= ~7; + if (dev->vbe_regs[VBE_DISPI_INDEX_XRES] == 0) { + dev->vbe_regs[VBE_DISPI_INDEX_XRES] = 8; + } + if (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES; + if (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] < dev->vbe_regs[VBE_DISPI_INDEX_XRES]) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = dev->vbe_regs[VBE_DISPI_INDEX_XRES]; + if (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES; + if (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES; + + if (dev->vbe_regs[VBE_DISPI_INDEX_YRES] == 0) + dev->vbe_regs[VBE_DISPI_INDEX_YRES] = 1; + if (dev->vbe_regs[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) + dev->vbe_regs[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES; + gen_mode_info(dev->vbe_regs[VBE_DISPI_INDEX_XRES], + dev->vbe_regs[VBE_DISPI_INDEX_YRES], 72.f, &mode); + svga->char_width = 1; + svga->dots_per_clock = 1; + svga->clock = (cpuclock * (double) (1ULL << 32)) / (mode.dot_clock * 1000.); + svga->dispend = mode.vdisplay; + svga->hdisp = mode.hdisplay; + svga->vsyncstart = mode.vsync_start; + svga->vtotal = mode.vtotal; + svga->htotal = mode.htotal; + svga->hblankstart = mode.hdisplay; + svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1); + svga->vblankstart = svga->dispend; /* no vertical overscan. */ + svga->rowcount = 0; + if (dev->vbe_regs[VBE_DISPI_INDEX_BPP] != 4) { + svga->fb_only = 1; + svga->adv_flags |= FLAG_NO_SHIFT3; + + } else { + svga->fb_only = 0; + svga->adv_flags &= ~FLAG_NO_SHIFT3; + } + + svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; + + if (svga->bpp == 4) { + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] >> 3; + svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); + } else { + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * (svga->bpp / 8); + svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); + } + + if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > + svga->vram_max) { + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; + svga->ma_latch = (svga->bpp == 4) ? (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3) : + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); + if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > + svga->vram_max) { + svga->ma_latch = 0; + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + } + } + svga->split = 0xffffff; + + switch (svga->bpp) { + case 4: + svga->render = svga_render_4bpp_highres; + break; + default: + case 8: + svga->render = svga_render_8bpp_clone_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } else { + svga->fb_only = 0; + svga->packed_4bpp = 0; + svga->adv_flags &= ~FLAG_NO_SHIFT3; + } +} + +uint16_t +bochs_vbe_inw(const uint16_t addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + const bool vbe_get_caps = !!(dev->vbe_regs[VBE_DISPI_INDEX_ENABLE] & + VBE_DISPI_GETCAPS); + uint16_t ret; + + if (addr == 0x1ce) + ret = dev->vbe_index; + else switch (dev->vbe_index) { + default: + ret = dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_XRES: + ret = vbe_get_caps ? VBE_DISPI_MAX_XRES : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_YRES: + ret = vbe_get_caps ? VBE_DISPI_MAX_YRES : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_BPP: + ret = vbe_get_caps ? 32 : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_VIDEO_MEMORY_64K: + ret = dev->vram_size >> 16; + break; + case VBE_DISPI_INDEX_BANK: + ret = vbe_get_caps ? (VBE_DISPI_BANK_GRANULARITY_32K << 8) : + dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_DDC: + if (dev->vbe_regs[dev->vbe_index] & (1 << 7)) { + ret = dev->vbe_regs[dev->vbe_index] & ((1 << 7) | 0x3); + ret |= i2c_gpio_get_scl(dev->i2c) << 2; + ret |= i2c_gpio_get_sda(dev->i2c) << 3; + } else + ret = 0x000f; + break; + } + + return ret; +} + +uint32_t +bochs_vbe_inl(const uint16_t addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + uint32_t ret; + + if (addr == 0x1ce) + ret = dev->vbe_index; + else + ret = dev->vram_size; + + pclog("[%04X:%08X] [R] %04X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +void +bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (addr == 0x1ce) + dev->vbe_index = val; + else if ((addr == 0x1cf) || (addr == 0x1d0)) switch (dev->vbe_index) { + default: + break; + case VBE_DISPI_INDEX_ID: + if ((val == VBE_DISPI_ID0) || (val == VBE_DISPI_ID1) || + (val == VBE_DISPI_ID2) || (val == VBE_DISPI_ID3) || + (val == VBE_DISPI_ID4)) + dev->vbe_regs[dev->vbe_index] = val; + else if (val == VBE_DISPI_ID5) + dev->vbe_regs[dev->vbe_index] = dev->id5_val; + break; + case VBE_DISPI_INDEX_XRES: + case VBE_DISPI_INDEX_YRES: + case VBE_DISPI_INDEX_BPP: + case VBE_DISPI_INDEX_VIRT_WIDTH: + case VBE_DISPI_INDEX_X_OFFSET: + case VBE_DISPI_INDEX_Y_OFFSET: + dev->vbe_regs[dev->vbe_index] = val; + svga_recalctimings(&dev->svga); + break; + + case VBE_DISPI_INDEX_BANK: + if (val & VBE_DISPI_BANK_RD) + dev->svga.read_bank = (val & 0x1ff) * (dev->bank_gran << 10); + if (val & VBE_DISPI_BANK_WR) + dev->svga.write_bank = (val & 0x1ff) * (dev->bank_gran << 10); + break; + + case VBE_DISPI_INDEX_DDC: + if (val & (1 << 7)) { + i2c_gpio_set(dev->i2c, !!(val & 1), !!(val & 2)); + dev->vbe_regs[dev->vbe_index] = val; + } else + dev->vbe_regs[dev->vbe_index] &= ~(1 << 7); + break; + + case VBE_DISPI_INDEX_ENABLE: { + uint32_t new_bank_gran; + dev->vbe_regs[dev->vbe_index] = val; + if ((val & VBE_DISPI_ENABLED) && + !(dev->vbe_regs[VBE_DISPI_ENABLED] & VBE_DISPI_ENABLED)) { + dev->vbe_regs[dev->vbe_index] = val; + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; + svga_recalctimings(&dev->svga); + if (!(val & VBE_DISPI_NOCLEARMEM)) { + memset(dev->svga.vram, 0, + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * dev->svga.rowoffset); + } + } else + dev->svga.read_bank = dev->svga.write_bank = 0; + if ((val & VBE_DISPI_BANK_GRANULARITY_32K) != 0) + new_bank_gran = 32; + else + new_bank_gran = 64; + if (dev->bank_gran != new_bank_gran) { + dev->bank_gran = new_bank_gran; + dev->svga.read_bank = dev->svga.write_bank = 0; + } + if (val & VBE_DISPI_8BIT_DAC) + dev->svga.adv_flags &= ~FLAG_RAMDAC_SHIFT; + else + dev->svga.adv_flags |= FLAG_RAMDAC_SHIFT; + dev->vbe_regs[dev->vbe_index] &= ~VBE_DISPI_NOCLEARMEM; + } + } +} + +void +bochs_vbe_outl(const uint16_t addr, const uint32_t val, void *priv) +{ + bochs_vbe_outw(addr, val & 0xffff, priv); + bochs_vbe_outw(addr + 2, val >> 16, priv); +} + +void +bochs_vbe_out(uint16_t addr, uint8_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + svga_t * svga = &dev->svga; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case VBE_DISPI_IOPORT_INDEX: + dev->vbe_index = val; + return; + case VBE_DISPI_IOPORT_DATA: + bochs_vbe_outw(0x1cf, val | (bochs_vbe_inw(0x1cf, dev) & 0xFF00), dev); + return; + case VBE_DISPI_IOPORT_DATA + 1: + bochs_vbe_outw(0x1cf, (val << 8) | (bochs_vbe_inw(0x1cf, dev) & 0xFF), dev); + return; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + + default: + break; + } + + svga_out(addr, val, svga); +} + +uint8_t +bochs_vbe_in(uint16_t addr, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + svga_t * svga = &dev->svga; + uint8_t ret; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + default: + ret = svga_in(addr, svga); + break; + case VBE_DISPI_IOPORT_INDEX: + ret = dev->vbe_index; + break; + case VBE_DISPI_IOPORT_DATA: + ret = bochs_vbe_inw(0x1cf, dev); + break; + case VBE_DISPI_IOPORT_DATA + 1: + ret = bochs_vbe_inw(0x1cf, dev) >> 8; + break; + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + break; + } + + return ret; +} + +static uint8_t +bochs_vbe_pci_read(const int func, const int addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + uint8_t ret = 0x00; + + if (func == 0x00) switch (addr) { + default: + break; + case 0x00: + ret = 0x34; + break; + case 0x01: + ret = 0x12; + break; + case 0x02: + ret = 0x11; + break; + case 0x03: + ret = 0x11; + break; + case 0x04: + ret = (dev->pci_conf_status & 0b11100011) | 0x80; + break; + case 0x06: + ret = 0x80; + break; + case 0x07: + ret = 0x02; + break; + case 0x0b: + ret = 0x03; + break; + case 0x13: + ret = dev->pci_regs[addr]; + break; + case 0x17: + ret = (dev->pci_regs[0x13] != 0x00) ? 0xe0 : 0x00; + break; + case 0x30: + ret = dev->pci_rom_enable & 0x01; + break; + case 0x32: + ret = dev->rom_addr & 0xff; + break; + case 0x33: + ret = (dev->rom_addr & 0xff00) >> 8; + break; + case 0x3c: + ret = dev->pci_line_interrupt; + break; + case 0x3d: + ret = 0x01; + break; + } else + ret = 0xff; + + if (func == 0x00) + pclog("[R] %02X = %02X\n", addr, ret); + + return ret; +} + +static void +bochs_vbe_disable_handlers(bochs_vbe_t *dev) +{ + io_removehandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_removehandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, + bochs_vbe_inl, bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->svga.mapping); + mem_mapping_disable(&dev->bios_rom.mapping); + + reset_state->linear_mapping_2 = dev->linear_mapping_2; + reset_state->linear_mapping = dev->linear_mapping; + reset_state->svga.mapping = dev->svga.mapping; + reset_state->bios_rom.mapping = dev->bios_rom.mapping; +} + +static void +bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (func == 0x00) + pclog("[W] %02X = %02X\n", addr, val); + + if (func == 0x00) switch (addr) { + default: + break; + case 0x04: + dev->pci_conf_status = val; + io_removehandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_removehandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, + bochs_vbe_inl, bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->svga.mapping); + if (dev->pci_conf_status & PCI_COMMAND_IO) { + io_sethandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_sethandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, bochs_vbe_inl, + bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + } + if (dev->pci_conf_status & PCI_COMMAND_MEM) { + mem_mapping_enable(&dev->svga.mapping); + if (dev->pci_regs[0x13] != 0x00) { + mem_mapping_enable(&dev->linear_mapping); + if (dev->pci_regs[0x13] != 0xe0) + mem_mapping_enable(&dev->linear_mapping_2); + } + } + break; + case 0x13: + dev->pci_regs[addr] = val; + + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + + if ((dev->pci_conf_status & PCI_COMMAND_MEM) && (val != 0x00)) { + mem_mapping_set_addr(&dev->linear_mapping, val << 24, 0x01000000); + if (val != 0xe0) + mem_mapping_set_addr(&dev->linear_mapping_2, 0xe0000000, 0x01000000); + } + break; + case 0x3c: + dev->pci_line_interrupt = val; + break; + case 0x30: + dev->pci_rom_enable = val & 0x01; + mem_mapping_disable(&dev->bios_rom.mapping); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + case 0x32: + dev->rom_addr = (dev->rom_addr & 0xff00) | (val & 0xfc); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + case 0x33: + dev->rom_addr = (dev->rom_addr & 0x00ff) | (val << 8); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + } +} + +static void +bochs_vbe_reset(void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (reset_state != NULL) { + bochs_vbe_disable_handlers(dev); + reset_state->slot = dev->slot; + + *dev = *reset_state; + } +} + +static void * +bochs_vbe_init(const device_t *info) +{ + bochs_vbe_t *dev = calloc(1, sizeof(bochs_vbe_t)); + reset_state = calloc(1, sizeof(bochs_vbe_t)); + + dev->id5_val = device_get_config_int("revision"); + dev->vram_size = device_get_config_int("memory") * (1 << 20); + + rom_init(&dev->bios_rom, "roms/video/bochs/VGABIOS-lgpl-latest.bin", + 0xc0000, 0x10000, 0xffff, 0x0000, + MEM_MAPPING_EXTERNAL); + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs); + + svga_init(info, &dev->svga, dev, dev->vram_size, + bochs_vbe_recalctimings, + bochs_vbe_in, bochs_vbe_out, + NULL, + NULL); + + mem_mapping_add(&dev->linear_mapping, 0, 0, + svga_readb_linear, svga_readw_linear, svga_readl_linear, + svga_writeb_linear, svga_writew_linear, svga_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, &dev->svga); + /* Hack: If the mapping gets mapped anywhere other than at 0xe0000000, + enable this second copy of it at 0xe0000000 so michaln's driver works. */ + mem_mapping_add(&dev->linear_mapping_2, 0, 0, + svga_readb_linear, svga_readw_linear, svga_readl_linear, + svga_writeb_linear, svga_writew_linear, svga_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, &dev->svga); + + mem_mapping_disable(&dev->bios_rom.mapping); + + mem_mapping_disable(&dev->svga.mapping); + + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->linear_mapping_2); + + dev->svga.bpp = 8; + dev->svga.miscout = 1; + + dev->bank_gran = 64; + + svga_set_ramdac_type(&dev->svga, RAMDAC_8BIT); + + dev->svga.adv_flags |= FLAG_RAMDAC_SHIFT; + dev->svga.decode_mask = 0xffffff; + + dev->i2c = i2c_gpio_init("ddc_bochs"); + dev->ddc = ddc_init(i2c_gpio_get_bus(dev->i2c)); + + pci_add_card(PCI_ADD_NORMAL, bochs_vbe_pci_read, bochs_vbe_pci_write, dev, &dev->slot); + + *reset_state = *dev; + + return dev; +} + +static int +bochs_vbe_available(void) +{ + return rom_present("roms/video/bochs/VGABIOS-lgpl-latest.bin"); +} + +void +bochs_vbe_close(void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + ddc_close(dev->ddc); + i2c_gpio_close(dev->i2c); + + svga_close(&dev->svga); + + free(reset_state); + reset_state = NULL; + + free(dev); +} + +void +bochs_vbe_speed_changed(void *priv) +{ + bochs_vbe_t *bochs_vbe = (bochs_vbe_t *) priv; + + svga_recalctimings(&bochs_vbe->svga); +} + +void +bochs_vbe_force_redraw(void *priv) +{ + bochs_vbe_t *bochs_vbe = (bochs_vbe_t *) priv; + + bochs_vbe->svga.fullchange = changeframecount; +} + +static const device_config_t bochs_vbe_config[] = { + // clang-format off + { + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "VirtualBox", + .value = VBE_DISPI_ID4 + }, + { + .description = "Bochs latest", + .value = VBE_DISPI_ID5 + }, + { + .description = "" + } + }, + .default_int = VBE_DISPI_ID5 + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } + }, + .default_int = 16 + }, + { + .type = CONFIG_END + } + // clang-format on +}; + +const device_t bochs_svga_device = { + .name = "Bochs SVGA", + .internal_name = "bochs_svga", + .flags = DEVICE_PCI, + .local = 0, + .init = bochs_vbe_init, + .close = bochs_vbe_close, + .reset = bochs_vbe_reset, + { .available = bochs_vbe_available }, + .speed_changed = bochs_vbe_speed_changed, + .force_redraw = bochs_vbe_force_redraw, + .config = bochs_vbe_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e526216c3..b2686b2f3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -163,11 +163,8 @@ video_cards[] = { { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_pci_device }, { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, + { &bochs_svga_device }, + { &chips_69000_device }, { &gd5430_pci_device, }, { &gd5434_pci_device }, { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, @@ -175,6 +172,11 @@ video_cards[] = { { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, { &gd5480_pci_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, { &s3_spea_mercury_lite_86c928_pci_device }, { &s3_diamond_stealth64_964_pci_device }, { &s3_elsa_winner2000_pro_x_964_pci_device }, @@ -206,7 +208,6 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, - { &chips_69000_device }, { &millennium_device }, { &millennium_ii_device }, { &mystique_device }, diff --git a/src/video/video.c b/src/video/video.c index 01c398118..0773e61ce 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -104,7 +104,7 @@ monitor_settings_t monitor_settings[MONITORS_NUM]; atomic_bool doresize_monitors[MONITORS_NUM]; #ifdef _WIN32 -void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; +void * (*__cdecl video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; #else void *(*video_copy)(void *__restrict, const void *__restrict, size_t); #endif From c33adcb7a46aa7791362bde5e0860d753cc15c20 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Apr 2024 18:43:56 +0200 Subject: [PATCH 457/690] The forgotten vid_svga.h. --- src/include/86box/vid_svga.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index bc33ac746..9eecebf2c 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -29,6 +29,7 @@ # define FLAG_ATI 128 # define FLAG_S3_911_16BIT 256 # define FLAG_512K_MASK 512 +# define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ struct monitor_t; typedef struct hwcursor_t { From dde745d8786d8fd193445b251331ed522129d979 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Apr 2024 00:01:14 +0200 Subject: [PATCH 458/690] Some Bochs VBE fixes. --- src/video/vid_bochs_vbe.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index c94049a1c..bfd917a4a 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -438,8 +438,6 @@ bochs_vbe_inl(const uint16_t addr, void *priv) else ret = dev->vram_size; - pclog("[%04X:%08X] [R] %04X = %08X\n", CS, cpu_state.pc, addr, ret); - return ret; } @@ -672,9 +670,6 @@ bochs_vbe_pci_read(const int func, const int addr, void *priv) } else ret = 0xff; - if (func == 0x00) - pclog("[R] %02X = %02X\n", addr, ret); - return ret; } @@ -691,10 +686,14 @@ bochs_vbe_disable_handlers(bochs_vbe_t *dev) mem_mapping_disable(&dev->svga.mapping); mem_mapping_disable(&dev->bios_rom.mapping); + /* Save all the mappings and the timers because they are part of linked lists. */ reset_state->linear_mapping_2 = dev->linear_mapping_2; - reset_state->linear_mapping = dev->linear_mapping; - reset_state->svga.mapping = dev->svga.mapping; + reset_state->linear_mapping = dev->linear_mapping; + reset_state->svga.mapping = dev->svga.mapping; reset_state->bios_rom.mapping = dev->bios_rom.mapping; + + reset_state->svga.timer = dev->svga.timer; + reset_state->svga.timer8514 = dev->svga.timer8514; } static void @@ -702,9 +701,6 @@ bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *pri { bochs_vbe_t *dev = (bochs_vbe_t *) priv; - if (func == 0x00) - pclog("[W] %02X = %02X\n", addr, val); - if (func == 0x00) switch (addr) { default: break; From 2e4366de8b2773194176222d1b0a980478280d6f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Apr 2024 00:06:47 +0200 Subject: [PATCH 459/690] And the PCI device ID. --- src/video/vid_bochs_vbe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index bfd917a4a..603e455d1 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -623,16 +623,16 @@ bochs_vbe_pci_read(const int func, const int addr, void *priv) default: break; case 0x00: - ret = 0x34; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x34 : 0xee; break; case 0x01: - ret = 0x12; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x12 : 0x80; break; case 0x02: - ret = 0x11; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x11 : 0xef; break; case 0x03: - ret = 0x11; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x11 : 0xbe; break; case 0x04: ret = (dev->pci_conf_status & 0b11100011) | 0x80; From 37996011248b6dbfd3697f039f0d70037e8f1c79 Mon Sep 17 00:00:00 2001 From: Barnacl437 Date: Thu, 2 May 2024 21:23:03 +0700 Subject: [PATCH 460/690] Adding Vietnamese language (vi-VN) translation file --- src/qt/languages/vi-VN.po | 1174 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1174 insertions(+) create mode 100644 src/qt/languages/vi-VN.po diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po new file mode 100644 index 000000000..ed483dec2 --- /dev/null +++ b/src/qt/languages/vi-VN.po @@ -0,0 +1,1174 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: vi_VN\n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "&Thực hiện" + +msgid "&Keyboard requires capture" +msgstr "Bàn phím &hoạt động cần capture chuột" + +msgid "&Right CTRL is left ALT" +msgstr "Gắn CTRL p&hải vào ALT trái" + +msgid "&Hard Reset..." +msgstr "Buộc khởi độn&g lại" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "Tạm &dừng" + +msgid "E&xit..." +msgstr "Th&oát..." + +msgid "&View" +msgstr "&Xem" + +msgid "&Hide status bar" +msgstr "Ẩn tha&nh trạng thái" + +msgid "Hide &toolbar" +msgstr "Ẩn thanh &công cụ" + +msgid "&Resizeable window" +msgstr "Tùy chỉnh cỡ cử&a sổ" + +msgid "R&emember size && position" +msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&Qt (Software)" +msgstr "&Qt (phần mềm)" + +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Tự nhập độ &phân giải..." + +msgid "F&orce 4:3 display ratio" +msgstr "Giữ n&guyên khung hình 4:3" + +msgid "&Window scale factor" +msgstr "Đổi &tỷ lệ cửa sổ" + +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 "&Bộ lọc hình ảnh" + +msgid "&Nearest" +msgstr "&Cực cận" + +msgid "&Linear" +msgstr "Tu&yến tính" + +msgid "Hi&DPI scaling" +msgstr "Tỷ lệ hinh ảnh phân giải cao" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "&Chế độ kéo giãn hình" + +msgid "&Full screen stretch" +msgstr "Kéo giãn hình" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Điểm ảnh vuông (giữ tỷ lệ)" + +msgid "&Integer scale" +msgstr "Căn tỷ lệ số nguyên" + +msgid "4:&3 Integer scale" +msgstr "Căn tỷ lệ 4:3 số nguyên" + +msgid "E&GA/(S)VGA settings" +msgstr "Cài đặt EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Đảo mà&u VGA" + +msgid "VGA screen &type" +msgstr "L&oại màn VGA" + +msgid "RGB &Color" +msgstr "Màu R&GB" + +msgid "&RGB Grayscale" +msgstr "Thang xám RG&B" + +msgid "&Amber monitor" +msgstr "Màn hình vàng hổ phách (amber)" + +msgid "&Green monitor" +msgstr "Màn hình lục" + +msgid "&White monitor" +msgstr "Màn hinh trắng" + +msgid "Grayscale &conversion type" +msgstr "Chuyển đổi thang &màu xám" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Trung bình" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Chỉnh tương phản cho màn hình đơn sắc" + +msgid "&Media" +msgstr "&Phương tiện" + +msgid "&Tools" +msgstr "&Công cụ" + +msgid "&Settings..." +msgstr "&Cài đặt..." + +msgid "&Update status bar icons" +msgstr "Cậ&p nhật biểu tượng thanh trạng thái" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Chụp &màn hình\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Tùy biến..." + +msgid "Enable &Discord integration" +msgstr "Bật trình trạng thái cho Discord" + +msgid "Sound &gain..." +msgstr "Bộ &tăng âm..." + +msgid "Begin trace\tCtrl+T" +msgstr "Bắt đầu dò\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Ngưng dò\tCtrl+T" + +msgid "&Help" +msgstr "&Trợ giúp" + +msgid "&Documentation..." +msgstr "&Trợ giúp..." + +msgid "&About 86Box..." +msgstr "&Về 86Box..." + +msgid "&New image..." +msgstr "Tạo file ảnh đĩa mới..." + +msgid "&Existing image..." +msgstr "Ảnh đĩa có sẵn..." + +msgid "Existing image (&Write-protected)..." +msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." + +msgid "&Record" +msgstr "&Ghi lại" + +msgid "&Play" +msgstr "&Phát" + +msgid "&Rewind to the beginning" +msgstr "&Tua về đầu" + +msgid "&Fast forward to the end" +msgstr "T&iến về cuối" + +msgid "E&ject" +msgstr "Đẩy đĩ&a ra" + +msgid "&Image..." +msgstr "&Ảnh đĩa..." + +msgid "E&xport to 86F..." +msgstr "Xuất ra f&ile 86F..." + +msgid "&Mute" +msgstr "Tắt tiến&g" + +msgid "E&mpty" +msgstr "Làm trố&ng đĩa" + +msgid "&Reload previous image" +msgstr "Load đĩ&a trước đó" + +msgid "&Folder..." +msgstr "Thư mụ&c" + +msgid "Target &framerate" +msgstr "Số khung hình mục tiêu" + +msgid "&Sync with video" +msgstr "Đồng bộ &với video" + +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 "&Chọn shader..." + +msgid "&Remove shader" +msgstr "&Bỏ shader" + +msgid "Preferences" +msgstr "Tùy biến" + +msgid "Sound Gain" +msgstr "Tăng âm" + +msgid "New Image" +msgstr "Ảnh đĩa mới" + +msgid "Settings" +msgstr "Cài đặt" + +msgid "Specify Main Window Dimensions" +msgstr "Tùy biến kích thước cửa sổ chính" + +msgid "OK" +msgstr "Đồng ý" + +msgid "Cancel" +msgstr "Thôi" + +msgid "Save these settings as &global defaults" +msgstr "Lưu cài đặt làm mặc định chung" + +msgid "&Default" +msgstr "&Mặc định" + +msgid "Language:" +msgstr "Ngôn ngữ:" + +msgid "Icon set:" +msgstr "Bộ biểu tượng:" + +msgid "Gain" +msgstr "Tăng" + +msgid "File name:" +msgstr "Tên tập tin:" + +msgid "Disk size:" +msgstr "Kích thước đĩa:" + +msgid "RPM mode:" +msgstr "Tốc độ vòng quay:" + +msgid "Progress:" +msgstr "Tiến trình:" + +msgid "Width:" +msgstr "Chiều rộng:" + +msgid "Height:" +msgstr "Chiều cao:" + +msgid "Lock to this size" +msgstr "Cố định kích thước hình hiện tại" + +msgid "Machine type:" +msgstr "Loại máy:" + +msgid "Machine:" +msgstr "Mẫu máy:" + +msgid "Configure" +msgstr "Tinh chỉnh" + +msgid "CPU type:" +msgstr "Loại CPU:" + +msgid "Speed:" +msgstr "Tốc độ:" + +msgid "Frequency:" +msgstr "Tần số xung:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Trạng thái chờ:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Bộ nhớ (RAM):" + +msgid "Time synchronization" +msgstr "Đồng bộ thời gian" + +msgid "Disabled" +msgstr "Vô hiệu hóa" + +msgid "Enabled (local time)" +msgstr "Bật (giờ địa phương)" + +msgid "Enabled (UTC)" +msgstr "Bật (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo đồ họa" + +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A đồ họa" + +msgid "XGA Graphics" +msgstr "XGA đồ họa" + +msgid "Mouse:" +msgstr "Chuột:" + +msgid "Joystick:" +msgstr "Cần điều khiển:" + +msgid "Joystick 1..." +msgstr "Cần điều khiển 1..." + +msgid "Joystick 2..." +msgstr "Cần điều khiển 2..." + +msgid "Joystick 3..." +msgstr "Cần điều khiển 3..." + +msgid "Joystick 4..." +msgstr "Cần điều khiển 4..." + +msgid "Sound card #1:" +msgstr "Card âm thanh 1:" + +msgid "Sound card #2:" +msgstr "Card âm thanh 2:" + +msgid "Sound card #3:" +msgstr "Card âm thanh 3:" + +msgid "Sound card #4:" +msgstr "Card âm thanh 4:" + +msgid "MIDI Out Device:" +msgstr "Thiết bị MIDI out:" + +msgid "MIDI In Device:" +msgstr "Thiết bị MIDI in:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 độc lập" + +msgid "Use FLOAT32 sound" +msgstr "Dùng âm FLOAT32" + +msgid "FM synth driver" +msgstr "Driver bộ tổng hợp (synth) FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (chính xác hơn)" + +msgid "YMFM (faster)" +msgstr "YMFM (nhanh hơn)" + +msgid "Network type:" +msgstr "Kiểu loại mạng:" + +msgid "PCap device:" +msgstr "Thiết bị PCap:" + +msgid "Network adapter:" +msgstr "Bộ thích ứng (adapter) mạng:" + +msgid "COM1 Device:" +msgstr "Thiết bị COM1:" + +msgid "COM2 Device:" +msgstr "Thiết bị COM2:" + +msgid "COM3 Device:" +msgstr "Thiết bị COM3:" + +msgid "COM4 Device:" +msgstr "Thiết bị COM4:" + +msgid "LPT1 Device:" +msgstr "Thiết bị LPT1:" + +msgid "LPT2 Device:" +msgstr "Thiết bị LPT2:" + +msgid "LPT3 Device:" +msgstr "Thiết bị LPT3:" + +msgid "LPT4 Device:" +msgstr "Thiết bị LPT4:" + +msgid "Serial port 1" +msgstr "Cổng serial 1" + +msgid "Serial port 2" +msgstr "Cổng serial 2" + +msgid "Serial port 3" +msgstr "Puerto serie 3" + +msgid "Serial port 4" +msgstr "Cổng serial 4" + +msgid "Parallel port 1" +msgstr "Cổng parallel 1" + +msgid "Parallel port 2" +msgstr "Cổng parallel 2" + +msgid "Parallel port 3" +msgstr "Cổng parallel 3" + +msgid "Parallel port 4" +msgstr "Cổng parallel 4" + +msgid "HD Controller:" +msgstr "Bộ điều khiển HD:" + +msgid "FD Controller:" +msgstr "Bộ điều khiển FD:" + +msgid "Tertiary IDE Controller" +msgstr "Bộ điều khiển IDE thứ ba" + +msgid "Quaternary IDE Controller" +msgstr "Bộ điều khiển IDE thứ tư" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Bộ điều khiển 1:" + +msgid "Controller 2:" +msgstr "Bộ điều khiển 2:" + +msgid "Controller 3:" +msgstr "Bộ điều khiển 3:" + +msgid "Controller 4:" +msgstr "Bộ điều khiển 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Đĩa cứng:" + +msgid "&New..." +msgstr "Tạ&o mới..." + +msgid "&Existing..." +msgstr "&Có sẵn..." + +msgid "&Remove" +msgstr "Loạ&i bỏ" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kênh:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "Chỉ &rõ..." + +msgid "Sectors:" +msgstr "Sector:" + +msgid "Heads:" +msgstr "Đầu ghi:" + +msgid "Cylinders:" +msgstr "Trụ:" + +msgid "Size (MB):" +msgstr "Kích thước (MB):" + +msgid "Type:" +msgstr "Loại:" + +msgid "Image Format:" +msgstr "Định dạng ảnh đĩa:" + +msgid "Block Size:" +msgstr "Kích thước bloc:" + +msgid "Floppy drives:" +msgstr "Ổ đĩa mềm:" + +msgid "Turbo timings" +msgstr "Thời gian turbo" + +msgid "Check BPB" +msgstr "Kiểm tra BPB" + +msgid "CD-ROM drives:" +msgstr "Ổ đĩa CD-ROM:" + +msgid "MO drives:" +msgstr "Ổ đĩa MO:" + +msgid "ZIP drives:" +msgstr "Ổ đĩa ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr Mở rộng bộ nhớ qua ISA" + +msgid "Card 1:" +msgstr "Thẻ 1:" + +msgid "Card 2:" +msgstr "Thẻ 2:" + +msgid "Card 3:" +msgstr "Thẻ 3:" + +msgid "Card 4:" +msgstr "Thẻ 4:" + +msgid "ISABugger device" +msgstr "Thiết bị ISABugger" + +msgid "POST card" +msgstr "Thẻ POST" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Lỗi" + +msgid "Fatal error" +msgstr "Lỗi nghiêm trọng" + +msgid " - PAUSED" +msgstr " - TẠM DỪNG" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." + +msgid "Speed" +msgstr "Vận tốc" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Ảnh đĩa 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 không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." + +msgid "(empty)" +msgstr "(trống trơn)" + +msgid "All files" +msgstr "Tất cả file" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Bật" + +msgid "Off" +msgstr "Tắt" + +msgid "All images" +msgstr "Tất cả ảnh" + +msgid "Basic sector images" +msgstr "Ảnh sector cơ bản" + +msgid "Surface images" +msgstr "Ảnh bề mặt" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." + +msgid "Machine" +msgstr "Mẫu máy" + +msgid "Display" +msgstr "Hiển thị" + +msgid "Input devices" +msgstr "Thiết bị nhập" + +msgid "Sound" +msgstr "Thanh âm" + +msgid "Network" +msgstr "Nối mạng" + +msgid "Ports (COM & LPT)" +msgstr "Cổng (COM và LPT)" + +msgid "Storage controllers" +msgstr "Vi điều khiển bộ nhớ ổ cứng" + +msgid "Hard disks" +msgstr "Ổ cứng" + +msgid "Floppy & CD-ROM drives" +msgstr "Ổ (đĩa) mềm và CD-ROM" + +msgid "Other removable devices" +msgstr "Thiết bị tháo rời được khác" + +msgid "Other peripherals" +msgstr "Thiết bị ngoại vi khác" + +msgid "Click to capture mouse" +msgstr "Bấm để capture ('nhốt') chuột vào" + +msgid "Press %1 to release mouse" +msgstr "Nhấn %1 để thả chuột" + +msgid "Press %1 or middle button to release mouse" +msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." + +msgid "Default" +msgstr "Mặc định" + +msgid "%i Wait state(s)" +msgstr "%i trạng thái chờ" + +msgid "Type" +msgstr "Loại" + +msgid "No PCap devices found" +msgstr "Không tìm thấy thiết bị PCap" + +msgid "Invalid PCap device" +msgstr "Thiết bị PCap không hợp quy" + +msgid "Standard 2-button joystick(s)" +msgstr "Cần điều khiển hai nút tiêu chuẩn" + +msgid "Standard 4-button joystick" +msgstr "Cần điều khiển bốn nút tiêu chuẩn" + +msgid "Standard 6-button joystick" +msgstr "Cần điều khiển sáu nút tiêu chuẩn" + +msgid "Standard 8-button joystick" +msgstr "Cần điều khiển tám nút tiêu chuẩn" + +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 "Không có" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Đĩa mềm %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Ảnh (đĩa) sector nâng cao" + +msgid "Flux images" +msgstr "Ảnh thông lượng (flux)" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Bạn có thật sự buộc máy khởi động lại không?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Bạn có muốn thoát 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Không thể khởi tạo Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Ảnh đĩa MO" + +msgid "Welcome to 86Box!" +msgstr "Chào mừng đến 86Box!" + +msgid "Internal controller" +msgstr "Vi điều khiển nội bộ" + +msgid "Exit" +msgstr "Thoát" + +msgid "No ROMs found" +msgstr "Không tìm thấy ROM" + +msgid "Do you want to save the settings?" +msgstr "Bạn có muốn lưu cài đặt không?" + +msgid "This will hard reset the emulated machine." +msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." + +msgid "Save" +msgstr "Lưu" + +msgid "About 86Box" +msgstr "Về 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." + +msgid "Hardware not available" +msgstr "Phần cứng không có sẵn" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." + +msgid "Invalid configuration" +msgstr "Tinh chỉnh không hợp lý" + +msgid "%1 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 "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Đang tiến vào chế độ toàn màn hình" + +msgid "Don't show this message again" +msgstr "Không hiện thông báo này nữa" + +msgid "Don't exit" +msgstr "Không thoát" + +msgid "Reset" +msgstr "Khởi động lại" + +msgid "Don't reset" +msgstr "Không khởi động lại" + +msgid "CD-ROM images" +msgstr "Ảnh đĩa CD-ROM" + +msgid "%1 Device Configuration" +msgstr "Tinh chỉnh thiết bị %1" + +msgid "Monitor in sleep mode" +msgstr "Màn hình chế độ chờ/ngủ" + +msgid "OpenGL Shaders" +msgstr "Shader OpenGL" + +msgid "OpenGL options" +msgstr "Tùy chọn OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." + +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 "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." + +msgid "Continue" +msgstr "Tiếp tục" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Ảnh đĩa Cassette" + +msgid "Cartridge %i: %ls" +msgstr "Băng cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Ảnh đĩa băng cartridge" + +msgid "Error initializing renderer" +msgstr "Lỗi khởi tạo renderer (trình kết xuất)" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." + +msgid "Resume execution" +msgstr "Tiếp tục chạy thực thi" + +msgid "Pause execution" +msgstr "Dừng chạy thực thi" + +msgid "Press Ctrl+Alt+Del" +msgstr "Nhấn Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Nhấn Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Buộc khởi động lại" + +msgid "ACPI shutdown" +msgstr "Tắt máy theo ACPI" + +msgid "Hard disk (%1)" +msgstr "Ổ cứng (%1)" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" + +msgid "Custom..." +msgstr "Tùy chỉnh..." + +msgid "Custom (large)..." +msgstr "Tùy chỉnh (dung tích lớn)..." + +msgid "Add New Hard Disk" +msgstr "Thêm ổ cứng mới" + +msgid "Add Existing Hard Disk" +msgstr "Thêm ổ cứng đã có" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Ảnh đĩa không to hơn 127 GB." + +msgid "Hard disk images" +msgstr "Ảnh đĩa ổ cứng" + +msgid "Unable to read file" +msgstr "Không đọc được file" + +msgid "Unable to write file" +msgstr "Không ghi được vào file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." + +msgid "Disk image file already exists" +msgstr "Đã có file ảnh đĩa rồi" + +msgid "Please specify a valid file name." +msgstr "Vui lòng đặt tên hợp lệ." + +msgid "Disk image created" +msgstr "Đã tạo ảnh đĩa" + +msgid "Make sure the file exists and is readable." +msgstr "Chắc chắn rằng file tồn tại và đọc được." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." + +msgid "Disk image too large" +msgstr "Ảnh đĩa quá to" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" + +msgid "Unsupported disk image" +msgstr "File ảnh đĩa không được hỗ trợ" + +msgid "Overwrite" +msgstr "Có ghi đè" + +msgid "Don't overwrite" +msgstr "Không ghi đè" + +msgid "Raw image (.img)" +msgstr "Ảnh đĩa thô (.img)" + +msgid "HDI image (.hdi)" +msgstr "Ảnh đĩa HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Ảnh đĩa HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước cố định (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước tăng dần (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Bloc lớn (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Bloc bé (512 KB)" + +msgid "VHD files" +msgstr "File VHD" + +msgid "Select the parent VHD" +msgstr "Chọn file VHD cha (parent)" + +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 "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" + +msgid "Could not fix VHD timestamp." +msgstr "Không thể sửa mốc timestamp cho VHD." + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +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 "Số RPM(vòng quay đĩa/phút) hoàn thiện" + +msgid "1% below perfect RPM" +msgstr "1% thấp hơn số RPM hoàn thiện" + +msgid "1.5% below perfect RPM" +msgstr "1.5% thấp hơn số RPM hoàn thiện" + +msgid "2% below perfect RPM" +msgstr "2% thấp hơn số RPM hoàn thiện" + +msgid "(System Default)" +msgstr "(Mặc định hệ thống)" + +msgid "Failed to initialize network driver" +msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" + +msgid "The network configuration will be switched to the null driver" +msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" + +msgid "Mouse sensitivity:" +msgstr "Độ nhạy chuột:" + +msgid "Select media images from program working directory" +msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" + +msgid "PIT mode:" +msgstr "Chế độ PIT:" + +msgid "Auto" +msgstr "Tự động" + +msgid "Slow" +msgstr "Chậm" + +msgid "Fast" +msgstr "Nhanh" + +msgid "&Auto-pause on focus loss" +msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" + +msgid "WinBox is no longer supported" +msgstr "WinBox không còn được hỗ trợ" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." From b4174e07f05b69d5cabbe593daf7d398e4e1e552 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:39:09 +0500 Subject: [PATCH 461/690] Fix up the vi-VN translation --- src/qt/languages/vi-VN.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index ed483dec2..6c4f772de 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -490,7 +490,7 @@ msgid "Serial port 2" msgstr "Cổng serial 2" msgid "Serial port 3" -msgstr "Puerto serie 3" +msgstr "Cổng serial 3" msgid "Serial port 4" msgstr "Cổng serial 4" @@ -607,7 +607,7 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr Mở rộng bộ nhớ qua ISA" +msgstr "Mở rộng bộ nhớ qua ISA" msgid "Card 1:" msgstr "Thẻ 1:" From eca80d375ab2df065a305c5e56e9c1754003b482 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:39:35 +0500 Subject: [PATCH 462/690] Convert the new translation file to LF line endings --- src/qt/languages/vi-VN.po | 2348 ++++++++++++++++++------------------- 1 file changed, 1174 insertions(+), 1174 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 6c4f772de..9f5421ee9 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -1,1174 +1,1174 @@ -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Language: vi_VN\n" -"X-Source-Language: en_US\n" - -msgid "&Action" -msgstr "&Thực hiện" - -msgid "&Keyboard requires capture" -msgstr "Bàn phím &hoạt động cần capture chuột" - -msgid "&Right CTRL is left ALT" -msgstr "Gắn CTRL p&hải vào ALT trái" - -msgid "&Hard Reset..." -msgstr "Buộc khởi độn&g lại" - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "Tạm &dừng" - -msgid "E&xit..." -msgstr "Th&oát..." - -msgid "&View" -msgstr "&Xem" - -msgid "&Hide status bar" -msgstr "Ẩn tha&nh trạng thái" - -msgid "Hide &toolbar" -msgstr "Ẩn thanh &công cụ" - -msgid "&Resizeable window" -msgstr "Tùy chỉnh cỡ cử&a sổ" - -msgid "R&emember size && position" -msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (phần mềm)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Tự nhập độ &phân giải..." - -msgid "F&orce 4:3 display ratio" -msgstr "Giữ n&guyên khung hình 4:3" - -msgid "&Window scale factor" -msgstr "Đổi &tỷ lệ cửa sổ" - -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 "&Bộ lọc hình ảnh" - -msgid "&Nearest" -msgstr "&Cực cận" - -msgid "&Linear" -msgstr "Tu&yến tính" - -msgid "Hi&DPI scaling" -msgstr "Tỷ lệ hinh ảnh phân giải cao" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "&Chế độ kéo giãn hình" - -msgid "&Full screen stretch" -msgstr "Kéo giãn hình" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "Điểm ảnh vuông (giữ tỷ lệ)" - -msgid "&Integer scale" -msgstr "Căn tỷ lệ số nguyên" - -msgid "4:&3 Integer scale" -msgstr "Căn tỷ lệ 4:3 số nguyên" - -msgid "E&GA/(S)VGA settings" -msgstr "Cài đặt EGA/(S)VGA" - -msgid "&Inverted VGA monitor" -msgstr "Đảo mà&u VGA" - -msgid "VGA screen &type" -msgstr "L&oại màn VGA" - -msgid "RGB &Color" -msgstr "Màu R&GB" - -msgid "&RGB Grayscale" -msgstr "Thang xám RG&B" - -msgid "&Amber monitor" -msgstr "Màn hình vàng hổ phách (amber)" - -msgid "&Green monitor" -msgstr "Màn hình lục" - -msgid "&White monitor" -msgstr "Màn hinh trắng" - -msgid "Grayscale &conversion type" -msgstr "Chuyển đổi thang &màu xám" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Trung bình" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" - -msgid "Change contrast for &monochrome display" -msgstr "Chỉnh tương phản cho màn hình đơn sắc" - -msgid "&Media" -msgstr "&Phương tiện" - -msgid "&Tools" -msgstr "&Công cụ" - -msgid "&Settings..." -msgstr "&Cài đặt..." - -msgid "&Update status bar icons" -msgstr "Cậ&p nhật biểu tượng thanh trạng thái" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Chụp &màn hình\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Tùy biến..." - -msgid "Enable &Discord integration" -msgstr "Bật trình trạng thái cho Discord" - -msgid "Sound &gain..." -msgstr "Bộ &tăng âm..." - -msgid "Begin trace\tCtrl+T" -msgstr "Bắt đầu dò\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "Ngưng dò\tCtrl+T" - -msgid "&Help" -msgstr "&Trợ giúp" - -msgid "&Documentation..." -msgstr "&Trợ giúp..." - -msgid "&About 86Box..." -msgstr "&Về 86Box..." - -msgid "&New image..." -msgstr "Tạo file ảnh đĩa mới..." - -msgid "&Existing image..." -msgstr "Ảnh đĩa có sẵn..." - -msgid "Existing image (&Write-protected)..." -msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." - -msgid "&Record" -msgstr "&Ghi lại" - -msgid "&Play" -msgstr "&Phát" - -msgid "&Rewind to the beginning" -msgstr "&Tua về đầu" - -msgid "&Fast forward to the end" -msgstr "T&iến về cuối" - -msgid "E&ject" -msgstr "Đẩy đĩ&a ra" - -msgid "&Image..." -msgstr "&Ảnh đĩa..." - -msgid "E&xport to 86F..." -msgstr "Xuất ra f&ile 86F..." - -msgid "&Mute" -msgstr "Tắt tiến&g" - -msgid "E&mpty" -msgstr "Làm trố&ng đĩa" - -msgid "&Reload previous image" -msgstr "Load đĩ&a trước đó" - -msgid "&Folder..." -msgstr "Thư mụ&c" - -msgid "Target &framerate" -msgstr "Số khung hình mục tiêu" - -msgid "&Sync with video" -msgstr "Đồng bộ &với video" - -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 "&Chọn shader..." - -msgid "&Remove shader" -msgstr "&Bỏ shader" - -msgid "Preferences" -msgstr "Tùy biến" - -msgid "Sound Gain" -msgstr "Tăng âm" - -msgid "New Image" -msgstr "Ảnh đĩa mới" - -msgid "Settings" -msgstr "Cài đặt" - -msgid "Specify Main Window Dimensions" -msgstr "Tùy biến kích thước cửa sổ chính" - -msgid "OK" -msgstr "Đồng ý" - -msgid "Cancel" -msgstr "Thôi" - -msgid "Save these settings as &global defaults" -msgstr "Lưu cài đặt làm mặc định chung" - -msgid "&Default" -msgstr "&Mặc định" - -msgid "Language:" -msgstr "Ngôn ngữ:" - -msgid "Icon set:" -msgstr "Bộ biểu tượng:" - -msgid "Gain" -msgstr "Tăng" - -msgid "File name:" -msgstr "Tên tập tin:" - -msgid "Disk size:" -msgstr "Kích thước đĩa:" - -msgid "RPM mode:" -msgstr "Tốc độ vòng quay:" - -msgid "Progress:" -msgstr "Tiến trình:" - -msgid "Width:" -msgstr "Chiều rộng:" - -msgid "Height:" -msgstr "Chiều cao:" - -msgid "Lock to this size" -msgstr "Cố định kích thước hình hiện tại" - -msgid "Machine type:" -msgstr "Loại máy:" - -msgid "Machine:" -msgstr "Mẫu máy:" - -msgid "Configure" -msgstr "Tinh chỉnh" - -msgid "CPU type:" -msgstr "Loại CPU:" - -msgid "Speed:" -msgstr "Tốc độ:" - -msgid "Frequency:" -msgstr "Tần số xung:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Trạng thái chờ:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Bộ nhớ (RAM):" - -msgid "Time synchronization" -msgstr "Đồng bộ thời gian" - -msgid "Disabled" -msgstr "Vô hiệu hóa" - -msgid "Enabled (local time)" -msgstr "Bật (giờ địa phương)" - -msgid "Enabled (UTC)" -msgstr "Bật (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo đồ họa" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A đồ họa" - -msgid "XGA Graphics" -msgstr "XGA đồ họa" - -msgid "Mouse:" -msgstr "Chuột:" - -msgid "Joystick:" -msgstr "Cần điều khiển:" - -msgid "Joystick 1..." -msgstr "Cần điều khiển 1..." - -msgid "Joystick 2..." -msgstr "Cần điều khiển 2..." - -msgid "Joystick 3..." -msgstr "Cần điều khiển 3..." - -msgid "Joystick 4..." -msgstr "Cần điều khiển 4..." - -msgid "Sound card #1:" -msgstr "Card âm thanh 1:" - -msgid "Sound card #2:" -msgstr "Card âm thanh 2:" - -msgid "Sound card #3:" -msgstr "Card âm thanh 3:" - -msgid "Sound card #4:" -msgstr "Card âm thanh 4:" - -msgid "MIDI Out Device:" -msgstr "Thiết bị MIDI out:" - -msgid "MIDI In Device:" -msgstr "Thiết bị MIDI in:" - -msgid "Standalone MPU-401" -msgstr "MPU-401 độc lập" - -msgid "Use FLOAT32 sound" -msgstr "Dùng âm FLOAT32" - -msgid "FM synth driver" -msgstr "Driver bộ tổng hợp (synth) FM" - -msgid "Nuked (more accurate)" -msgstr "Nuked (chính xác hơn)" - -msgid "YMFM (faster)" -msgstr "YMFM (nhanh hơn)" - -msgid "Network type:" -msgstr "Kiểu loại mạng:" - -msgid "PCap device:" -msgstr "Thiết bị PCap:" - -msgid "Network adapter:" -msgstr "Bộ thích ứng (adapter) mạng:" - -msgid "COM1 Device:" -msgstr "Thiết bị COM1:" - -msgid "COM2 Device:" -msgstr "Thiết bị COM2:" - -msgid "COM3 Device:" -msgstr "Thiết bị COM3:" - -msgid "COM4 Device:" -msgstr "Thiết bị COM4:" - -msgid "LPT1 Device:" -msgstr "Thiết bị LPT1:" - -msgid "LPT2 Device:" -msgstr "Thiết bị LPT2:" - -msgid "LPT3 Device:" -msgstr "Thiết bị LPT3:" - -msgid "LPT4 Device:" -msgstr "Thiết bị LPT4:" - -msgid "Serial port 1" -msgstr "Cổng serial 1" - -msgid "Serial port 2" -msgstr "Cổng serial 2" - -msgid "Serial port 3" -msgstr "Cổng serial 3" - -msgid "Serial port 4" -msgstr "Cổng serial 4" - -msgid "Parallel port 1" -msgstr "Cổng parallel 1" - -msgid "Parallel port 2" -msgstr "Cổng parallel 2" - -msgid "Parallel port 3" -msgstr "Cổng parallel 3" - -msgid "Parallel port 4" -msgstr "Cổng parallel 4" - -msgid "HD Controller:" -msgstr "Bộ điều khiển HD:" - -msgid "FD Controller:" -msgstr "Bộ điều khiển FD:" - -msgid "Tertiary IDE Controller" -msgstr "Bộ điều khiển IDE thứ ba" - -msgid "Quaternary IDE Controller" -msgstr "Bộ điều khiển IDE thứ tư" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Bộ điều khiển 1:" - -msgid "Controller 2:" -msgstr "Bộ điều khiển 2:" - -msgid "Controller 3:" -msgstr "Bộ điều khiển 3:" - -msgid "Controller 4:" -msgstr "Bộ điều khiển 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Đĩa cứng:" - -msgid "&New..." -msgstr "Tạ&o mới..." - -msgid "&Existing..." -msgstr "&Có sẵn..." - -msgid "&Remove" -msgstr "Loạ&i bỏ" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Kênh:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "Chỉ &rõ..." - -msgid "Sectors:" -msgstr "Sector:" - -msgid "Heads:" -msgstr "Đầu ghi:" - -msgid "Cylinders:" -msgstr "Trụ:" - -msgid "Size (MB):" -msgstr "Kích thước (MB):" - -msgid "Type:" -msgstr "Loại:" - -msgid "Image Format:" -msgstr "Định dạng ảnh đĩa:" - -msgid "Block Size:" -msgstr "Kích thước bloc:" - -msgid "Floppy drives:" -msgstr "Ổ đĩa mềm:" - -msgid "Turbo timings" -msgstr "Thời gian turbo" - -msgid "Check BPB" -msgstr "Kiểm tra BPB" - -msgid "CD-ROM drives:" -msgstr "Ổ đĩa CD-ROM:" - -msgid "MO drives:" -msgstr "Ổ đĩa MO:" - -msgid "ZIP drives:" -msgstr "Ổ đĩa ZIP:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "Mở rộng bộ nhớ qua ISA" - -msgid "Card 1:" -msgstr "Thẻ 1:" - -msgid "Card 2:" -msgstr "Thẻ 2:" - -msgid "Card 3:" -msgstr "Thẻ 3:" - -msgid "Card 4:" -msgstr "Thẻ 4:" - -msgid "ISABugger device" -msgstr "Thiết bị ISABugger" - -msgid "POST card" -msgstr "Thẻ POST" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Lỗi" - -msgid "Fatal error" -msgstr "Lỗi nghiêm trọng" - -msgid " - PAUSED" -msgstr " - TẠM DỪNG" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." - -msgid "Speed" -msgstr "Vận tốc" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "Ảnh đĩa 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 không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." - -msgid "(empty)" -msgstr "(trống trơn)" - -msgid "All files" -msgstr "Tất cả file" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "Bật" - -msgid "Off" -msgstr "Tắt" - -msgid "All images" -msgstr "Tất cả ảnh" - -msgid "Basic sector images" -msgstr "Ảnh sector cơ bản" - -msgid "Surface images" -msgstr "Ảnh bề mặt" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." - -msgid "Machine" -msgstr "Mẫu máy" - -msgid "Display" -msgstr "Hiển thị" - -msgid "Input devices" -msgstr "Thiết bị nhập" - -msgid "Sound" -msgstr "Thanh âm" - -msgid "Network" -msgstr "Nối mạng" - -msgid "Ports (COM & LPT)" -msgstr "Cổng (COM và LPT)" - -msgid "Storage controllers" -msgstr "Vi điều khiển bộ nhớ ổ cứng" - -msgid "Hard disks" -msgstr "Ổ cứng" - -msgid "Floppy & CD-ROM drives" -msgstr "Ổ (đĩa) mềm và CD-ROM" - -msgid "Other removable devices" -msgstr "Thiết bị tháo rời được khác" - -msgid "Other peripherals" -msgstr "Thiết bị ngoại vi khác" - -msgid "Click to capture mouse" -msgstr "Bấm để capture ('nhốt') chuột vào" - -msgid "Press %1 to release mouse" -msgstr "Nhấn %1 để thả chuột" - -msgid "Press %1 or middle button to release mouse" -msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" - -msgid "Could not initialize the video renderer." -msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." - -msgid "Default" -msgstr "Mặc định" - -msgid "%i Wait state(s)" -msgstr "%i trạng thái chờ" - -msgid "Type" -msgstr "Loại" - -msgid "No PCap devices found" -msgstr "Không tìm thấy thiết bị PCap" - -msgid "Invalid PCap device" -msgstr "Thiết bị PCap không hợp quy" - -msgid "Standard 2-button joystick(s)" -msgstr "Cần điều khiển hai nút tiêu chuẩn" - -msgid "Standard 4-button joystick" -msgstr "Cần điều khiển bốn nút tiêu chuẩn" - -msgid "Standard 6-button joystick" -msgstr "Cần điều khiển sáu nút tiêu chuẩn" - -msgid "Standard 8-button joystick" -msgstr "Cần điều khiển tám nút tiêu chuẩn" - -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 "Không có" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Đĩa mềm %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Ảnh (đĩa) sector nâng cao" - -msgid "Flux images" -msgstr "Ảnh thông lượng (flux)" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Bạn có thật sự buộc máy khởi động lại không?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Bạn có muốn thoát 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Không thể khởi tạo Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "Ảnh đĩa MO" - -msgid "Welcome to 86Box!" -msgstr "Chào mừng đến 86Box!" - -msgid "Internal controller" -msgstr "Vi điều khiển nội bộ" - -msgid "Exit" -msgstr "Thoát" - -msgid "No ROMs found" -msgstr "Không tìm thấy ROM" - -msgid "Do you want to save the settings?" -msgstr "Bạn có muốn lưu cài đặt không?" - -msgid "This will hard reset the emulated machine." -msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." - -msgid "Save" -msgstr "Lưu" - -msgid "About 86Box" -msgstr "Về 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." - -msgid "Hardware not available" -msgstr "Phần cứng không có sẵn" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." - -msgid "Invalid configuration" -msgstr "Tinh chỉnh không hợp lý" - -msgid "%1 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 "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." - -msgid "Entering fullscreen mode" -msgstr "Đang tiến vào chế độ toàn màn hình" - -msgid "Don't show this message again" -msgstr "Không hiện thông báo này nữa" - -msgid "Don't exit" -msgstr "Không thoát" - -msgid "Reset" -msgstr "Khởi động lại" - -msgid "Don't reset" -msgstr "Không khởi động lại" - -msgid "CD-ROM images" -msgstr "Ảnh đĩa CD-ROM" - -msgid "%1 Device Configuration" -msgstr "Tinh chỉnh thiết bị %1" - -msgid "Monitor in sleep mode" -msgstr "Màn hình chế độ chờ/ngủ" - -msgid "OpenGL Shaders" -msgstr "Shader OpenGL" - -msgid "OpenGL options" -msgstr "Tùy chọn OpenGL" - -msgid "You are loading an unsupported configuration" -msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." - -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 "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." - -msgid "Continue" -msgstr "Tiếp tục" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Ảnh đĩa Cassette" - -msgid "Cartridge %i: %ls" -msgstr "Băng cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Ảnh đĩa băng cartridge" - -msgid "Error initializing renderer" -msgstr "Lỗi khởi tạo renderer (trình kết xuất)" - -msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." - -msgid "Resume execution" -msgstr "Tiếp tục chạy thực thi" - -msgid "Pause execution" -msgstr "Dừng chạy thực thi" - -msgid "Press Ctrl+Alt+Del" -msgstr "Nhấn Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Nhấn Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Buộc khởi động lại" - -msgid "ACPI shutdown" -msgstr "Tắt máy theo ACPI" - -msgid "Hard disk (%1)" -msgstr "Ổ cứng (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" - -msgid "Custom..." -msgstr "Tùy chỉnh..." - -msgid "Custom (large)..." -msgstr "Tùy chỉnh (dung tích lớn)..." - -msgid "Add New Hard Disk" -msgstr "Thêm ổ cứng mới" - -msgid "Add Existing Hard Disk" -msgstr "Thêm ổ cứng đã có" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Ảnh đĩa không to hơn 127 GB." - -msgid "Hard disk images" -msgstr "Ảnh đĩa ổ cứng" - -msgid "Unable to read file" -msgstr "Không đọc được file" - -msgid "Unable to write file" -msgstr "Không ghi được vào file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." - -msgid "Disk image file already exists" -msgstr "Đã có file ảnh đĩa rồi" - -msgid "Please specify a valid file name." -msgstr "Vui lòng đặt tên hợp lệ." - -msgid "Disk image created" -msgstr "Đã tạo ảnh đĩa" - -msgid "Make sure the file exists and is readable." -msgstr "Chắc chắn rằng file tồn tại và đọc được." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." - -msgid "Disk image too large" -msgstr "Ảnh đĩa quá to" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" - -msgid "Unsupported disk image" -msgstr "File ảnh đĩa không được hỗ trợ" - -msgid "Overwrite" -msgstr "Có ghi đè" - -msgid "Don't overwrite" -msgstr "Không ghi đè" - -msgid "Raw image (.img)" -msgstr "Ảnh đĩa thô (.img)" - -msgid "HDI image (.hdi)" -msgstr "Ảnh đĩa HDI (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "Ảnh đĩa HDX (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Ảnh VHD kích thước cố định (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Ảnh VHD kích thước tăng dần (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Bloc lớn (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Bloc bé (512 KB)" - -msgid "VHD files" -msgstr "File VHD" - -msgid "Select the parent VHD" -msgstr "Chọn file VHD cha (parent)" - -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 "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" - -msgid "Could not fix VHD timestamp." -msgstr "Không thể sửa mốc timestamp cho VHD." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -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 "Số RPM(vòng quay đĩa/phút) hoàn thiện" - -msgid "1% below perfect RPM" -msgstr "1% thấp hơn số RPM hoàn thiện" - -msgid "1.5% below perfect RPM" -msgstr "1.5% thấp hơn số RPM hoàn thiện" - -msgid "2% below perfect RPM" -msgstr "2% thấp hơn số RPM hoàn thiện" - -msgid "(System Default)" -msgstr "(Mặc định hệ thống)" - -msgid "Failed to initialize network driver" -msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" - -msgid "The network configuration will be switched to the null driver" -msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" - -msgid "Mouse sensitivity:" -msgstr "Độ nhạy chuột:" - -msgid "Select media images from program working directory" -msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" - -msgid "PIT mode:" -msgstr "Chế độ PIT:" - -msgid "Auto" -msgstr "Tự động" - -msgid "Slow" -msgstr "Chậm" - -msgid "Fast" -msgstr "Nhanh" - -msgid "&Auto-pause on focus loss" -msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" - -msgid "WinBox is no longer supported" -msgstr "WinBox không còn được hỗ trợ" - -msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: vi_VN\n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "&Thực hiện" + +msgid "&Keyboard requires capture" +msgstr "Bàn phím &hoạt động cần capture chuột" + +msgid "&Right CTRL is left ALT" +msgstr "Gắn CTRL p&hải vào ALT trái" + +msgid "&Hard Reset..." +msgstr "Buộc khởi độn&g lại" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "Tạm &dừng" + +msgid "E&xit..." +msgstr "Th&oát..." + +msgid "&View" +msgstr "&Xem" + +msgid "&Hide status bar" +msgstr "Ẩn tha&nh trạng thái" + +msgid "Hide &toolbar" +msgstr "Ẩn thanh &công cụ" + +msgid "&Resizeable window" +msgstr "Tùy chỉnh cỡ cử&a sổ" + +msgid "R&emember size && position" +msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&Qt (Software)" +msgstr "&Qt (phần mềm)" + +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Tự nhập độ &phân giải..." + +msgid "F&orce 4:3 display ratio" +msgstr "Giữ n&guyên khung hình 4:3" + +msgid "&Window scale factor" +msgstr "Đổi &tỷ lệ cửa sổ" + +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 "&Bộ lọc hình ảnh" + +msgid "&Nearest" +msgstr "&Cực cận" + +msgid "&Linear" +msgstr "Tu&yến tính" + +msgid "Hi&DPI scaling" +msgstr "Tỷ lệ hinh ảnh phân giải cao" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "&Chế độ kéo giãn hình" + +msgid "&Full screen stretch" +msgstr "Kéo giãn hình" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Điểm ảnh vuông (giữ tỷ lệ)" + +msgid "&Integer scale" +msgstr "Căn tỷ lệ số nguyên" + +msgid "4:&3 Integer scale" +msgstr "Căn tỷ lệ 4:3 số nguyên" + +msgid "E&GA/(S)VGA settings" +msgstr "Cài đặt EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Đảo mà&u VGA" + +msgid "VGA screen &type" +msgstr "L&oại màn VGA" + +msgid "RGB &Color" +msgstr "Màu R&GB" + +msgid "&RGB Grayscale" +msgstr "Thang xám RG&B" + +msgid "&Amber monitor" +msgstr "Màn hình vàng hổ phách (amber)" + +msgid "&Green monitor" +msgstr "Màn hình lục" + +msgid "&White monitor" +msgstr "Màn hinh trắng" + +msgid "Grayscale &conversion type" +msgstr "Chuyển đổi thang &màu xám" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Trung bình" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Chỉnh tương phản cho màn hình đơn sắc" + +msgid "&Media" +msgstr "&Phương tiện" + +msgid "&Tools" +msgstr "&Công cụ" + +msgid "&Settings..." +msgstr "&Cài đặt..." + +msgid "&Update status bar icons" +msgstr "Cậ&p nhật biểu tượng thanh trạng thái" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Chụp &màn hình\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Tùy biến..." + +msgid "Enable &Discord integration" +msgstr "Bật trình trạng thái cho Discord" + +msgid "Sound &gain..." +msgstr "Bộ &tăng âm..." + +msgid "Begin trace\tCtrl+T" +msgstr "Bắt đầu dò\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Ngưng dò\tCtrl+T" + +msgid "&Help" +msgstr "&Trợ giúp" + +msgid "&Documentation..." +msgstr "&Trợ giúp..." + +msgid "&About 86Box..." +msgstr "&Về 86Box..." + +msgid "&New image..." +msgstr "Tạo file ảnh đĩa mới..." + +msgid "&Existing image..." +msgstr "Ảnh đĩa có sẵn..." + +msgid "Existing image (&Write-protected)..." +msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." + +msgid "&Record" +msgstr "&Ghi lại" + +msgid "&Play" +msgstr "&Phát" + +msgid "&Rewind to the beginning" +msgstr "&Tua về đầu" + +msgid "&Fast forward to the end" +msgstr "T&iến về cuối" + +msgid "E&ject" +msgstr "Đẩy đĩ&a ra" + +msgid "&Image..." +msgstr "&Ảnh đĩa..." + +msgid "E&xport to 86F..." +msgstr "Xuất ra f&ile 86F..." + +msgid "&Mute" +msgstr "Tắt tiến&g" + +msgid "E&mpty" +msgstr "Làm trố&ng đĩa" + +msgid "&Reload previous image" +msgstr "Load đĩ&a trước đó" + +msgid "&Folder..." +msgstr "Thư mụ&c" + +msgid "Target &framerate" +msgstr "Số khung hình mục tiêu" + +msgid "&Sync with video" +msgstr "Đồng bộ &với video" + +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 "&Chọn shader..." + +msgid "&Remove shader" +msgstr "&Bỏ shader" + +msgid "Preferences" +msgstr "Tùy biến" + +msgid "Sound Gain" +msgstr "Tăng âm" + +msgid "New Image" +msgstr "Ảnh đĩa mới" + +msgid "Settings" +msgstr "Cài đặt" + +msgid "Specify Main Window Dimensions" +msgstr "Tùy biến kích thước cửa sổ chính" + +msgid "OK" +msgstr "Đồng ý" + +msgid "Cancel" +msgstr "Thôi" + +msgid "Save these settings as &global defaults" +msgstr "Lưu cài đặt làm mặc định chung" + +msgid "&Default" +msgstr "&Mặc định" + +msgid "Language:" +msgstr "Ngôn ngữ:" + +msgid "Icon set:" +msgstr "Bộ biểu tượng:" + +msgid "Gain" +msgstr "Tăng" + +msgid "File name:" +msgstr "Tên tập tin:" + +msgid "Disk size:" +msgstr "Kích thước đĩa:" + +msgid "RPM mode:" +msgstr "Tốc độ vòng quay:" + +msgid "Progress:" +msgstr "Tiến trình:" + +msgid "Width:" +msgstr "Chiều rộng:" + +msgid "Height:" +msgstr "Chiều cao:" + +msgid "Lock to this size" +msgstr "Cố định kích thước hình hiện tại" + +msgid "Machine type:" +msgstr "Loại máy:" + +msgid "Machine:" +msgstr "Mẫu máy:" + +msgid "Configure" +msgstr "Tinh chỉnh" + +msgid "CPU type:" +msgstr "Loại CPU:" + +msgid "Speed:" +msgstr "Tốc độ:" + +msgid "Frequency:" +msgstr "Tần số xung:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Trạng thái chờ:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Bộ nhớ (RAM):" + +msgid "Time synchronization" +msgstr "Đồng bộ thời gian" + +msgid "Disabled" +msgstr "Vô hiệu hóa" + +msgid "Enabled (local time)" +msgstr "Bật (giờ địa phương)" + +msgid "Enabled (UTC)" +msgstr "Bật (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo đồ họa" + +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A đồ họa" + +msgid "XGA Graphics" +msgstr "XGA đồ họa" + +msgid "Mouse:" +msgstr "Chuột:" + +msgid "Joystick:" +msgstr "Cần điều khiển:" + +msgid "Joystick 1..." +msgstr "Cần điều khiển 1..." + +msgid "Joystick 2..." +msgstr "Cần điều khiển 2..." + +msgid "Joystick 3..." +msgstr "Cần điều khiển 3..." + +msgid "Joystick 4..." +msgstr "Cần điều khiển 4..." + +msgid "Sound card #1:" +msgstr "Card âm thanh 1:" + +msgid "Sound card #2:" +msgstr "Card âm thanh 2:" + +msgid "Sound card #3:" +msgstr "Card âm thanh 3:" + +msgid "Sound card #4:" +msgstr "Card âm thanh 4:" + +msgid "MIDI Out Device:" +msgstr "Thiết bị MIDI out:" + +msgid "MIDI In Device:" +msgstr "Thiết bị MIDI in:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 độc lập" + +msgid "Use FLOAT32 sound" +msgstr "Dùng âm FLOAT32" + +msgid "FM synth driver" +msgstr "Driver bộ tổng hợp (synth) FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (chính xác hơn)" + +msgid "YMFM (faster)" +msgstr "YMFM (nhanh hơn)" + +msgid "Network type:" +msgstr "Kiểu loại mạng:" + +msgid "PCap device:" +msgstr "Thiết bị PCap:" + +msgid "Network adapter:" +msgstr "Bộ thích ứng (adapter) mạng:" + +msgid "COM1 Device:" +msgstr "Thiết bị COM1:" + +msgid "COM2 Device:" +msgstr "Thiết bị COM2:" + +msgid "COM3 Device:" +msgstr "Thiết bị COM3:" + +msgid "COM4 Device:" +msgstr "Thiết bị COM4:" + +msgid "LPT1 Device:" +msgstr "Thiết bị LPT1:" + +msgid "LPT2 Device:" +msgstr "Thiết bị LPT2:" + +msgid "LPT3 Device:" +msgstr "Thiết bị LPT3:" + +msgid "LPT4 Device:" +msgstr "Thiết bị LPT4:" + +msgid "Serial port 1" +msgstr "Cổng serial 1" + +msgid "Serial port 2" +msgstr "Cổng serial 2" + +msgid "Serial port 3" +msgstr "Cổng serial 3" + +msgid "Serial port 4" +msgstr "Cổng serial 4" + +msgid "Parallel port 1" +msgstr "Cổng parallel 1" + +msgid "Parallel port 2" +msgstr "Cổng parallel 2" + +msgid "Parallel port 3" +msgstr "Cổng parallel 3" + +msgid "Parallel port 4" +msgstr "Cổng parallel 4" + +msgid "HD Controller:" +msgstr "Bộ điều khiển HD:" + +msgid "FD Controller:" +msgstr "Bộ điều khiển FD:" + +msgid "Tertiary IDE Controller" +msgstr "Bộ điều khiển IDE thứ ba" + +msgid "Quaternary IDE Controller" +msgstr "Bộ điều khiển IDE thứ tư" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Bộ điều khiển 1:" + +msgid "Controller 2:" +msgstr "Bộ điều khiển 2:" + +msgid "Controller 3:" +msgstr "Bộ điều khiển 3:" + +msgid "Controller 4:" +msgstr "Bộ điều khiển 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Đĩa cứng:" + +msgid "&New..." +msgstr "Tạ&o mới..." + +msgid "&Existing..." +msgstr "&Có sẵn..." + +msgid "&Remove" +msgstr "Loạ&i bỏ" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kênh:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "Chỉ &rõ..." + +msgid "Sectors:" +msgstr "Sector:" + +msgid "Heads:" +msgstr "Đầu ghi:" + +msgid "Cylinders:" +msgstr "Trụ:" + +msgid "Size (MB):" +msgstr "Kích thước (MB):" + +msgid "Type:" +msgstr "Loại:" + +msgid "Image Format:" +msgstr "Định dạng ảnh đĩa:" + +msgid "Block Size:" +msgstr "Kích thước bloc:" + +msgid "Floppy drives:" +msgstr "Ổ đĩa mềm:" + +msgid "Turbo timings" +msgstr "Thời gian turbo" + +msgid "Check BPB" +msgstr "Kiểm tra BPB" + +msgid "CD-ROM drives:" +msgstr "Ổ đĩa CD-ROM:" + +msgid "MO drives:" +msgstr "Ổ đĩa MO:" + +msgid "ZIP drives:" +msgstr "Ổ đĩa ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Mở rộng bộ nhớ qua ISA" + +msgid "Card 1:" +msgstr "Thẻ 1:" + +msgid "Card 2:" +msgstr "Thẻ 2:" + +msgid "Card 3:" +msgstr "Thẻ 3:" + +msgid "Card 4:" +msgstr "Thẻ 4:" + +msgid "ISABugger device" +msgstr "Thiết bị ISABugger" + +msgid "POST card" +msgstr "Thẻ POST" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Lỗi" + +msgid "Fatal error" +msgstr "Lỗi nghiêm trọng" + +msgid " - PAUSED" +msgstr " - TẠM DỪNG" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." + +msgid "Speed" +msgstr "Vận tốc" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Ảnh đĩa 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 không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." + +msgid "(empty)" +msgstr "(trống trơn)" + +msgid "All files" +msgstr "Tất cả file" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Bật" + +msgid "Off" +msgstr "Tắt" + +msgid "All images" +msgstr "Tất cả ảnh" + +msgid "Basic sector images" +msgstr "Ảnh sector cơ bản" + +msgid "Surface images" +msgstr "Ảnh bề mặt" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." + +msgid "Machine" +msgstr "Mẫu máy" + +msgid "Display" +msgstr "Hiển thị" + +msgid "Input devices" +msgstr "Thiết bị nhập" + +msgid "Sound" +msgstr "Thanh âm" + +msgid "Network" +msgstr "Nối mạng" + +msgid "Ports (COM & LPT)" +msgstr "Cổng (COM và LPT)" + +msgid "Storage controllers" +msgstr "Vi điều khiển bộ nhớ ổ cứng" + +msgid "Hard disks" +msgstr "Ổ cứng" + +msgid "Floppy & CD-ROM drives" +msgstr "Ổ (đĩa) mềm và CD-ROM" + +msgid "Other removable devices" +msgstr "Thiết bị tháo rời được khác" + +msgid "Other peripherals" +msgstr "Thiết bị ngoại vi khác" + +msgid "Click to capture mouse" +msgstr "Bấm để capture ('nhốt') chuột vào" + +msgid "Press %1 to release mouse" +msgstr "Nhấn %1 để thả chuột" + +msgid "Press %1 or middle button to release mouse" +msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." + +msgid "Default" +msgstr "Mặc định" + +msgid "%i Wait state(s)" +msgstr "%i trạng thái chờ" + +msgid "Type" +msgstr "Loại" + +msgid "No PCap devices found" +msgstr "Không tìm thấy thiết bị PCap" + +msgid "Invalid PCap device" +msgstr "Thiết bị PCap không hợp quy" + +msgid "Standard 2-button joystick(s)" +msgstr "Cần điều khiển hai nút tiêu chuẩn" + +msgid "Standard 4-button joystick" +msgstr "Cần điều khiển bốn nút tiêu chuẩn" + +msgid "Standard 6-button joystick" +msgstr "Cần điều khiển sáu nút tiêu chuẩn" + +msgid "Standard 8-button joystick" +msgstr "Cần điều khiển tám nút tiêu chuẩn" + +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 "Không có" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Đĩa mềm %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Ảnh (đĩa) sector nâng cao" + +msgid "Flux images" +msgstr "Ảnh thông lượng (flux)" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Bạn có thật sự buộc máy khởi động lại không?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Bạn có muốn thoát 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Không thể khởi tạo Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Ảnh đĩa MO" + +msgid "Welcome to 86Box!" +msgstr "Chào mừng đến 86Box!" + +msgid "Internal controller" +msgstr "Vi điều khiển nội bộ" + +msgid "Exit" +msgstr "Thoát" + +msgid "No ROMs found" +msgstr "Không tìm thấy ROM" + +msgid "Do you want to save the settings?" +msgstr "Bạn có muốn lưu cài đặt không?" + +msgid "This will hard reset the emulated machine." +msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." + +msgid "Save" +msgstr "Lưu" + +msgid "About 86Box" +msgstr "Về 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." + +msgid "Hardware not available" +msgstr "Phần cứng không có sẵn" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." + +msgid "Invalid configuration" +msgstr "Tinh chỉnh không hợp lý" + +msgid "%1 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 "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Đang tiến vào chế độ toàn màn hình" + +msgid "Don't show this message again" +msgstr "Không hiện thông báo này nữa" + +msgid "Don't exit" +msgstr "Không thoát" + +msgid "Reset" +msgstr "Khởi động lại" + +msgid "Don't reset" +msgstr "Không khởi động lại" + +msgid "CD-ROM images" +msgstr "Ảnh đĩa CD-ROM" + +msgid "%1 Device Configuration" +msgstr "Tinh chỉnh thiết bị %1" + +msgid "Monitor in sleep mode" +msgstr "Màn hình chế độ chờ/ngủ" + +msgid "OpenGL Shaders" +msgstr "Shader OpenGL" + +msgid "OpenGL options" +msgstr "Tùy chọn OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." + +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 "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." + +msgid "Continue" +msgstr "Tiếp tục" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Ảnh đĩa Cassette" + +msgid "Cartridge %i: %ls" +msgstr "Băng cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Ảnh đĩa băng cartridge" + +msgid "Error initializing renderer" +msgstr "Lỗi khởi tạo renderer (trình kết xuất)" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." + +msgid "Resume execution" +msgstr "Tiếp tục chạy thực thi" + +msgid "Pause execution" +msgstr "Dừng chạy thực thi" + +msgid "Press Ctrl+Alt+Del" +msgstr "Nhấn Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Nhấn Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Buộc khởi động lại" + +msgid "ACPI shutdown" +msgstr "Tắt máy theo ACPI" + +msgid "Hard disk (%1)" +msgstr "Ổ cứng (%1)" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" + +msgid "Custom..." +msgstr "Tùy chỉnh..." + +msgid "Custom (large)..." +msgstr "Tùy chỉnh (dung tích lớn)..." + +msgid "Add New Hard Disk" +msgstr "Thêm ổ cứng mới" + +msgid "Add Existing Hard Disk" +msgstr "Thêm ổ cứng đã có" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Ảnh đĩa không to hơn 127 GB." + +msgid "Hard disk images" +msgstr "Ảnh đĩa ổ cứng" + +msgid "Unable to read file" +msgstr "Không đọc được file" + +msgid "Unable to write file" +msgstr "Không ghi được vào file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." + +msgid "Disk image file already exists" +msgstr "Đã có file ảnh đĩa rồi" + +msgid "Please specify a valid file name." +msgstr "Vui lòng đặt tên hợp lệ." + +msgid "Disk image created" +msgstr "Đã tạo ảnh đĩa" + +msgid "Make sure the file exists and is readable." +msgstr "Chắc chắn rằng file tồn tại và đọc được." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." + +msgid "Disk image too large" +msgstr "Ảnh đĩa quá to" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" + +msgid "Unsupported disk image" +msgstr "File ảnh đĩa không được hỗ trợ" + +msgid "Overwrite" +msgstr "Có ghi đè" + +msgid "Don't overwrite" +msgstr "Không ghi đè" + +msgid "Raw image (.img)" +msgstr "Ảnh đĩa thô (.img)" + +msgid "HDI image (.hdi)" +msgstr "Ảnh đĩa HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Ảnh đĩa HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước cố định (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước tăng dần (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Bloc lớn (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Bloc bé (512 KB)" + +msgid "VHD files" +msgstr "File VHD" + +msgid "Select the parent VHD" +msgstr "Chọn file VHD cha (parent)" + +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 "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" + +msgid "Could not fix VHD timestamp." +msgstr "Không thể sửa mốc timestamp cho VHD." + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +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 "Số RPM(vòng quay đĩa/phút) hoàn thiện" + +msgid "1% below perfect RPM" +msgstr "1% thấp hơn số RPM hoàn thiện" + +msgid "1.5% below perfect RPM" +msgstr "1.5% thấp hơn số RPM hoàn thiện" + +msgid "2% below perfect RPM" +msgstr "2% thấp hơn số RPM hoàn thiện" + +msgid "(System Default)" +msgstr "(Mặc định hệ thống)" + +msgid "Failed to initialize network driver" +msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" + +msgid "The network configuration will be switched to the null driver" +msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" + +msgid "Mouse sensitivity:" +msgstr "Độ nhạy chuột:" + +msgid "Select media images from program working directory" +msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" + +msgid "PIT mode:" +msgstr "Chế độ PIT:" + +msgid "Auto" +msgstr "Tự động" + +msgid "Slow" +msgstr "Chậm" + +msgid "Fast" +msgstr "Nhanh" + +msgid "&Auto-pause on focus loss" +msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" + +msgid "WinBox is no longer supported" +msgstr "WinBox không còn được hỗ trợ" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." From 7ed68413568f4cbf02cfebec1ae8275f6387b1a1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:22:36 +0500 Subject: [PATCH 463/690] Hook up the new translation --- src/qt/qt_platform.cpp | 1 + src/qt/qt_translations.qrc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 275d1df2e..e0b11ad7b 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -455,6 +455,7 @@ QMap> ProgSettings::lcid_langcode = { { 0x0C0A, { "es-ES", "Spanish (Spain, Modern Sort)" } }, { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, + { 0x042A, { "vi-VN", "Vietnamese (Vietnam)" } }, { 0xFFFF, { "system", "(System Default)" } }, }; } diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 017354f82..9f75fd6d6 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc @@ -21,6 +21,7 @@ 86box_sl-SI.qm 86box_tr-TR.qm 86box_uk-UA.qm + 86box_vi-VN.qm 86box_zh-CN.qm 86box_zh-TW.qm From 15b3c44cb7cbe002dd83e507f41292ee451bcbe6 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:58:32 +0500 Subject: [PATCH 464/690] Update .gitattributes Declare CMake scripts, Windows resource scripts and manifests, .po translation files and Qt XML files as text --- .gitattributes | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitattributes b/.gitattributes index 32eb262c9..9b39a29c0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,12 +3,28 @@ # Explicitly declare text files you want to always be normalized and converted # to native line endings on checkout. +# Code *.c text *.cc text *.cpp text *.h text *.hpp text + +# CMake scripts +CMakeLists.txt text +*.cmake text + +# Windows resource scripts and manifests *.rc text +*.manifest text + +# Translation files +*.po text + +# Qt XML files +*.ui text +*.ts text +*.qrc text # Declare files that will always have CRLF line endings on checkout. From 56f7030c98172b7b96b05e2c4e05dbe6cebedd1f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 00:23:08 +0200 Subject: [PATCH 465/690] IDE clean-ups. --- src/disk/hdc_ide.c | 519 +++++++++++++++------------------------------ 1 file changed, 170 insertions(+), 349 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 428804b5a..d203a52e8 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -91,15 +91,15 @@ #define WIN_SET_MULTIPLE_MODE 0xc6 #define WIN_READ_DMA 0xc8 #define WIN_READ_DMA_ALT 0xc9 -#define WIN_WRITE_DMA 0xcA -#define WIN_WRITE_DMA_ALT 0xcB +#define WIN_WRITE_DMA 0xca +#define WIN_WRITE_DMA_ALT 0xcb #define WIN_STANDBYNOW1 0xe0 #define WIN_IDLENOW1 0xe1 #define WIN_SETIDLE1 0xe3 #define WIN_CHECKPOWERMODE1 0xe5 #define WIN_SLEEP1 0xe6 -#define WIN_IDENTIFY 0xeC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xeF +#define WIN_IDENTIFY 0xec /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xef #define WIN_READ_NATIVE_MAX 0xf8 #define FEATURE_SET_TRANSFER_MODE 0x03 @@ -377,7 +377,7 @@ ide_atapi_get_period(uint8_t channel) ide_log("ide_atapi_get_period(%i)\n", channel); - if (!ide) { + if (ide == NULL) { ide_log("Get period failed\n"); return -1.0; } @@ -411,7 +411,7 @@ ide_irq_update(ide_board_t *dev, int log) void ide_irq(ide_t *ide, int set, int log) { - if (!ide_boards[ide->board]) + if (ide_boards[ide->board] == NULL) return; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) @@ -437,7 +437,7 @@ ide_irq(ide_t *ide, int set, int log) * this length will be padded with spaces. */ void -ide_padstr(char *str, const char *src, int len) +ide_padstr(char *str, const char *src, const int len) { int v; @@ -471,37 +471,39 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src) } static int -ide_get_max(ide_t *ide, int type) +ide_is_ata4(const ide_board_t *board) { - int ret = -1; - ide_bm_t *bm = ide_boards[ide->board]->bm; - int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); - int max[2][4] = { { 0, -1, -1, -1 }, { 4, 2, 2, 5 } }; + const ide_bm_t *bm = board->bm; + + return (!board->force_ata3 && (bm != NULL)); +} + +static int +ide_get_max(const ide_t *ide, const int type) +{ + const int ata_4 = ide_is_ata4(ide_boards[ide->board]); + const int max[2][4] = { { 0, -1, -1, -1 }, { 4, 2, 2, 5 } }; + int ret; if (ide->type == IDE_ATAPI) ret = ide->get_max(!IDE_ATAPI_IS_EARLY && ata_4, type); - else if (type <= TYPE_UDMA) - ret = max[ata_4][type]; else - fatal("Unknown transfer type: %i\n", type); + ret = max[ata_4][type]; return ret; } static int -ide_get_timings(ide_t *ide, int type) +ide_get_timings(const ide_t *ide, const int type) { - int ret = 0; - ide_bm_t *bm = ide_boards[ide->board]->bm; - int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); - int timings[2][3] = { { 0, 0, 0 }, { 120, 120, 0 } }; + const int ata_4 = ide_is_ata4(ide_boards[ide->board]); + const int timings[2][3] = { { 0, 0, 0 }, { 120, 120, 0 } }; + int ret; if (ide->type == IDE_ATAPI) ret = ide->get_timings(!IDE_ATAPI_IS_EARLY && ata_4, type); - else if (type <= TIMINGS_PIO_FC) - ret = timings[ata_4][type]; else - fatal("Unknown transfer type: %i\n", type); + ret = timings[ata_4][type]; return ret; } @@ -510,22 +512,20 @@ ide_get_timings(ide_t *ide, int type) * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command */ static void -ide_hd_identify(ide_t *ide) +ide_hd_identify(const ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - ide_bm_t *bm = ide_boards[ide->board]->bm; - + const ide_bm_t *bm = ide_boards[ide->board]->bm; + const uint32_t d_spt = ide->spt; + uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * + hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); uint32_t d_hpc; - uint32_t d_spt; uint32_t d_tracks; - uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * - hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); - d_spt = ide->spt; if (ide->hpc <= 16) { /* HPC <= 16, report as needed. */ d_tracks = ide->tracks; @@ -973,7 +973,7 @@ ide_atapi_attach(ide_t *ide) void ide_set_callback(ide_t *ide, double callback) { - if (!ide) { + if (ide == NULL) { ide_log("ide_set_callback(NULL): Set callback failed\n"); return; } @@ -993,7 +993,7 @@ ide_set_board_callback(uint8_t board, double callback) ide_log("ide_set_board_callback(%i)\n", board); - if (!dev) { + if (dev == NULL) { ide_log("Set board callback failed\n"); return; } @@ -1086,13 +1086,15 @@ ide_atapi_callback(ide_t *ide) /* Else, DMA command without a bus master, ret = 0 (default). */ switch (ret) { + default: + break; case 0: if (ide->bus_master_error) ide->bus_master_error(ide->sc); break; case 1: if (out && ide->phase_data_out) - ret = ide->phase_data_out(ide->sc); + (void) ide->phase_data_out(ide->sc); else if (!out && ide->command_stop) ide->command_stop(ide->sc); @@ -1154,7 +1156,7 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) } static uint16_t -ide_atapi_packet_read(ide_t *ide, int length) +ide_atapi_packet_read(ide_t *ide) { scsi_common_t *dev = ide->sc; const uint16_t *bufferw; @@ -1170,15 +1172,10 @@ ide_atapi_packet_read(ide_t *ide, int length) we're transferring bytes beyond it, which can happen when issuing media access commands with an allocated length below minimum request length (which is 1 sector = 2048 bytes). */ - if (length == 2) { - ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; - ide->tf->pos += 2; - dev->request_pos += 2; - } else { - ret = (ide->tf->pos < dev->packet_len) ? dev->temp_buffer[ide->tf->pos] : 0; - ide->tf->pos++; - dev->request_pos++; - } + ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; + ide->tf->pos += 2; + + dev->request_pos += 2; if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { /* Time for a DRQ. */ @@ -1190,7 +1187,7 @@ ide_atapi_packet_read(ide_t *ide, int length) } static void -ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) +ide_atapi_packet_write(ide_t *ide, const uint16_t val) { scsi_common_t *dev = ide->sc; @@ -1207,15 +1204,10 @@ ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) } if ((bufferb != NULL) && (dev->packet_status != PHASE_DATA_IN)) { - if (length == 2) { - bufferw[ide->tf->pos >> 1] = val & 0xffff; - ide->tf->pos += 2; - dev->request_pos += 2; - } else { - bufferb[ide->tf->pos] = val & 0xff; - ide->tf->pos++; - dev->request_pos++; - } + bufferw[ide->tf->pos >> 1] = val & 0xffff; + + ide->tf->pos += 2; + dev->request_pos += 2; if (dev->packet_status == PHASE_DATA_OUT) { if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { @@ -1234,32 +1226,26 @@ ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) } static void -ide_write_data(ide_t *ide, uint16_t val, int length) +ide_write_data(ide_t *ide, const uint16_t val) { - uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; if ((ide->type != IDE_NONE) && !(ide->type & IDE_SHADOW) && ide->buffer) { if (ide->command == WIN_PACKETCMD) { if (ide->type == IDE_ATAPI) - ide_atapi_packet_write(ide, val, length); + ide_atapi_packet_write(ide, val); else ide->tf->pos = 0; } else { - if (length == 2) { - idebufferw[ide->tf->pos >> 1] = val & 0xffff; - ide->tf->pos += 2; - } else { - idebufferb[ide->tf->pos] = val & 0xff; - ide->tf->pos++; - } + idebufferw[ide->tf->pos >> 1] = val & 0xffff; + ide->tf->pos += 2; if (ide->tf->pos >= 512) { ide->tf->pos = 0; ide->tf->atastat = BSY_STAT; - double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - double wait_time = seek_time + xfer_time; + const double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + const double xfer_time = ide_get_xfer_time(ide, 512); + const double wait_time = seek_time + xfer_time; if (ide->command == WIN_WRITE_MULTIPLE) { if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); @@ -1297,7 +1283,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val, 2); + ide_write_data(ide, val); break; case 0x7: ide_writeb(addr, val & 0xff, priv); @@ -1331,9 +1317,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val & 0xffff, 2); + ide_write_data(ide, val & 0xffff); if (dev->bit32) - ide_write_data(ide, val >> 16, 2); + ide_write_data(ide, val >> 16); else ide_writew(addr + 2, (val >> 16) & 0xffff, priv); break; @@ -1487,7 +1473,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type != IDE_NONE) || ((addr != 0x0) && (addr != 0x7))) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val | (val << 8), 2); + ide_write_data(ide, val | (val << 8)); break; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ @@ -1605,8 +1591,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->tf->error = 0; switch (val) { - case WIN_RECAL ... 0x1F: - case WIN_SEEK ... 0x7F: + case WIN_RECAL ... 0x1f: + case WIN_SEEK ... 0x7f: if (ide->type == IDE_ATAPI) ide->tf->atastat = DRDY_STAT; else @@ -1655,7 +1641,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) uint32_t sec_count; double wait_time; if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - /* TODO make DMA timing more accurate */ + /* TODO: Make DMA timing more accurate. */ sec_count = ide->tf->secount ? ide->tf->secount : 256; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); @@ -1818,39 +1804,28 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } static uint16_t -ide_read_data(ide_t *ide, int length) +ide_read_data(ide_t *ide) { - const uint8_t *idebufferb = (uint8_t *) ide->buffer; const uint16_t *idebufferw = ide->buffer; - uint16_t ret = 0; - double seek_us; - double xfer_us; + uint16_t ret = 0x0000; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel, ide->board, ide->type); #endif - if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || !ide->buffer) { - if (length == 2) - ret = 0xff7f; - else - ret = 0x7f; - } else if (ide->command == WIN_PACKETCMD) { + if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || (ide->buffer == NULL)) + ret = 0xff7f; + else if (ide->command == WIN_PACKETCMD) { if (ide->type == IDE_ATAPI) - ret = ide_atapi_packet_read(ide, length); + ret = ide_atapi_packet_read(ide); else { ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos); ide->tf->pos = 0; } } else { - if (length == 2) { - ret = idebufferw[ide->tf->pos >> 1]; - ide->tf->pos += 2; - } else { - ret = idebufferb[ide->tf->pos]; - ide->tf->pos++; - } + ret = idebufferw[ide->tf->pos >> 1]; + ide->tf->pos += 2; if (ide->tf->pos >= 512) { ide->tf->pos = 0; @@ -1861,6 +1836,7 @@ ide_read_data(ide_t *ide, int length) if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || (ide->command == WIN_READ_MULTIPLE)) { + ide->tf->secount--; if (ide->tf->secount) { @@ -1872,16 +1848,16 @@ ide_read_data(ide_t *ide, int length) ide->tf->secount : 256; if (cnt > ide->blocksize) cnt = ide->blocksize; - seek_us = hdd_timing_read(&hdd[ide->hdd_num], - ide_get_sector(ide), cnt); - xfer_us = ide_get_xfer_time(ide, 512 * cnt); + const double seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), cnt); + const double xfer_us = ide_get_xfer_time(ide, 512 * cnt); ide_set_callback(ide, seek_us + xfer_us); } else ide_callback(ide); } else { - seek_us = hdd_timing_read(&hdd[ide->hdd_num], - ide_get_sector(ide), 1); - xfer_us = ide_get_xfer_time(ide, 512); + const double seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), 1); + const double xfer_us = ide_get_xfer_time(ide, 512); ide_set_callback(ide, seek_us + xfer_us); } } else @@ -1931,7 +1907,7 @@ ide_readb(uint16_t addr, void *priv) switch (addr & 0x7) { case 0x0: /* Data */ - ret = ide_read_data(ide, 2) & 0xff; + ret = ide_read_data(ide) & 0xff; break; /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), @@ -2012,53 +1988,45 @@ ide_readb(uint16_t addr, void *priv) } ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint8_t -ide_read_alt_status(UNUSED(uint16_t addr), void *priv) +ide_read_alt_status(UNUSED(const uint16_t addr), void *priv) { - uint8_t ret = 0xff; - const ide_board_t *dev = (ide_board_t *) priv; - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; /* Per the Seagate ATA-3 specification: Reading the alternate status does *NOT* clear the IRQ. */ - ret = ide_status(ide, ide_drives[ch ^ 1], ch); + const uint8_t ret = ide_status(ide, ide_drives[ch ^ 1], ch); ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint16_t ide_readw(uint16_t addr, void *priv) { - uint16_t ret = 0xffff; - const ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; + uint16_t ret; switch (addr & 0x7) { + default: + ret = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); + break; case 0x0: /* Data */ - ret = ide_read_data(ide, 2); + ret = ide_read_data(ide); break; case 0x7: ret = ide_readb(addr, priv) | 0xff00; break; - default: - ret = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); - break; } #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) @@ -2070,20 +2038,16 @@ ide_readw(uint16_t addr, void *priv) static uint32_t ide_readl(uint16_t addr, void *priv) { - ide_t *ide; - int ch; - uint32_t ret = 0xffffffff; - const ide_board_t *dev = (ide_board_t *) priv; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; + uint32_t ret; switch (addr & 0x7) { case 0x0: /* Data */ - ret = ide_read_data(ide, 2); + ret = ide_read_data(ide); if (dev->bit32) - ret |= (ide_read_data(ide, 2) << 16); + ret |= (ide_read_data(ide) << 16); else ret |= (ide_readw(addr + 2, priv) << 16); break; @@ -2148,12 +2112,11 @@ atapi_error_no_ready(ide_t *ide) static void ide_callback(void *priv) { - int snum; - int ret = 0; - uint8_t err = 0x00; - int chk_chs = 0; - ide_t *ide = (ide_t *) priv; - ide_bm_t *bm = ide_boards[ide->board]->bm; + ide_t * ide = (ide_t *) priv; + const ide_bm_t *bm = ide_boards[ide->board]->bm; + int chk_chs; + int ret; + uint8_t err = 0x00; ide_log("ide_callback(%i): %02X\n", ide->channel, ide->command); @@ -2187,7 +2150,7 @@ ide_callback(void *priv) Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, Cylinder Low = 14h, Cylinder High = EBh and Drive/Head = 00h. */ case WIN_SRST: /*ATAPI Device Reset */ - ide->tf->error = 1; /*Device passed*/ + ide->tf->error = 1; /*Device passed*/ ide->tf->secount = 1; ide->tf->sector = 1; @@ -2269,7 +2232,7 @@ ide_callback(void *priv) ide->tf->pos = 0; - if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + if (!ide_boards[ide->board]->force_ata3 && bm->dma) { /* We should not abort - we should simply wait for the host to start DMA. */ ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv); if (ret == 2) { @@ -2365,7 +2328,7 @@ ide_callback(void *priv) ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); err = IDNF_ERR; } else { - if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + if (!ide_boards[ide->board]->force_ata3 && bm->dma) { if (ide->tf->secount) ide->sector_pos = ide->tf->secount; else @@ -2515,7 +2478,7 @@ ide_callback(void *priv) case WIN_READ_NATIVE_MAX: if (ide->type == IDE_HDD) { - snum = hdd[ide->hdd_num].spt; + int snum = hdd[ide->hdd_num].spt; snum *= hdd[ide->hdd_num].hpc; snum *= hdd[ide->hdd_num].tracks; ide_set_sector(ide, snum - 1); @@ -2725,10 +2688,8 @@ ide_board_close(int board) dev->buffer = NULL; } - if (dev) { - free(dev); - ide_drives[c] = NULL; - } + free(dev); + ide_drives[c] = NULL; } } @@ -2737,19 +2698,12 @@ ide_board_close(int board) } static void -ide_board_setup(int board) +ide_board_setup(const int board) { - ide_t *dev; - int c; - int d; - int ch; - int is_ide; - int valid_ch; - int min_ch; - int max_ch; - - min_ch = (board << 1); - max_ch = min_ch + 1; + const int min_ch = (board << 1); + const int max_ch = min_ch + 1; + int c; + int d; ide_log("IDE: board %i: loading disks...\n", board); for (d = 0; d < 2; d++) { @@ -2759,14 +2713,10 @@ ide_board_setup(int board) c = 0; for (d = 0; d < HDD_NUM; d++) { - is_ide = (hdd[d].bus == HDD_BUS_IDE); - ch = hdd[d].ide_channel; + const int is_ide = (hdd[d].bus == HDD_BUS_IDE); + const int ch = hdd[d].ide_channel; - if (board == 4) { - valid_ch = ((ch >= 0) && (ch <= 1)); - ch |= 8; - } else - valid_ch = ((ch >= min_ch) && (ch <= max_ch)); + const int valid_ch = ((ch >= min_ch) && (ch <= max_ch)); if (is_ide && valid_ch) { ide_log("Found IDE hard disk on channel %i\n", ch); @@ -2780,8 +2730,8 @@ ide_board_setup(int board) ide_log("IDE: board %i: done, loaded %d disks.\n", board, c); for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; + c = (board << 1) + d; + ide_t *dev = ide_drives[c]; if (dev->type == IDE_NONE) continue; @@ -3095,7 +3045,7 @@ ide_close(UNUSED(void *priv)) } static uint8_t -mcide_mca_read(int port, void *priv) +mcide_mca_read(const int port, void *priv) { const mcide_t *dev = (mcide_t *) priv; @@ -3105,196 +3055,67 @@ mcide_mca_read(int port, void *priv) } static void -mcide_mca_write(int port, uint8_t val, void *priv) +mcide_mca_write(const int port, const uint8_t val, void *priv) { - mcide_t *dev = (mcide_t *) priv; + mcide_t *dev = (mcide_t *) priv; + uint16_t bases[4] = { 0x01f0, 0x0170, 0x01e8, 0x0168 }; + int irqs[4] = { 10, 11, 14, 15 }; - ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", - port, val, dev->pos_regs[2], dev->pos_regs[3]); + if ((port >= 0x102) && (dev->pos_regs[port & 7] != val)) { + ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", + port, val, dev->pos_regs[2], dev->pos_regs[3]); - if (port < 0x102) - return; + /* Save the new value. */ + dev->pos_regs[port & 7] = val; - /* Save the new value. */ - dev->pos_regs[port & 7] = val; + mem_mapping_disable(&dev->bios_rom.mapping); + dev->bios_addr = 0x00000000; - io_handler(0, ide_boards[0]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[0]); - io_handler(0, ide_boards[0]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[0]); - io_handler(0, ide_boards[1]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[1]); - io_handler(0, ide_boards[1]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[1]); - mem_mapping_disable(&dev->bios_rom.mapping); + ide_remove_handlers(0); + ide_boards[0]->base[0] = ide_boards[0]->base[1] = 0x0000; - if (dev->pos_regs[2] & 0x80) { - switch ((dev->pos_regs[2] >> 4) & 7) { - case 0: - dev->bios_addr = 0xc0000; - break; - case 1: - dev->bios_addr = 0xc4000; - break; - case 2: - dev->bios_addr = 0xc8000; - break; - case 3: - dev->bios_addr = 0xcc000; - break; - case 4: - dev->bios_addr = 0xd0000; - break; - case 5: - dev->bios_addr = 0xd4000; - break; - case 6: - dev->bios_addr = 0xd8000; - break; - case 7: - dev->bios_addr = 0xd8000; - break; - default: - break; + ide_boards[0]->irq = -1; + + ide_remove_handlers(1); + ide_boards[1]->base[0] = ide_boards[1]->base[1] = 0x0000; + + ide_boards[1]->irq = -1; + + if (dev->pos_regs[2] & 1) { + if (dev->pos_regs[2] & 0x80) + dev->bios_addr = 0x000c0000 + (0x00004000 * (uint32_t) ((dev->pos_regs[2] >> 4) & 0x07)); + + if (dev->pos_regs[3] & 0x08) { + ide_boards[0]->base[0] = bases[dev->pos_regs[3] & 0x03]; + ide_boards[0]->base[1] = bases[dev->pos_regs[3] & 0x03] + 0x0206; + } + + if (dev->pos_regs[3] & 0x80) + ide_boards[0]->irq = irqs[(dev->pos_regs[3] >> 4) & 0x03]; + + if (dev->pos_regs[4] & 0x08) { + ide_boards[1]->base[0] = bases[dev->pos_regs[4] & 0x03]; + ide_boards[1]->base[1] = bases[dev->pos_regs[4] & 0x03] + 0x0206; + } + + if (dev->pos_regs[4] & 0x80) + ide_boards[1]->irq = irqs[(dev->pos_regs[4] >> 4) & 0x03]; + + ide_set_handlers(0); + + ide_set_handlers(1); + + if (dev->bios_addr) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios_addr, 0x00004000); + + /* Say hello. */ + ide_log("McIDE: Primary Master I/O=%03X, Primary IRQ=%02i, " + "Secondary Master I/O=%03X, Secondary IRQ=%02i, " + "BIOS @%05X\n", + ide_boards[0]->base[0], ide_boards[0]->irq, + ide_boards[1]->base[0], ide_boards[1]->irq, + dev->bios_addr); } - } else { - dev->bios_addr = 0; - } - - if (dev->pos_regs[3] & 0x08) { - switch (dev->pos_regs[3] & 3) { - case 0: - ide_boards[0]->base[0] = 0x1f0; - ide_boards[0]->base[1] = 0x3f6; - break; - case 1: - ide_boards[0]->base[0] = 0x170; - ide_boards[0]->base[1] = 0x376; - break; - case 2: - ide_boards[0]->base[0] = 0x1e8; - ide_boards[0]->base[1] = 0x3ee; - break; - case 3: - ide_boards[0]->base[0] = 0x168; - ide_boards[0]->base[1] = 0x36e; - break; - default: - break; - } - } else { - ide_boards[0]->base[0] = 0; - ide_boards[0]->base[1] = 0; - } - - if (dev->pos_regs[3] & 0x80) { - switch (dev->pos_regs[3] & 0x30) { - case 0x00: - ide_boards[0]->irq = 10; - break; - case 0x10: - ide_boards[0]->irq = 11; - break; - case 0x20: - ide_boards[0]->irq = 14; - break; - case 0x30: - ide_boards[0]->irq = 15; - break; - - default: - break; - } - } else - ide_boards[0]->irq = -1; - - if (dev->pos_regs[4] & 0x08) { - switch ((dev->pos_regs[4] & 3)) { - case 0: - ide_boards[1]->base[0] = 0x1f0; - ide_boards[1]->base[1] = 0x3f6; - break; - case 1: - ide_boards[1]->base[0] = 0x170; - ide_boards[1]->base[1] = 0x376; - break; - case 2: - ide_boards[1]->base[0] = 0x1e8; - ide_boards[1]->base[1] = 0x3ee; - break; - case 3: - ide_boards[1]->base[0] = 0x168; - ide_boards[1]->base[1] = 0x36e; - break; - default: - break; - } - } else { - ide_boards[1]->base[0] = 0; - ide_boards[1]->base[1] = 0; - } - - if (dev->pos_regs[4] & 0x80) { - switch (dev->pos_regs[4] & 0x30) { - case 0x00: - ide_boards[1]->irq = 10; - break; - case 0x10: - ide_boards[1]->irq = 11; - break; - case 0x20: - ide_boards[1]->irq = 14; - break; - case 0x30: - ide_boards[1]->irq = 15; - break; - - default: - break; - } - } else - ide_boards[1]->irq = -1; - - if (dev->pos_regs[2] & 1) { - if (ide_boards[0]->base[0] && ide_boards[0]->base[1]) { - io_handler(1, ide_boards[0]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[0]); - io_handler(1, ide_boards[0]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[0]); - } - - if (ide_boards[1]->base[0] && ide_boards[1]->base[1]) { - io_handler(1, ide_boards[1]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[1]); - io_handler(1, ide_boards[1]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[1]); - } - - if (dev->bios_addr) { - mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - dev->bios_addr, 0x4000); - } - - /* Say hello. */ - ide_log("McIDE: Primary Master I/O=%03x, Primary IRQ=%i, Secondary Master I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", - ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); } } @@ -3464,7 +3285,7 @@ const device_t mcide_device = { .name = "MCA McIDE Controller", .internal_name = "ide_mcide", .flags = DEVICE_MCA, - .local = 0, + .local = 3, .init = mcide_init, .close = mcide_close, .reset = mcide_reset, From 3f6126f72dd83e34b01543fa84c259f51027f396 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 01:45:22 +0200 Subject: [PATCH 466/690] Bochs VBE fixes, fixes #4410. --- src/video/vid_bochs_vbe.c | 80 ++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index 603e455d1..a4459ce4c 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -124,6 +124,7 @@ typedef struct bochs_vbe_t { mem_mapping_t linear_mapping; mem_mapping_t linear_mapping_2; + uint32_t ma_latch_old; void * i2c; void * ddc; @@ -322,10 +323,10 @@ bochs_vbe_recalctimings(svga_t* svga) svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1); svga->vblankstart = svga->dispend; /* no vertical overscan. */ svga->rowcount = 0; + svga->hoverride = 1; if (dev->vbe_regs[VBE_DISPI_INDEX_BPP] != 4) { svga->fb_only = 1; svga->adv_flags |= FLAG_NO_SHIFT3; - } else { svga->fb_only = 0; svga->adv_flags &= ~FLAG_NO_SHIFT3; @@ -334,26 +335,29 @@ bochs_vbe_recalctimings(svga_t* svga) svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; if (svga->bpp == 4) { - svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] >> 3; + svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3; svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); } else { - svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * (svga->bpp / 8); + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + - (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); } - - if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > - svga->vram_max) { - dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; - svga->ma_latch = (svga->bpp == 4) ? (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3) : - (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); - if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > - svga->vram_max) { - svga->ma_latch = 0; - dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + if (svga->ma_latch != dev->ma_latch_old) { + if (svga->bpp == 4) { + svga->maback = (svga->maback - (dev->ma_latch_old << 2)) + + (svga->ma_latch << 2); + } else { + svga->maback = (svga->maback - (dev->ma_latch_old)) + + (svga->ma_latch); + dev->ma_latch_old = svga->ma_latch; } } + + if (svga->bpp == 4) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max * 2) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; + else + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max / ((svga->bpp == 15) ? 2 : (svga->bpp / 8))) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; svga->split = 0xffffff; switch (svga->bpp) { @@ -381,6 +385,7 @@ bochs_vbe_recalctimings(svga_t* svga) svga->fb_only = 0; svga->packed_4bpp = 0; svga->adv_flags &= ~FLAG_NO_SHIFT3; + svga->hoverride = 0; } } @@ -417,8 +422,10 @@ bochs_vbe_inw(const uint16_t addr, void *priv) case VBE_DISPI_INDEX_DDC: if (dev->vbe_regs[dev->vbe_index] & (1 << 7)) { ret = dev->vbe_regs[dev->vbe_index] & ((1 << 7) | 0x3); - ret |= i2c_gpio_get_scl(dev->i2c) << 2; - ret |= i2c_gpio_get_sda(dev->i2c) << 3; + if ((ret & 0x01) && i2c_gpio_get_scl(dev->i2c)) + ret |= 0x04; + if ((ret & 0x02) && i2c_gpio_get_sda(dev->i2c)) + ret |= 0x08; } else ret = 0x000f; break; @@ -466,7 +473,30 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) case VBE_DISPI_INDEX_X_OFFSET: case VBE_DISPI_INDEX_Y_OFFSET: dev->vbe_regs[dev->vbe_index] = val; - svga_recalctimings(&dev->svga); + if (dev->vbe_index == VBE_DISPI_INDEX_X_OFFSET || dev->vbe_index == VBE_DISPI_INDEX_Y_OFFSET) { + svga_t *svga = &dev->svga; + if (svga->bpp == 4) { + svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3; + svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); + } else { + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); + svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); + } + if (svga->ma_latch != dev->ma_latch_old) { + if (svga->bpp == 4) { + svga->maback = (svga->maback - (dev->ma_latch_old << 2)) + + (svga->ma_latch << 2); + } else { + svga->maback = (svga->maback - (dev->ma_latch_old)) + + (svga->ma_latch); + dev->ma_latch_old = svga->ma_latch; + } + } + } + else + svga_recalctimings(&dev->svga); break; case VBE_DISPI_INDEX_BANK: @@ -788,6 +818,21 @@ bochs_vbe_init(const device_t *info) 0xc0000, 0x10000, 0xffff, 0x0000, MEM_MAPPING_EXTERNAL); + if (dev->id5_val == VBE_DISPI_ID4) { + /* Patch the BIOS to match the PCI ID. */ + dev->bios_rom.rom[0x010c] = 0xee; + dev->bios_rom.rom[0x8dff] -= (0xee - 0x34); + + dev->bios_rom.rom[0x010d] = 0x80; + dev->bios_rom.rom[0x8dff] -= (0x80 - 0x12); + + dev->bios_rom.rom[0x010e] = 0xef; + dev->bios_rom.rom[0x8dff] -= (0xef - 0x11); + + dev->bios_rom.rom[0x010f] = 0xbe; + dev->bios_rom.rom[0x8dff] -= (0xbe - 0x11); + } + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs); svga_init(info, &dev->svga, dev, dev->vram_size, @@ -826,6 +871,7 @@ bochs_vbe_init(const device_t *info) dev->i2c = i2c_gpio_init("ddc_bochs"); dev->ddc = ddc_init(i2c_gpio_get_bus(dev->i2c)); + dev->svga.packed_chain4 = 1; pci_add_card(PCI_ADD_NORMAL, bochs_vbe_pci_read, bochs_vbe_pci_write, dev, &dev->slot); From 656591d3851d480fc72a186fe7e845499cfb8108 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 11:18:28 +0200 Subject: [PATCH 467/690] The forgotten changes to video/vid_svga.c. --- src/video/vid_svga.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a8bf76505..4632ab85e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1130,9 +1130,9 @@ svga_poll(void *priv) svga->linecountff = 0; svga->sc = 0; - svga->maback += (svga->rowoffset << 3); + svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); if (svga->interlace) - svga->maback += (svga->rowoffset << 3); + svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); svga->maback &= svga->vram_display_mask; svga->ma = svga->maback; @@ -1237,8 +1237,10 @@ svga_poll(void *priv) svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); + if (!(svga->adv_flags & FLAG_NO_SHIFT3)) { + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); + } svga->ca = (svga->ca << 2); if (svga->vsync_callback) @@ -1341,6 +1343,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; svga->conv_16to32 = svga_conv_16to32; + svga->render = svga_render_blank; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; From 2acb11d37c72a027f091df779590a1542f64d787 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 17:02:13 +0200 Subject: [PATCH 468/690] Implemented the Pro Audio Spectrum Plus serial mixer, Pro Audio Spectrum 16 parallel mixer, Pro Audio Spectrum Plus/16 SCSI, ESS ES688, all three ESS PnP AudioDrives, made the wavetables use a separate 44.1 kHz source, and made the Sound Blaster 16 PNP use a proper PNP ROM dump. --- src/86box.c | 18 +- src/config.c | 13 +- src/device.c | 6 + src/dma.c | 1 + src/include/86box/86box.h | 2 + src/include/86box/device.h | 1 + src/include/86box/filters.h | 50 +- src/include/86box/pit.h | 1 + src/include/86box/scsi.h | 10 +- src/include/86box/scsi_ncr5380.h | 8 + src/include/86box/scsi_ncr53c400.h | 62 + src/include/86box/snd_emu8k.h | 6 +- src/include/86box/snd_sb_dsp.h | 19 +- src/include/86box/sound.h | 91 +- src/pit.c | 5 + src/qt/qt_deviceconfig.cpp | 411 +++--- src/qt/qt_deviceconfig.hpp | 6 +- src/qt/qt_harddrive_common.cpp | 10 +- src/qt/qt_machinestatus.cpp | 4 +- src/qt/qt_main.cpp | 15 +- src/qt/qt_mainwindow.cpp | 89 +- src/qt/qt_mainwindow.hpp | 2 +- src/qt/qt_mediamenu.cpp | 66 +- src/qt/qt_rendererstack.cpp | 5 +- src/qt/qt_settings.cpp | 20 + src/qt/qt_settings_bus_tracking.cpp | 45 +- src/qt/qt_settings_bus_tracking.hpp | 6 +- src/qt/qt_settingsfloppycdrom.cpp | 1 + src/qt/qt_settingsotherremovable.cpp | 48 +- src/qt/qt_settingsotherremovable.hpp | 7 + src/qt/qt_settingssound.cpp | 31 +- src/qt/qt_settingsstoragecontrollers.cpp | 4 +- src/qt/qt_ui.cpp | 32 +- src/scsi/scsi.c | 8 +- src/scsi/scsi_ncr5380.c | 46 +- src/scsi/scsi_ncr53c400.c | 177 ++- src/sound/openal.c | 103 +- src/sound/snd_emu8k.c | 23 +- src/sound/snd_lpt_dac.c | 54 +- src/sound/snd_lpt_dss.c | 23 +- src/sound/snd_opl_ymfm.cpp | 48 +- src/sound/snd_optimc.c | 2 +- src/sound/snd_pas16.c | 1461 ++++++++++++++++++++-- src/sound/snd_sb.c | 1426 ++++++++++++++++----- src/sound/snd_sb_dsp.c | 511 ++++---- src/sound/sound.c | 290 +++-- src/sound/xaudio2.c | 76 +- 47 files changed, 4000 insertions(+), 1343 deletions(-) create mode 100644 src/include/86box/scsi_ncr53c400.h diff --git a/src/86box.c b/src/86box.c index 67d0bb165..61b81bbf3 100644 --- a/src/86box.c +++ b/src/86box.c @@ -208,6 +208,11 @@ int do_auto_pause = 0; /* (C) Auto-pa loss */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ +int other_ide_present = 0; /* IDE controllers from non-IDE cards are + present */ +int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are + present */ + /* Statistics. */ extern int mmuflush; extern int readlnum; @@ -1080,18 +1085,22 @@ pc_reset_hard_close(void) /* Close all the memory mappings. */ mem_close(); + suppress_overscan = 0; + /* Turn off timer processing to avoid potential segmentation faults. */ timer_close(); - suppress_overscan = 0; + lpt_devices_close(); + +#ifdef UNCOMMENT_LATER + lpt_close(); +#endif nvr_save(); nvr_close(); mouse_close(); - lpt_devices_close(); - device_close_all(); scsi_device_close_all(); @@ -1132,6 +1141,9 @@ pc_reset_hard_init(void) * modules that are. */ + /* Reset the IDE and SCSI presences */ + other_ide_present = other_scsi_present = 0; + /* Mark ACPI as unavailable */ acpi_enabled = 0; diff --git a/src/config.c b/src/config.c index df0ae1c35..02c1d276a 100644 --- a/src/config.c +++ b/src/config.c @@ -745,7 +745,6 @@ load_ports(void) char *p; char temp[512]; int c; - int d; memset(temp, 0, sizeof(temp)); @@ -768,14 +767,6 @@ load_ports(void) p = ini_section_get_string(cat, temp, "none"); lpt_ports[c].device = lpt_device_get_from_internal_name(p); } - - /* Legacy config compatibility. */ - d = ini_section_get_int(cat, "lpt_enabled", 2); - if (d < 2) { - for (c = 0; c < PARALLEL_MAX; c++) - lpt_ports[c].enabled = d; - } - ini_section_delete_var(cat, "lpt_enabled"); } /* Load "Storage Controllers" section. */ @@ -790,7 +781,7 @@ load_storage_controllers(void) int min = 0; int free_p = 0; - for (c = min; c < SCSI_BUS_MAX; c++) { + for (c = min; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); p = ini_section_get_string(cat, temp, NULL); @@ -2288,7 +2279,7 @@ save_storage_controllers(void) ini_section_delete_var(cat, "scsicard"); - for (c = 0; c < SCSI_BUS_MAX; c++) { + for (c = 0; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); if (scsi_card_current[c] == 0) diff --git a/src/device.c b/src/device.c index 321f105e5..14380f6c5 100644 --- a/src/device.c +++ b/src/device.c @@ -51,6 +51,8 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/device.h> +#include <86box/timer.h> +#include <86box/lpt.h> #include <86box/machine.h> #include <86box/mem.h> #include <86box/rom.h> @@ -345,6 +347,10 @@ device_reset_all(uint32_t match_flags) devices[c]->reset(device_priv[c]); } } + + /* TODO: Actually convert the LPT devices to device_t's. */ + if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI)) + lpt_reset(); } void * diff --git a/src/dma.c b/src/dma.c index ebe75bba6..318c6cda2 100644 --- a/src/dma.c +++ b/src/dma.c @@ -22,6 +22,7 @@ #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" #include "x86.h" diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 3f5f3f2ab..f76d70797 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -149,6 +149,8 @@ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ extern int enable_discord; /* (C) enable Discord integration */ +extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ +extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ extern int fixed_size_x; extern int fixed_size_y; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index bd39a02e4..cc564ceb2 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -57,6 +57,7 @@ #define CONFIG_MIDI_OUT (3 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_SPINNER (4 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_MIDI_IN (5 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MEMORY (6 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_STRING (0 | CONFIG_TYPE_STRING) /* config_get_string() */ #define CONFIG_FNAME (1 | CONFIG_TYPE_STRING) /* config_get_string() */ diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index 0aa1c17f1..d11e79512 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[4][NCoef + 1]; /* output samples */ - static double x[4][NCoef + 1]; /* input samples */ + static double y[5][NCoef + 1]; /* output samples */ + static double x[5][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,7 +395,7 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[4][SB16_NCoef]; +extern double low_fir_sb16_coef[5][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) @@ -422,28 +422,28 @@ low_fir_sb16(int c, int i, double NewSample) return out; } -extern double low_fir_pas16_coef[4][SB16_NCoef]; +extern double low_fir_pas16_coef[SB16_NCoef]; static inline double -low_fir_pas16(int c, int i, double NewSample) +low_fir_pas16(const int i, const double NewSample) { - static double x[4][2][SB16_NCoef + 1]; // input samples - static int pos[4] = { 0, 0, 0, 0 }; - double out = 0.0; + static double x[2][SB16_NCoef + 1]; // input samples + static int pos = 0; + double out = 0.0; int n; /* Calculate the new output */ - x[c][i][pos[c]] = NewSample; + x[i][pos] = NewSample; - for (n = 0; n < ((SB16_NCoef + 1) - pos[c]) && n < SB16_NCoef; n++) - out += low_fir_pas16_coef[c][n] * x[c][i][n + pos[c]]; + for (n = 0; n < ((SB16_NCoef + 1) - pos) && n < SB16_NCoef; n++) + out += low_fir_pas16_coef[n] * x[i][n + pos]; for (; n < SB16_NCoef; n++) - out += low_fir_pas16_coef[c][n] * x[c][i][(n + pos[c]) - (SB16_NCoef + 1)]; + out += low_fir_pas16_coef[n] * x[i][(n + pos) - (SB16_NCoef + 1)]; if (i == 1) { - pos[c]++; - if (pos[c] > SB16_NCoef) - pos[c] = 0; + pos++; + if (pos > SB16_NCoef) + pos = 0; } return out; diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 4129a1093..eb03fd2c9 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -114,6 +114,7 @@ extern double AGPCLK; extern uint64_t PITCONST; extern uint64_t PAS16CONST; extern uint64_t PAS16CONST2; +extern uint64_t PASSCSICONST; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; diff --git a/src/include/86box/scsi.h b/src/include/86box/scsi.h index 376ac79b9..32ad1f912 100644 --- a/src/include/86box/scsi.h +++ b/src/include/86box/scsi.h @@ -22,12 +22,14 @@ #define EMU_SCSI_H /* Configuration. */ -#define SCSI_BUS_MAX 4 /* currently we support up to 4 controllers */ +#define SCSI_CARD_MAX 4 +#define SCSI_BUS_MAX 9 /* currently we support up to 9 controllers: + up to 1 on-board + up to 4x pas plus/16 + up to 4 scsi controllers */ -#define SCSI_ID_MAX 16 /* 16 on wide buses */ -#define SCSI_LUN_MAX 8 /* always 8 */ +#define SCSI_ID_MAX 16 /* 16 on wide buses */ +#define SCSI_LUN_MAX 8 /* always 8 */ -extern int scsi_card_current[SCSI_BUS_MAX]; +extern int scsi_card_current[SCSI_CARD_MAX]; extern int scsi_card_available(int card); #ifdef EMU_DEVICE_H diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index a213e299d..55c3bf3c5 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -88,6 +88,7 @@ typedef struct ncr_t { uint8_t target_id; uint8_t tx_data; uint8_t msglun; + uint8_t irq_state; uint8_t command[20]; uint8_t msgout[4]; @@ -108,10 +109,14 @@ typedef struct ncr_t { int data_pos; int irq; + int simple_pseudo_dma; + + uint32_t block_count; double period; void *priv; + void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -121,10 +126,12 @@ typedef struct ncr_t { extern int ncr5380_cmd_len[8]; extern void ncr5380_irq(ncr_t *ncr, int set_irq); +extern void ncr5380_set_irq(ncr_t *ncr, int irq); extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); +extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H @@ -138,6 +145,7 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif +extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_ncr53c400.h new file mode 100644 index 000000000..9a5315990 --- /dev/null +++ b/src/include/86box/scsi_ncr53c400.h @@ -0,0 +1,62 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NCR 53c400 series of SCSI Host Adapters + * made by NCR. These controllers were designed for the ISA and MCA bus. + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2018 Sarah Walker. + * Copyright 2017-2018 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ + +#ifndef SCSI_NCR53C400_H +#define SCSI_NCR53C400_H + +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[512]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int simple_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + +extern void ncr53c400_simple_write(uint8_t val, void *priv); +extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t ncr53c400_simple_read(void *priv); +extern uint8_t ncr53c400_read(uint32_t addr, void *priv); +extern void ncr53c400_callback(void *priv); + +#endif /*SCSI_NCR53C400_H*/ diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index d226ed8db..4bad23b97 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -390,12 +390,12 @@ typedef struct emu8k_t { int16_t out_r; emu8k_chorus_eng_t chorus_engine; - int32_t chorus_in_buffer[SOUNDBUFLEN]; + int32_t chorus_in_buffer[WTBUFLEN]; emu8k_reverb_eng_t reverb_engine; - int32_t reverb_in_buffer[SOUNDBUFLEN]; + int32_t reverb_in_buffer[WTBUFLEN]; int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[WTBUFLEN * 2]; uint16_t addr; } emu8k_t; diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index a00f512a3..c179fd197 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -4,13 +4,16 @@ #include <86box/fifo.h> /*Sound Blaster Clones, for quirks*/ -#define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ -#define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_ESS_ES1688 3 /* ESS Technology ES1688 */ +#define SB_SUBTYPE_DEFAULT 0 /* Handle as a Creative card */ +#define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /* Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone */ +#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /* Aztech Sound Galaxy Nova 16 Extra / + Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone */ +#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ +#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ +#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) /* Check for future ESS cards here */ +#define IS_NOT_ESS(dsp) ((dsp)->sb_subtype < SB_SUBTYPE_ESS_ES688) /* Check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -51,6 +54,10 @@ typedef struct sb_dsp_t { void *dma_priv; uint8_t sb_read_data[256]; + + uint8_t dma_ff; + int dma_data; + int sb_read_wp; int sb_read_rp; int sb_speaker; @@ -116,6 +123,8 @@ typedef struct sb_dsp_t { int sbenable; int sb_enable_i; + int state; + pc_timer_t output_timer; pc_timer_t input_timer; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 5f04c10fe..9ede638e5 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -39,6 +39,9 @@ extern int sound_gain; #define CD_FREQ FREQ_44100 #define CD_BUFLEN (CD_FREQ / 10) +#define WT_FREQ FREQ_44100 +#define WTBUFLEN (MUSIC_FREQ / 45) + enum { SOUND_NONE = 0, SOUND_INTERNAL @@ -50,7 +53,9 @@ extern int speakval; extern int speakon; extern int sound_pos_global; + extern int music_pos_global; +extern int wavetable_pos_global; extern int sound_card_current[SOUND_CARD_MAX]; @@ -62,6 +67,10 @@ extern void music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv); +extern void wavetable_add_handler(void (*get_buffer)(int32_t *buffer, + int len, void *priv), + void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv); @@ -94,9 +103,10 @@ extern void sound_cd_thread_reset(void); extern void closeal(void); extern void inital(void); -extern void givealbuffer(void *buf); -extern void givealbuffer_music(void *buf); -extern void givealbuffer_cd(void *buf); +extern void givealbuffer(const void *buf); +extern void givealbuffer_music(const void *buf); +extern void givealbuffer_wt(const void *buf); +extern void givealbuffer_cd(const void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv); @@ -113,30 +123,16 @@ extern const device_t acermagic_s20_device; extern const device_t mirosound_pcm10_device; extern const device_t azt1605_device; -/* Ensoniq AudioPCI */ -extern const device_t es1371_device; -extern const device_t es1371_onboard_device; +/* C-Media CMI8x38 */ +extern const device_t cmi8338_device; +extern const device_t cmi8338_onboard_device; +extern const device_t cmi8738_device; +extern const device_t cmi8738_onboard_device; +extern const device_t cmi8738_6ch_onboard_device; /* Creative Labs Game Blaster */ extern const device_t cms_device; -/* Gravis UltraSound and UltraSound Max */ -extern const device_t gus_device; - -/* Pro Audio Spectrum 16 */ -extern const device_t pasplus_device; -extern const device_t pas16_device; - -/* IBM PS/1 Audio Card */ -extern const device_t ps1snd_device; - -/* Tandy PSSJ */ -extern const device_t pssj_device; -extern const device_t pssj_isa_device; - -/* Tandy PSG */ -extern const device_t tndy_device; - /* Creative Labs Sound Blaster */ extern const device_t sb_1_device; extern const device_t sb_15_device; @@ -163,13 +159,6 @@ extern const device_t sb_awe64_value_device; extern const device_t sb_awe64_device; extern const device_t sb_awe64_gold_device; -/* Innovation SSI-2001 */ -extern const device_t ssi2001_device; - -/* Windows Sound System */ -extern const device_t wss_device; -extern const device_t ncr_business_audio_device; - /* Crystal CS423x */ extern const device_t cs4235_device; extern const device_t cs4235_onboard_device; @@ -177,15 +166,43 @@ extern const device_t cs4236b_device; extern const device_t cs4237b_device; extern const device_t cs4238b_device; -/* C-Media CMI8x38 */ -extern const device_t cmi8338_device; -extern const device_t cmi8338_onboard_device; -extern const device_t cmi8738_device; -extern const device_t cmi8738_onboard_device; -extern const device_t cmi8738_6ch_onboard_device; - /* ESS Technology */ +extern const device_t ess_688_device; +extern const device_t ess_ess0100_pnp_device; extern const device_t ess_1688_device; +extern const device_t ess_ess0102_pnp_device; +extern const device_t ess_ess0968_pnp_device; +extern const device_t ess_soundpiper_16_mca_device; +extern const device_t ess_soundpiper_32_mca_device; +extern const device_t ess_chipchat_16_mca_device; + +/* Ensoniq AudioPCI */ +extern const device_t es1371_device; +extern const device_t es1371_onboard_device; + +/* Gravis UltraSound and UltraSound Max */ +extern const device_t gus_device; + +/* IBM PS/1 Audio Card */ +extern const device_t ps1snd_device; + +/* Innovation SSI-2001 */ +extern const device_t ssi2001_device; + +/* Pro Audio Spectrum 16 */ +extern const device_t pasplus_device; +extern const device_t pas16_device; + +/* Tandy PSSJ */ +extern const device_t pssj_device; +extern const device_t pssj_isa_device; + +/* Tandy PSG */ +extern const device_t tndy_device; + +/* Windows Sound System */ +extern const device_t wss_device; +extern const device_t ncr_business_audio_device; #endif diff --git a/src/pit.c b/src/pit.c index 7ae50f413..0816094cb 100644 --- a/src/pit.c +++ b/src/pit.c @@ -49,6 +49,7 @@ double cpuclock; double PITCONSTD; double PAS16CONSTD; double PAS16CONST2D; +double PASSCSICONSTD; double SYSCLK; double isa_timing; double bus_timing; @@ -60,6 +61,7 @@ double AGPCLK; uint64_t PITCONST; uint64_t PAS16CONST; uint64_t PAS16CONST2; +uint64_t PASSCSICONST; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -1222,6 +1224,9 @@ pit_set_clock(uint32_t clock) PAS16CONST2D = (cpuclock / 1008000.0); PAS16CONST2 = (uint64_t) (PAS16CONST2D * (double) (1ULL << 32)); + PASSCSICONSTD = (cpuclock / (28224000.0 / 14.0)); + PASSCSICONST = (uint64_t) (PASSCSICONSTD * (double) (1ULL << 32)); + isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) bus_timing = (cpuclock / (cpu_busspeed / 2)); diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index d2ae70245..def3a4385 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,9 +30,7 @@ #include #include #include -#include #include -#include extern "C" { #include <86box/86box.h> @@ -87,10 +86,15 @@ EnumerateSerialDevices() #ifdef Q_OS_WINDOWS for (int i = 1; i < 256; i++) { devstr[0] = 0; - snprintf(devstr.data(), 1024, "\\\\.\\COM%d", i); - auto handle = CreateFileA(devstr.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0); - auto dwError = GetLastError(); - if (handle != INVALID_HANDLE_VALUE || (handle == INVALID_HANDLE_VALUE && ((dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT)))) { + snprintf(devstr.data(), 1024, R"(\\.\COM%d)", i); + const auto handle = CreateFileA(devstr.data(), + GENERIC_READ | GENERIC_WRITE, 0, + nullptr, OPEN_EXISTING, + 0, nullptr); + const auto dwError = GetLastError(); + if ((handle != INVALID_HANDLE_VALUE) || (dwError == ERROR_ACCESS_DENIED) || + (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || + (dwError == ERROR_SEM_TIMEOUT)) { if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); serialDevices.push_back(QString(devstr)); } @@ -108,233 +112,266 @@ EnumerateSerialDevices() } void -DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) { - DeviceConfig dc(settings); - dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); - int p; - int q; + auto * device_context = static_cast(dc); + const auto * config = static_cast(c); + const QString blank = ""; + int p; + int q; - device_context_t device_context; - device_set_context(&device_context, device, instance); - - auto device_label = new QLabel(device->name); - device_label->setAlignment(Qt::AlignCenter); - dc.ui->formLayout->addRow(device_label); - auto line = new QFrame; - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - dc.ui->formLayout->addRow(line); - const auto *config = device->config; while (config->type != -1) { + const int config_type = config->type & CONFIG_TYPE_MASK; + + /* Ignore options of the wrong class. */ + if (!!(config->type & CONFIG_DEP) != is_dep) + continue; + + /* If this is a BIOS-dependent option and it's BIOS, ignore it. */ + if (!!(config->type & CONFIG_DEP) && (config_type == CONFIG_BIOS)) + continue; + + const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; + + int value = 0; + auto selected = static_cast(blank.toStdString().c_str()); + + switch (config_major_type) { + default: + break; + case CONFIG_TYPE_INT: + value = config_get_int(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_HEX16: + value = config_get_hex16(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_HEX20: + value = config_get_hex20(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_STRING: + selected = config_get_string(device_context->name, const_cast(config->name), + const_cast(config->default_string)); + break; + } + switch (config->type) { + default: + break; case CONFIG_BINARY: - { - auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto *cbox = new QCheckBox(); - cbox->setObjectName(config->name); - cbox->setChecked(value > 0); - dc.ui->formLayout->addRow(config->description, cbox); - break; - } + { + auto *cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + this->ui->formLayout->addRow(config->description, cbox); + break; + } #ifdef USE_RTMIDI case CONFIG_MIDI_OUT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_out_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_out_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_MIDI_IN: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_in_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_in_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } #endif + case CONFIG_INT: case CONFIG_SELECTION: case CONFIG_HEX16: case CONFIG_HEX20: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = 0; - switch (config->type) { - case CONFIG_SELECTION: - selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX16: - selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX20: - selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); - break; - } + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, sel->description, sel->value); - if (selected == sel->value) { - currentIndex = row; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && + (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, sel->description, sel->value); + + if (sel->value == value) + currentIndex = row; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_BIOS: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - char *selected; - selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - q = 0; - for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { - p = 0; - for (int d = 0; d < bios->files_no; d++) - p += !!rom_present(const_cast(bios->files[d])); - if (p == bios->files_no) { - int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) { - currentIndex = row; - } - } - q++; - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_SPINNER: - { - int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto *spinBox = new QSpinBox(); - spinBox->setObjectName(config->name); - spinBox->setMaximum(config->spinner.max); - spinBox->setMinimum(config->spinner.min); - if (config->spinner.step > 0) { - spinBox->setSingleStep(config->spinner.step); - } - spinBox->setValue(value); - dc.ui->formLayout->addRow(config->description, spinBox); - break; - } - case CONFIG_FNAME: - { - auto *fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - auto *fileField = new FileField(); - fileField->setObjectName(config->name); - fileField->setFileName(fileName); - fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); - dc.ui->formLayout->addRow(config->description, fileField); - break; - } - case CONFIG_STRING: - { - auto lineEdit = new QLineEdit; - lineEdit->setObjectName(config->name); - lineEdit->setCursor(Qt::IBeamCursor); - lineEdit->setText(config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string))); - dc.ui->formLayout->addRow(config->description, lineEdit); - break; - } - case CONFIG_SERPORT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = 0; - auto serialDevices = EnumerateSerialDevices(); - char *selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - - Models::AddEntry(model, "None", -1); - for (int i = 0; i < serialDevices.size(); i++) { - int row = Models::AddEntry(model, serialDevices[i], i); - if (selected == serialDevices[i]) { + q = 0; + for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && + (strlen(bios->name) > 0); ++bios) { + p = 0; + for (int d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + const int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) currentIndex = row; - } } - - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + q++; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SPINNER: + { + auto *spinBox = new QSpinBox(); + spinBox->setObjectName(config->name); + spinBox->setMaximum(config->spinner.max); + spinBox->setMinimum(config->spinner.min); + if (config->spinner.step > 0) + spinBox->setSingleStep(config->spinner.step); + spinBox->setValue(value); + this->ui->formLayout->addRow(config->description, spinBox); + break; + } + case CONFIG_FNAME: + { + auto *fileField = new FileField(); + fileField->setObjectName(config->name); + fileField->setFileName(selected); + fileField->setFilter(QString(config->file_filter).left(static_cast(strcspn(config->file_filter, + "|")))); + this->ui->formLayout->addRow(config->description, fileField); + break; + } + case CONFIG_STRING: + { + const auto lineEdit = new QLineEdit; + lineEdit->setObjectName(config->name); + lineEdit->setCursor(Qt::IBeamCursor); + lineEdit->setText(selected); + this->ui->formLayout->addRow(config->description, lineEdit); + break; + } + case CONFIG_SERPORT: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = 0; + auto serialDevices = EnumerateSerialDevices(); + + Models::AddEntry(model, "None", -1); + for (int i = 0; i < serialDevices.size(); i++) { + const int row = Models::AddEntry(model, serialDevices[i], i); + if (selected == serialDevices[i]) + currentIndex = row; + } + + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_MAC: { // QHBoxLayout for the line edit widget and the generate button - auto hboxLayout = new QHBoxLayout(); - auto generateButton = new QPushButton(tr("Generate")); - auto lineEdit = new QLineEdit; + const auto hboxLayout = new QHBoxLayout(); + const auto generateButton = new QPushButton(tr("Generate")); + const auto lineEdit = new QLineEdit; // Allow the line edit to expand and fill available space lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred); lineEdit->setInputMask("HH:HH:HH;0"); lineEdit->setObjectName(config->name); // Display the current or generated MAC in uppercase // When stored it will be converted to lowercase - if (config_get_mac(device_context.name, config->name, config->default_int) & 0xFF000000) { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + if (config_get_mac(device_context->name, config->name, + config->default_int) & 0xFF000000) { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); } else { - auto current_mac = QString(config_get_string(device_context.name, config->name, const_cast(config->default_string))); + auto current_mac = QString(config_get_string(device_context->name, config->name, + const_cast(config->default_string))); lineEdit->setText(current_mac.toUpper()); } // Action for the generate button connect(generateButton, &QPushButton::clicked, [lineEdit] { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); }); hboxLayout->addWidget(lineEdit); hboxLayout->addWidget(generateButton); - dc.ui->formLayout->addRow(config->description, hboxLayout); + this->ui->formLayout->addRow(config->description, hboxLayout); break; } } ++config; } +} + +void +DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +{ + DeviceConfig dc(settings); + dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + + device_context_t device_context; + device_set_context(&device_context, device, instance); + + const auto device_label = new QLabel(device->name); + device_label->setAlignment(Qt::AlignCenter); + dc.ui->formLayout->addRow(device_label); + const auto line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + dc.ui->formLayout->addRow(line); + const _device_config_ *config = device->config; + + dc.ProcessConfig(&device_context, config, false); dc.setFixedSize(dc.minimumSizeHint()); - int res = dc.exec(); - if (res == QDialog::Accepted) { + if (dc.exec() == QDialog::Accepted) { config = device->config; while (config->type != -1) { switch (config->type) { + default: + break; case CONFIG_BINARY: { - auto *cbox = dc.findChild(config->name); + const auto *cbox = dc.findChild(config->name); config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); break; } @@ -408,15 +445,15 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se } QString -DeviceConfig::DeviceName(const _device_ *device, const char *internalName, int bus) +DeviceConfig::DeviceName(const _device_ *device, const char *internalName, const int bus) { - if (QStringLiteral("none") == internalName) { + if (QStringLiteral("none") == internalName) return tr("None"); - } else if (QStringLiteral("internal") == internalName) { + else if (QStringLiteral("internal") == internalName) return tr("Internal controller"); - } else if (device == nullptr) { - return QString(); - } else { + else if (device == nullptr) + return ""; + else { char temp[512]; device_get_name(device, bus, temp); return tr(temp, nullptr, 512); diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp index 1ed24d618..a16c152a6 100644 --- a/src/qt/qt_deviceconfig.hpp +++ b/src/qt/qt_deviceconfig.hpp @@ -20,13 +20,15 @@ class DeviceConfig : public QDialog { public: explicit DeviceConfig(QWidget *parent = nullptr); - ~DeviceConfig(); + ~DeviceConfig() override; - static void ConfigureDevice(const _device_ *device, int instance = 0, Settings *settings = nullptr); + static void ConfigureDevice(const _device_ *device, int instance = 0, + Settings *settings = nullptr); static QString DeviceName(const _device_ *device, const char *internalName, int bus); private: Ui::DeviceConfig *ui; + void ProcessConfig(void *dc, const void *c, bool is_dep); }; #endif // QT_DEVICECONFIG_HPP diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 213ebf07b..e0b0233f1 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -20,6 +20,7 @@ extern "C" { #include <86box/hdd.h> +#include <86box/scsi.h> #include <86box/cdrom.h> } @@ -109,9 +110,16 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT QList channelsInUse; switch (bus) { case HDD_BUS_MFM: + busRows = 2; + busesToCheck.append(HDD_BUS_MFM); + break; case HDD_BUS_XTA: + busRows = 2; + busesToCheck.append(HDD_BUS_XTA); + break; case HDD_BUS_ESDI: busRows = 2; + busesToCheck.append(HDD_BUS_ESDI); break; case HDD_BUS_IDE: busRows = 8; @@ -126,7 +134,7 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT case HDD_BUS_SCSI: shifter = 4; orer = 15; - busRows = 64; + busRows = /*64*/ SCSI_BUS_MAX * SCSI_ID_MAX; subChannelWidth = 2; busesToCheck.append(HDD_BUS_SCSI); break; diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index dee487657..53e875e33 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -272,13 +272,13 @@ MachineStatus::hasCassette() bool MachineStatus::hasIDE() { - return machine_has_flags(machine, MACHINE_IDE_QUAD) > 0; + return (machine_has_flags(machine, MACHINE_IDE_QUAD) > 0) || other_ide_present; } bool MachineStatus::hasSCSI() { - return machine_has_flags(machine, MACHINE_SCSI) > 0; + return (machine_has_flags(machine, MACHINE_SCSI) > 0) || other_scsi_present; } void diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 78eaff5e9..dc8e1970f 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -91,26 +91,23 @@ void qt_set_sequence_auto_mnemonic(bool b); void main_thread_fn() { - uint64_t old_time; - uint64_t new_time; - int drawits; int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); - plat_set_thread_name(NULL, "main_thread_fn"); + plat_set_thread_name(nullptr, "main_thread_fn"); framecountx = 0; // title_update = 1; - old_time = elapsed_timer.elapsed(); - drawits = frames = 0; + uint64_t old_time = elapsed_timer.elapsed(); + int drawits = frames = 0; while (!is_quit && cpu_thread_run) { /* See if it is time to run a frame of code. */ - new_time = elapsed_timer.elapsed(); + const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) drawits = 10; else #endif - drawits += (new_time - old_time); + drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -395,7 +392,7 @@ main(int argc, char *argv[]) plat_pause(0); }); - auto ret = app.exec(); + const auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f4c01b4a2..c48dfd052 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -91,6 +91,7 @@ extern int qt_nvr_save(void); #endif #include +#include #include #include "qt_settings.hpp" @@ -289,14 +290,15 @@ MainWindow::MainWindow(QWidget *parent) resizableonce = true; } if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { - w = (w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); + w = static_cast(w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); - int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + const int modifiedHeight = + static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + menuBar()->height() + (statusBar()->height() * !hide_status_bar) + (ui->toolBar->height() * !hide_tool_bar); - ui->stackedWidget->resize(w, (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.))); + ui->stackedWidget->resize(w, static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.))); setFixedSize(w, modifiedHeight); } }); @@ -306,9 +308,9 @@ MainWindow::MainWindow(QWidget *parent) #ifdef QT_RESIZE_DEBUG qDebug() << "Resize"; #endif - w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + w = static_cast(w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); - int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + int modifiedHeight = static_cast(h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); renderers[monitor_index]->setFixedSize(w, modifiedHeight); } @@ -394,9 +396,7 @@ MainWindow::MainWindow(QWidget *parent) ui->actionVulkan->setVisible(false); } - QActionGroup *actGroup = nullptr; - - actGroup = new QActionGroup(this); + auto actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); actGroup->addAction(ui->actionHardware_Renderer_OpenGL); actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); @@ -418,6 +418,8 @@ MainWindow::MainWindow(QWidget *parent) #endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; switch (vid_api) { + default: + break; case 0: newVidApi = RendererStack::Renderer::Software; break; @@ -457,7 +459,7 @@ MainWindow::MainWindow(QWidget *parent) }); /* Trigger initial renderer switch */ - for (auto action : actGroup->actions()) + for (const auto action : actGroup->actions()) if (action->property("vid_api").toInt() == vid_api) { action->setChecked(true); emit actGroup->triggered(action); @@ -465,6 +467,8 @@ MainWindow::MainWindow(QWidget *parent) } switch (scale) { + default: + break; case 0: ui->action0_5x->setChecked(true); break; @@ -508,6 +512,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->action7x); actGroup->addAction(ui->action8x); switch (video_filter_method) { + default: + break; case 0: ui->actionNearest->setChecked(true); break; @@ -519,6 +525,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionNearest); actGroup->addAction(ui->actionLinear); switch (video_fullscreen_scale) { + default: + break; case FULLSCR_SCALE_FULL: ui->actionFullScreen_stretch->setChecked(true); break; @@ -542,6 +550,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionFullScreen_int); actGroup->addAction(ui->actionFullScreen_int43); switch (video_grayscale) { + default: + break; case 0: ui->actionRGB_Color->setChecked(true); break; @@ -565,6 +575,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionWhite_monitor); actGroup->addAction(ui->actionRGB_Color); switch (video_graytype) { + default: + break; case 0: ui->actionBT601_NTSC_PAL->setChecked(true); break; @@ -722,7 +734,7 @@ MainWindow::closeEvent(QCloseEvent *event) if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); @@ -771,7 +783,7 @@ void MainWindow::initRendererMonitorSlot(int monitor_index) { auto &secondaryRenderer = this->renderers[monitor_index]; - secondaryRenderer.reset(new RendererStack(nullptr, monitor_index)); + secondaryRenderer = std::make_unique(nullptr, monitor_index); if (secondaryRenderer) { connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] { this->renderers[monitor_index]->show(); @@ -779,9 +791,8 @@ MainWindow::initRendererMonitorSlot(int monitor_index) secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(monitor_index + 1)); - if (vid_resize == 2) { + if (vid_resize == 2) secondaryRenderer->setFixedSize(fixed_size_x, fixed_size_y); - } secondaryRenderer->setWindowIcon(this->windowIcon()); if (show_second_monitors) { secondaryRenderer->show(); @@ -791,9 +802,8 @@ MainWindow::initRendererMonitorSlot(int monitor_index) monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - if (monitor_settings[monitor_index].mon_window_maximized) { + if (monitor_settings[monitor_index].mon_window_maximized) secondaryRenderer->showMaximized(); - } secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); secondaryRenderer->setMouseTracking(true); @@ -877,7 +887,7 @@ MainWindow::on_actionHard_Reset_triggered() QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); questionbox.addButton(tr("Reset"), QMessageBox::AcceptRole); questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + const auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_reset); @@ -921,7 +931,7 @@ MainWindow::on_actionExit_triggered() void MainWindow::on_actionSettings_triggered() { - int currentPause = dopause; + const int currentPause = dopause; plat_pause(1); Settings settings(this); settings.setModal(true); @@ -932,6 +942,8 @@ MainWindow::on_actionSettings_triggered() settings.exec(); switch (settings.result()) { + default: + break; case QDialog::Accepted: pc_reset_hard_close(); settings.save(); @@ -968,6 +980,9 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) /* Apply special cases. */ switch (keycode) { + default: + break; + case 0x54: /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */ /* Send Alt as well. */ if (down) { @@ -1333,18 +1348,18 @@ MainWindow::checkFullscreenHotkey() { if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { /* Signal "exit fullscreen mode". */ - fs_off_signal = 1; + fs_off_signal = true; } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { ui->actionFullscreen->trigger(); - fs_off_signal = 0; + fs_off_signal = false; } if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { /* Signal "enter fullscreen mode". */ - fs_on_signal = 1; + fs_on_signal = true; } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { ui->actionFullscreen->trigger(); - fs_on_signal = 0; + fs_on_signal = false; } } @@ -1699,7 +1714,7 @@ MainWindow::on_actionAbout_86Box_triggered() msgBox.setInformativeText(tr("An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.")); msgBox.setWindowTitle("About 86Box"); msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); - auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); + const auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); webSiteButton->connect(webSiteButton, &QPushButton::released, []() { QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); @@ -1847,8 +1862,8 @@ void MainWindow::on_actionTake_screenshot_triggered() { startblit(); - for (int i = 0; i < MONITORS_NUM; i++) - monitors[i].mon_screenshots++; + for (auto & monitor : monitors) + ++monitor.mon_screenshots; endblit(); device_force_redraw(); } @@ -1869,8 +1884,10 @@ MainWindow::setSendKeyboardInput(bool enabled) void MainWindow::updateUiPauseState() { - auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : QIcon(":/menuicons/qt/icons/pause.ico"); - auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); + const auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : + QIcon(":/menuicons/qt/icons/pause.ico"); + const auto tooltip_text = dopause ? QString(tr("Resume execution")) : + QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); } @@ -1932,9 +1949,7 @@ MainWindow::changeEvent(QEvent *event) void MainWindow::on_actionRenderer_options_triggered() { - auto dlg = ui->stackedWidget->getOptions(this); - - if (dlg) { + if (const auto dlg = ui->stackedWidget->getOptions(this)) { if (dlg->exec() == QDialog::Accepted) { for (int i = 1; i < MONITORS_NUM; i++) { if (renderers[i] && renderers[i]->hasOptions()) @@ -1947,20 +1962,18 @@ MainWindow::on_actionRenderer_options_triggered() void MainWindow::on_actionMCA_devices_triggered() { - auto dlg = new MCADeviceList(this); - - if (dlg) + if (const auto dlg = new MCADeviceList(this)) dlg->exec(); } void MainWindow::on_actionShow_non_primary_monitors_triggered() { - show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); + show_second_monitors = static_cast(ui->actionShow_non_primary_monitors->isChecked()); if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto &secondaryRenderer = renderers[monitor_index]; + const auto &secondaryRenderer = renderers[monitor_index]; if (!renderers[monitor_index]) continue; secondaryRenderer->show(); @@ -1970,8 +1983,8 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); - ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); + secondaryRenderer->switchRenderer(static_cast(vid_api)); + ui->stackedWidget->switchRenderer(static_cast(vid_api)); } } else { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { @@ -1992,7 +2005,7 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() void MainWindow::on_actionOpen_screenshots_folder_triggered() { - QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); + static_cast(QDir(QString(usr_path) + QString("/screenshots/")).mkpath(".")); QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); } @@ -2001,7 +2014,7 @@ MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool { video_fullscreen_scale_maximized = checked; - auto widget = ui->stackedWidget->currentWidget(); + const auto widget = ui->stackedWidget->currentWidget(); ui->stackedWidget->onResize(widget->width(), widget->height()); for (int i = 1; i < MONITORS_NUM; i++) { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 950d145c1..1fca09231 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -73,7 +73,7 @@ private slots: void on_actionCtrl_Alt_Esc_triggered(); void on_actionHard_Reset_triggered(); void on_actionRight_CTRL_is_left_ALT_triggered(); - void on_actionKeyboard_requires_capture_triggered(); + static void on_actionKeyboard_requires_capture_triggered(); void on_actionResizable_window_triggered(bool checked); void on_actionInverted_VGA_monitor_triggered(); void on_action0_5x_triggered(); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index af6d40e79..c4fd50567 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -252,7 +252,7 @@ void MediaMenu::cassetteUpdateMenu() { QString name = cassette_fname; - QString mode = cassette_mode; + const QString mode = cassette_mode; auto childs = cassetteMenu->children(); auto *recordMenu = dynamic_cast(childs[cassetteRecordPos]); auto *playMenu = dynamic_cast(childs[cassettePlayPos]); @@ -266,11 +266,12 @@ MediaMenu::cassetteUpdateMenu() fastFwdMenu->setEnabled(!name.isEmpty()); ejectMenu->setEnabled(!name.isEmpty()); - bool isSaving = mode == QStringLiteral("save"); + const bool isSaving = (mode == QStringLiteral("save")); recordMenu->setChecked(isSaving); playMenu->setChecked(!isSaving); - cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); + cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), + (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); } void @@ -289,7 +290,7 @@ MediaMenu::cartridgeMount(int i, const QString &filename) void MediaMenu::cartridgeSelectImage(int i) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), @@ -314,8 +315,8 @@ MediaMenu::cartridgeEject(int i) void MediaMenu::cartridgeUpdateMenu(int i) { - QString name = cart_fns[i]; - auto *menu = cartridgeMenus[i]; + const QString name = cart_fns[i]; + auto *menu = cartridgeMenus[i]; auto childs = menu->children(); auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); @@ -328,8 +329,10 @@ MediaMenu::floppyNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); + const QByteArray filename = dialog.fileName().toUtf8(); floppyMount(i, filename, false); break; } @@ -516,7 +519,7 @@ MediaMenu::cdromEject(int i) void MediaMenu::cdromReload(int index, int slot) { - QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); + const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); cdromMount(index, filename.toUtf8().constData()); cdromUpdateMenu(index); ui_sb_update_tip(SB_CDROM | index); @@ -572,7 +575,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) return; } - QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + const QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData())); imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty()); imageHistoryUpdatePos->setVisible(fi.exists()); @@ -602,8 +605,8 @@ MediaMenu::cdromUpdateMenu(int i) auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); - QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); - auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + const QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); + const auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageMenu->setIcon(menu_icon); imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData())); @@ -613,15 +616,17 @@ MediaMenu::cdromUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (cdrom[i].bus_type) { + default: + break; case CDROM_BUS_ATAPI: busName = "ATAPI"; break; case CDROM_BUS_SCSI: busName = "SCSI"; break; - case CDROM_BUS_MITSUMI: - busName = "Mitsumi"; - break; + case CDROM_BUS_MITSUMI: + busName = "Mitsumi"; + break; } // menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); @@ -633,6 +638,8 @@ MediaMenu::zipNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: QByteArray filename = dialog.fileName().toUtf8(); zipMount(i, filename, false); @@ -643,7 +650,7 @@ MediaMenu::zipNewImage(int i) void MediaMenu::zipSelectImage(int i, bool wp) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), QString(), @@ -656,7 +663,7 @@ MediaMenu::zipSelectImage(int i, bool wp) void MediaMenu::zipMount(int i, const QString &filename, bool wp) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_close(dev); zip_drives[i].read_only = wp; @@ -676,7 +683,7 @@ MediaMenu::zipMount(int i, const QString &filename, bool wp) void MediaMenu::zipEject(int i) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_close(dev); zip_drives[i].image_path[0] = 0; @@ -694,7 +701,7 @@ MediaMenu::zipEject(int i) void MediaMenu::zipReload(int i) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_reload(dev); if (strlen(zip_drives[i].image_path) == 0) { @@ -712,8 +719,8 @@ MediaMenu::zipReload(int i) void MediaMenu::zipUpdateMenu(int i) { - QString name = zip_drives[i].image_path; - QString prev_name = zip_drives[i].prev_image_path; + const QString name = zip_drives[i].image_path; + const QString prev_name = zip_drives[i].prev_image_path; if (!zipMenus.contains(i)) return; auto *menu = zipMenus[i]; @@ -726,6 +733,8 @@ MediaMenu::zipUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (zip_drives[i].bus_type) { + default: + break; case ZIP_BUS_ATAPI: busName = "ATAPI"; break; @@ -743,6 +752,8 @@ MediaMenu::moNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: QByteArray filename = dialog.fileName().toUtf8(); moMount(i, filename, false); @@ -753,7 +764,7 @@ MediaMenu::moNewImage(int i) void MediaMenu::moSelectImage(int i, bool wp) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), @@ -769,7 +780,7 @@ MediaMenu::moSelectImage(int i, bool wp) void MediaMenu::moMount(int i, const QString &filename, bool wp) { - mo_t *dev = (mo_t *) mo_drives[i].priv; + const auto dev = static_cast(mo_drives[i].priv); mo_disk_close(dev); mo_drives[i].read_only = wp; @@ -789,7 +800,7 @@ MediaMenu::moMount(int i, const QString &filename, bool wp) void MediaMenu::moEject(int i) { - mo_t *dev = (mo_t *) mo_drives[i].priv; + const auto dev = static_cast(mo_drives[i].priv); mo_disk_close(dev); mo_drives[i].image_path[0] = 0; @@ -839,6 +850,8 @@ MediaMenu::moUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (mo_drives[i].bus_type) { + default: + break; case MO_BUS_ATAPI: busName = "ATAPI"; break; @@ -876,6 +889,8 @@ MediaMenu::nicUpdateMenu(int i) QString netType = tr("Null Driver"); switch (net_cards_conf[i].net_type) { + default: + break; case NET_TYPE_SLIRP: netType = "SLiRP"; break; @@ -901,9 +916,10 @@ QString MediaMenu::getMediaOpenDirectory() { QString openDirectory; - if (open_dir_usr_path > 0) { + + if (open_dir_usr_path > 0) openDirectory = QString::fromUtf8(usr_path); - } + return openDirectory; } diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 0f86e8ee6..bc4cb9c13 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -404,7 +404,10 @@ RendererStack::createRenderer(Renderer renderer) void RendererStack::blit(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || + (w > 2048) || (h > 2048) || + (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || + std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index a7e52c342..e9767083a 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -155,8 +155,28 @@ Settings::Settings(QWidget *parent) &SettingsOtherPeripherals::onCurrentMachineChanged); connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, harddisks, &SettingsHarddisks::reloadBusChannels); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); connect(harddisks, &SettingsHarddisks::driveChannelChanged, floppyCdrom, &SettingsFloppyCDROM::reloadBusChannels); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 064fbe0b4..6fb8637da 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -22,6 +22,7 @@ #include #include "86box/hdd.h" +#include "86box/scsi.h" #include "qt_settings_bus_tracking.hpp" SettingsBusTracking::SettingsBusTracking() @@ -30,12 +31,11 @@ SettingsBusTracking::SettingsBusTracking() esdi_tracking = 0x0000000000000000ULL; xta_tracking = 0x0000000000000000ULL; - for (uint8_t i = 0; i < 8; i++) { - if (i < 4) - ide_tracking[i] = 0x0000000000000000ULL; + for (uint8_t i = 0; i < 4; i++) + ide_tracking[i] = 0x0000000000000000ULL; + for (uint8_t i = 0; i < 32; i++) scsi_tracking[i] = 0x0000000000000000ULL; - } } uint8_t @@ -101,7 +101,7 @@ SettingsBusTracking::next_free_scsi_id() uint64_t mask; uint8_t ret = CHANNEL_NONE; - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); @@ -187,7 +187,7 @@ SettingsBusTracking::scsi_bus_full() uint64_t mask; uint8_t count = 0; - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); @@ -204,26 +204,45 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { int element; uint64_t mask; switch (bus) { + case HDD_BUS_MFM: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (mfm_tracking & mask) + channelsInUse.append(i); + } + break; + case HDD_BUS_ESDI: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (esdi_tracking & mask) + channelsInUse.append(i); + } + break; + case HDD_BUS_XTA: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (xta_tracking & mask) + channelsInUse.append(i); + } + break; case HDD_BUS_IDE: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) DEV_HDD) << ((uint64_t) ((i << 3) & 0x3f)); - if (ide_tracking[element] & mask) { + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) channelsInUse.append(i); - } } break; case HDD_BUS_ATAPI: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) DEV_CDROM) << ((uint64_t) ((i << 3) & 0x3f)); - if (ide_tracking[element] & mask) { + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) channelsInUse.append(i); - } } break; case HDD_BUS_SCSI: - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (scsi_tracking[element] & mask) diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 279d3247e..917706428 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -57,8 +57,10 @@ private: uint64_t xta_tracking { 0 }; /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ uint64_t ide_tracking[4] { 0, 0, 0, 0 }; - /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; + /* 9 buses (rounded upwards to 16for future-proofing), 16 devices per bus, + 8 bits per device (future-proofing) = 2048 bits. */ + uint64_t scsi_tracking[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index bb536e603..8f0ac81a9 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -368,6 +368,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) setCDROMType(ui->tableViewCDROM->model(), ui->tableViewCDROM->selectionModel()->currentIndex(), ui->comboBoxCDROMType->currentData().toUInt()); + emit cdromChannelChanged(); } void diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 36918ad99..1a6dceacb 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -201,6 +201,7 @@ SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); ui->comboBoxMOType->setCurrentIndex(type); + enableCurrentlySelectedChannel_MO(); } void @@ -221,6 +222,16 @@ SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); ui->checkBoxZIP250->setChecked(is250); + enableCurrentlySelectedChannel_ZIP(); +} + +void +SettingsOtherRemovable::reloadBusChannels_MO() { + auto selected = ui->comboBoxMOChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), + ui->comboBoxMOBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxMOChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel_MO(); } void @@ -231,7 +242,7 @@ SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) bool enabled = (bus != MO_BUS_DISABLED); ui->comboBoxMOChannel->setEnabled(enabled); ui->comboBoxMOType->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus, Harddrives::busTrackClass); } } @@ -258,6 +269,17 @@ SettingsOtherRemovable::on_comboBoxMOBus_activated(int) Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + emit moChannelChanged(); +} + +void +SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() +{ + const auto *item_model = qobject_cast(ui->comboBoxMOChannel->model()); + const auto index = ui->comboBoxMOChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) + item->setEnabled(true); } void @@ -274,6 +296,7 @@ SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + emit moChannelChanged(); } void @@ -286,6 +309,15 @@ SettingsOtherRemovable::on_comboBoxMOType_activated(int) ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } +void +SettingsOtherRemovable::reloadBusChannels_ZIP() { + auto selected = ui->comboBoxZIPChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), + ui->comboBoxZIPBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxZIPChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel_ZIP(); +} + void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { @@ -294,7 +326,7 @@ SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) bool enabled = (bus != ZIP_BUS_DISABLED); ui->comboBoxZIPChannel->setEnabled(enabled); ui->checkBoxZIP250->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus, Harddrives::busTrackClass); } } @@ -315,6 +347,17 @@ SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + emit zipChannelChanged(); +} + +void +SettingsOtherRemovable::enableCurrentlySelectedChannel_ZIP() +{ + const auto *item_model = qobject_cast(ui->comboBoxZIPChannel->model()); + const auto index = ui->comboBoxZIPChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) + item->setEnabled(true); } void @@ -331,6 +374,7 @@ SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + emit zipChannelChanged(); } void diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index 8b81fb0f0..cea1d202b 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -13,9 +13,14 @@ class SettingsOtherRemovable : public QWidget { public: explicit SettingsOtherRemovable(QWidget *parent = nullptr); ~SettingsOtherRemovable(); + void reloadBusChannels_MO(); + void reloadBusChannels_ZIP(); void save(); +signals: + void moChannelChanged(); + void zipChannelChanged(); private slots: void on_checkBoxZIP250_stateChanged(int arg1); @@ -46,6 +51,8 @@ private slots: private: Ui::SettingsOtherRemovable *ui; + void enableCurrentlySelectedChannel_MO(); + void enableCurrentlySelectedChannel_ZIP(); }; #endif // QT_SETTINGSOTHERREMOVABLE_HPP diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index b4df4ff69..e0572c3d8 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -67,17 +67,17 @@ SettingsSound::save() } void -SettingsSound::onCurrentMachineChanged(int machineId) +SettingsSound::onCurrentMachineChanged(const int machineId) { this->machineId = machineId; - int c = 0; - int selectedRow = 0; + int c; + int selectedRow; for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) { - auto *cbox = findChild(QString("comboBoxSoundCard%1").arg(i + 1)); - auto *model = cbox->model(); - auto removeRows = model->rowCount(); + auto * cbox = findChild(QString("comboBoxSoundCard%1").arg(i + 1)); + auto * model = cbox->model(); + const auto removeRows = model->rowCount(); c = 0; selectedRow = 0; @@ -207,7 +207,7 @@ SettingsSound::on_pushButtonConfigureSoundCard1_clicked() auto *device = sound_card_getdevice(sndCard); if (sndCard == SOUND_INTERNAL) device = machine_get_snd_device(machineId); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 1, qobject_cast(Settings::settings)); } void @@ -225,7 +225,7 @@ SettingsSound::on_pushButtonConfigureSoundCard2_clicked() { int sndCard = ui->comboBoxSoundCard2->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 2, qobject_cast(Settings::settings)); } void @@ -243,7 +243,7 @@ SettingsSound::on_pushButtonConfigureSoundCard3_clicked() { int sndCard = ui->comboBoxSoundCard3->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 3, qobject_cast(Settings::settings)); } void @@ -261,7 +261,7 @@ SettingsSound::on_pushButtonConfigureSoundCard4_clicked() { int sndCard = ui->comboBoxSoundCard4->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 4, qobject_cast(Settings::settings)); } void @@ -278,7 +278,8 @@ SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) void SettingsSound::on_pushButtonConfigureMidiOut_clicked() { - DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, + qobject_cast(Settings::settings)); } void @@ -295,7 +296,8 @@ SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) void SettingsSound::on_pushButtonConfigureMidiIn_clicked() { - DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, + qobject_cast(Settings::settings)); } void @@ -307,9 +309,8 @@ SettingsSound::on_checkBoxMPU401_stateChanged(int state) void SettingsSound::on_pushButtonConfigureMPU401_clicked() { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); - } else { + else DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); - } } diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 0f19d46fc..389e22852 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -52,7 +52,7 @@ void SettingsStorageControllers::save() { /* Storage devices category */ - for (int i = 0; i < SCSI_BUS_MAX; ++i) { + for (int i = 0; i < SCSI_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } @@ -161,7 +161,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxCDInterface->setCurrentIndex(-1); ui->comboBoxCDInterface->setCurrentIndex(selectedRow); - for (int i = 0; i < SCSI_BUS_MAX; ++i) { + for (int i = 0; i < SCSI_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); model = cbox->model(); removeRows = model->rowCount(); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 5412a0e4a..fc111e5b4 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -66,13 +66,13 @@ wchar_t * ui_window_title(wchar_t *str) { if (str == nullptr) { - static wchar_t title[512]; - memset(title, 0, sizeof(title)); + static wchar_t title[512] = { 0 }; + main_window->getTitle(title); str = title; - } else { + } else emit main_window->setTitle(QString::fromWCharArray(str)); - } + return str; } @@ -122,8 +122,10 @@ plat_mouse_capture(int on) int ui_msgbox_header(int flags, void *header, void *message) { - auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); - auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); + const auto hdr = (flags & MBX_ANSI) ? QString(static_cast(header)) : + QString::fromWCharArray(static_cast(header)); + const auto msg = (flags & MBX_ANSI) ? QString(static_cast(message)) : + QString::fromWCharArray(static_cast(message)); // any error in early init if (main_window == nullptr) { @@ -220,9 +222,13 @@ ui_sb_set_ready(int ready) void ui_sb_update_icon_state(int tag, int state) { - int category = tag & 0xfffffff0; - int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; + switch (category) { + default: + break; case SB_CASSETTE: machine_status.cassette.empty = state > 0 ? true : false; break; @@ -247,7 +253,6 @@ ui_sb_update_icon_state(int tag, int state) machine_status.net[item].empty = state > 0 ? true : false; break; case SB_SOUND: - break; case SB_TEXT: break; } @@ -256,11 +261,13 @@ ui_sb_update_icon_state(int tag, int state) void ui_sb_update_icon(int tag, int active) { - int category = tag & 0xfffffff0; - int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; + switch (category) { + default: case SB_CASSETTE: - break; case SB_CARTRIDGE: break; case SB_FLOPPY: @@ -282,7 +289,6 @@ ui_sb_update_icon(int tag, int active) machine_status.net[item].active = active > 0 ? true : false; break; case SB_SOUND: - break; case SB_TEXT: break; } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 328810a2f..aecbcadec 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -42,7 +42,7 @@ #include <86box/scsi_pcscsi.h> #include <86box/scsi_spock.h> -int scsi_card_current[SCSI_BUS_MAX] = { 0, 0, 0, 0 }; +int scsi_card_current[SCSI_CARD_MAX] = { 0, 0, 0, 0 }; double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 }; static uint8_t next_scsi_bus = 0; @@ -169,12 +169,12 @@ scsi_card_get_from_internal_name(char *s) void scsi_card_init(void) { - int max = SCSI_BUS_MAX; + int max = SCSI_CARD_MAX; /* On-board SCSI controllers get the first bus, so if one is present, increase our instance number here. */ - if (machine_has_flags(machine, MACHINE_SCSI)) - max--; + // if (machine_has_flags(machine, MACHINE_SCSI)) + // max--; /* Do not initialize any controllers if we have do not have any SCSI bus left. */ diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d113d2cb3..d256de764 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -68,16 +68,24 @@ void ncr5380_irq(ncr_t *ncr, int set_irq) { if (set_irq) { + ncr->irq_state = 1; ncr->isr |= STATUS_INT; if (ncr->irq != -1) picint(1 << ncr->irq); } else { + ncr->irq_state = 0; ncr->isr &= ~STATUS_INT; if (ncr->irq != 1) picintc(1 << ncr->irq); } } +void +ncr5380_set_irq(ncr_t *ncr, int irq) +{ + ncr->irq = irq; +} + static int ncr5380_get_dev_id(uint8_t data) { @@ -318,6 +326,19 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } + + if (ncr->simple_pseudo_dma) { + if (dev->phase == SCSI_PHASE_DATA_IN) { + ncr->block_count = dev->buffer_length / 512; + + ncr->dma_init_ext(ncr, ncr->priv, 1); + } else if (dev->phase == SCSI_PHASE_DATA_OUT) { + ncr->block_count = dev->buffer_length / 512; + + ncr->dma_init_ext(ncr, ncr->priv, 0); + } + } + ncr->new_phase = dev->phase; } } @@ -337,7 +358,10 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - ncr->timer(ncr->priv, ncr->period); + if (ncr->simple_pseudo_dma) + ncr->dma_init_ext(ncr, ncr->priv, 1); + else + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -364,7 +388,10 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - ncr->timer(ncr->priv, ncr->period); + if (!ncr->simple_pseudo_dma) + ncr->timer(ncr->priv, ncr->period); + if (ncr->simple_pseudo_dma) + ncr->dma_init_ext(ncr, ncr->priv, 0); } else ncr->clear_req = 3; @@ -490,6 +517,21 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } +uint8_t +ncr5380_drq(ncr_t *ncr) +{ + uint8_t ret = 0; + int bus; + + ncr5380_bus_read(ncr); + bus = ncr->cur_bus; + + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) + ret = 1; + + return ret; +} + uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 1ed8e520e..f4bd9de59 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,6 +41,7 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -48,43 +49,14 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 - enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B + ROM_T130B, + ROM_PAS }; -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; - ncr_t ncr; - uint8_t buffer[128]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; - - uint32_t rom_addr; - uint16_t base; - - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} ncr53c400_t; - #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -103,8 +75,29 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif +void +ncr53c400_simple_write(uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { + ncr400->buffer[ncr400->buffer_host_pos++] = val; + + ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + + if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr400->busy = 1; + + ncr53c400_callback(priv); + } + } +} + /* Memory-mapped I/O WRITE handler. */ -static void +void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -192,8 +185,30 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } +uint8_t +ncr53c400_simple_read(void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { + ret = ncr400->buffer[ncr400->buffer_host_pos++]; + ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + + if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + ncr53c400_callback(priv); + } + } + + return ret; +} + /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -385,6 +400,34 @@ t130b_in(uint16_t port, void *priv) return ret; } +static void +ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t val = send ? CTRL_DATA_DIR : 0x00; + + ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); + + ncr400->block_count_loaded = 1; + + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr400->buffer_host_pos = MIN(512, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { + memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); + ncr53c400_log("DMA buffer init\n"); + ncr->timer(ncr->priv, ncr->period); + } + ncr53c400_log("NCR DMA init\n"); +} + static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -412,17 +455,21 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -static void +void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; + int blocks_left; uint8_t c; uint8_t temp; + const int buf_len = ncr400->simple_ctrl ? 512 : 128; - if (ncr->dma_mode != DMA_IDLE) + ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); + + if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -441,7 +488,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (ncr400->status_ctrl & CTRL_DATA_DIR) { + if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -475,14 +522,20 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); - if (!ncr400->block_count) { + if (ncr400->simple_ctrl) { + ncr->block_count = (ncr->block_count - 1) & 0xffffffff; + blocks_left = ncr->block_count; + } else { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + blocks_left = ncr400->block_count; + } + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); + if (blocks_left == 0) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -499,7 +552,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -515,8 +568,10 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + if (ncr->cur_bus & BUS_REQ) { + ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); break; + } } /* Data ready. */ @@ -531,13 +586,19 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); - if (!ncr400->block_count) { + if (ncr400->simple_ctrl) { + ncr->block_count = (ncr->block_count - 1) & 0xffffffff; + blocks_left = ncr->block_count; + } else { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + blocks_left = ncr400->block_count; + } + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); + if (blocks_left == 0) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -562,6 +623,8 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; + if (ncr400->simple_ctrl) + ncr400->block_count_loaded = 0; } } @@ -656,7 +719,6 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; - case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -715,6 +777,13 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; + case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ + ncr400->simple_ctrl = 1; + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr->simple_pseudo_dma = 1; + ncr->dma_init_ext = ncr53c400_dma_init_ext; + break; + default: break; } @@ -1007,3 +1076,17 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = ROM_PAS, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/openal.c b/src/sound/openal.c index f015205f6..f1ca74182 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -21,7 +21,6 @@ #include #include #include -#include #undef AL_API #undef ALC_API #define AL_LIBTYPE_STATIC @@ -40,9 +39,10 @@ ALuint buffers[4]; /* front and back buffers */ ALuint buffers_music[4]; /* front and back buffers */ +ALuint buffers_wt[4]; /* front and back buffers */ ALuint buffers_cd[4]; /* front and back buffers */ ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[4]; /* audio source */ +static ALuint source[5]; /* audio source */ static int midi_freq = 44100; static int midi_buf_size = 4410; @@ -52,13 +52,12 @@ static ALCcontext *Context; static ALCdevice *Device; void -al_set_midi(int freq, int buf_size) +al_set_midi(const int freq, const int buf_size) { midi_freq = freq; midi_buf_size = buf_size; } -void closeal(void); ALvoid alutInit(UNUSED(ALint *argc), UNUSED(ALbyte **argv)) { @@ -116,14 +115,15 @@ inital(void) { float *buf = NULL; float *music_buf = NULL; + float *wt_buf = NULL; float *cd_buf = NULL; float *midi_buf = NULL; int16_t *buf_int16 = NULL; int16_t *music_buf_int16 = NULL; + int16_t *wt_buf_int16 = NULL; int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - const char *mdn; int init_midi = 0; if (initialized) @@ -132,21 +132,23 @@ inital(void) alutInit(0, 0); atexit(closeal); - mdn = midi_out_device_get_internal_name(midi_output_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) + const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); + if ((strcmp(mdn, "none") != 0) && (strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME) != 0)) init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the - MIDI buffer and source, otherwise, do not. */ - sources = 3 + !!init_midi; + MIDI buffer and source, otherwise, do not. */ + sources = 4 + !!init_midi; if (sound_is_float) { buf = (float *) calloc((BUFLEN << 1), sizeof(float)); music_buf = (float *) calloc((MUSICBUFLEN << 1), sizeof(float)); + wt_buf = (float *) calloc((WTBUFLEN << 1), sizeof(float)); cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); music_buf_int16 = (int16_t *) calloc((MUSICBUFLEN << 1), sizeof(int16_t)); + wt_buf_int16 = (int16_t *) calloc((WTBUFLEN << 1), sizeof(int16_t)); cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); @@ -155,47 +157,55 @@ inital(void) alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); alGenBuffers(4, buffers_music); + alGenBuffers(4, buffers_wt); if (init_midi) alGenBuffers(4, buffers_midi); if (init_midi) - alGenSources(4, source); + alGenSources(5, source); else - alGenSources(3, source); + alGenSources(4, source); - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0); + alSource3f(source[0], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[0], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[0], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0f); alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0); + alSource3f(source[1], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[1], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[1], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0f); alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); + alSource3f(source[2], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[2], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[2], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0f); alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[3], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[3], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[3], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); if (init_midi) { - alSource3f(source[3], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[3], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[3], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0); - alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[4], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[4], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[4], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[4], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[4], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); memset(cd_buf, 0, CD_BUFLEN * 2 * sizeof(float)); memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); + memset(wt_buf, 0, WTBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); memset(cd_buf_int16, 0, CD_BUFLEN * 2 * sizeof(int16_t)); memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); + memset(wt_buf_int16, 0, WTBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); } @@ -204,39 +214,45 @@ inital(void) if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, music_buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_wt[c], AL_FORMAT_STEREO_FLOAT32, wt_buf, WTBUFLEN * 2 * sizeof(float), WT_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * (int) sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); alBufferData(buffers_music[c], AL_FORMAT_STEREO16, music_buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_wt[c], AL_FORMAT_STEREO16, wt_buf_int16, WTBUFLEN * 2 * sizeof(int16_t), WT_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * (int) sizeof(int16_t), midi_freq); } } alSourceQueueBuffers(source[0], 4, buffers); alSourceQueueBuffers(source[1], 4, buffers_music); - alSourceQueueBuffers(source[2], 4, buffers_cd); + alSourceQueueBuffers(source[2], 4, buffers_wt); + alSourceQueueBuffers(source[3], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[3], 4, buffers_midi); + alSourceQueueBuffers(source[4], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); alSourcePlay(source[2]); + alSourcePlay(source[3]); if (init_midi) - alSourcePlay(source[3]); + alSourcePlay(source[4]); if (sound_is_float) { if (init_midi) free(midi_buf); free(cd_buf); + free(wt_buf); free(music_buf); free(buf); } else { if (init_midi) free(midi_buf_int16); free(cd_buf_int16); + free(wt_buf_int16); free(music_buf_int16); free(buf_int16); } @@ -245,12 +261,11 @@ inital(void) } void -givealbuffer_common(void *buf, uint8_t src, int size, int freq) +givealbuffer_common(const void *buf, const uint8_t src, const int size, const int freq) { int processed; int state; ALuint buffer; - double gain; if (!initialized) return; @@ -263,40 +278,40 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq) alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); if (processed >= 1) { - gain = pow(10.0, (double) sound_gain / 20.0); - alListenerf(AL_GAIN, gain); + const double gain = pow(10.0, (double) sound_gain / 20.0); + alListenerf(AL_GAIN, (float) gain); alSourceUnqueueBuffers(source[src], 1, &buffer); if (sound_is_float) - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * (int) sizeof(float), freq); else - alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * (int) sizeof(int16_t), freq); alSourceQueueBuffers(source[src], 1, &buffer); } } void -givealbuffer(void *buf) +givealbuffer(const void *buf) { givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } void -givealbuffer_music(void *buf) +givealbuffer_music(const void *buf) { givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } void -givealbuffer_cd(void *buf) +givealbuffer_cd(const void *buf) { givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); } void -givealbuffer_midi(void *buf, uint32_t size) +givealbuffer_midi(const void *buf, const uint32_t size) { - givealbuffer_common(buf, 3, size, midi_freq); + givealbuffer_common(buf, 3, (int) size, midi_freq); } diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 793f8bcb7..cc01ff6dd 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -1758,8 +1758,7 @@ int32_t old_vol[32] = { 0 }; void emu8k_update(emu8k_t *emu8k) { - int new_pos = (sound_pos_global * FREQ_44100) / SOUND_FREQ; - if (emu8k->pos >= new_pos) + if (emu8k->pos >= wavetable_pos_global) return; int32_t *buf; @@ -1768,16 +1767,16 @@ emu8k_update(emu8k_t *emu8k) /* Clean the buffers since we will accumulate into them. */ buf = &emu8k->buffer[emu8k->pos * 2]; - memset(buf, 0, 2 * (new_pos - emu8k->pos) * sizeof(emu8k->buffer[0])); - memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->chorus_in_buffer[0])); - memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->reverb_in_buffer[0])); + memset(buf, 0, 2 * (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->buffer[0])); + memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->chorus_in_buffer[0])); + memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->reverb_in_buffer[0])); /* Voices section */ for (uint8_t c = 0; c < 32; c++) { emu_voice = &emu8k->voice[c]; buf = &emu8k->buffer[emu8k->pos * 2]; - for (pos = emu8k->pos; pos < new_pos; pos++) { + for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { int32_t dat; if (emu_voice->cvcf_curr_volume) { @@ -2121,12 +2120,12 @@ emu8k_update(emu8k_t *emu8k) } buf = &emu8k->buffer[emu8k->pos * 2]; - emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos - emu8k->pos); - emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos - emu8k->pos); - emu8k_work_eq(buf, new_pos - emu8k->pos); + emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, wavetable_pos_global - emu8k->pos); + emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, wavetable_pos_global - emu8k->pos); + emu8k_work_eq(buf, wavetable_pos_global - emu8k->pos); // Clip signal - for (pos = emu8k->pos; pos < new_pos; pos++) { + for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { if (buf[0] < -32768) buf[0] = -32768; else if (buf[0] > 32767) @@ -2141,9 +2140,9 @@ emu8k_update(emu8k_t *emu8k) } /* Update EMU clock. */ - emu8k->wc += (new_pos - emu8k->pos); + emu8k->wc += (wavetable_pos_global - emu8k->pos); - emu8k->pos = new_pos; + emu8k->pos = wavetable_pos_global; } void diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 8fb526f14..8d7dbba4e 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -5,12 +5,14 @@ #include #include "cpu.h" + +#include #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct lpt_dac_t { @@ -50,6 +52,14 @@ dac_write_data(uint8_t val, void *priv) dac_update(lpt_dac); } +static void +dac_strobe(uint8_t old, uint8_t val, void *priv) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; + + lpt_dac->channel = val; +} + static void dac_write_ctrl(uint8_t val, void *priv) { @@ -110,25 +120,31 @@ dac_close(void *priv) } const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .init = dac_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .init = dac_stereo_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index bd794fffb..5e5191e98 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct dss_t { @@ -134,13 +134,16 @@ dss_close(void *priv) } const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .write_ctrl = dss_write_ctrl, - .read_data = NULL, - .read_status = dss_read_status, - .read_ctrl = NULL + .name = "Disney Sound Source", + .internal_name = "dss", + .init = dss_init, + .close = dss_close, + .write_data = dss_write_data, + .autofeed = NULL, + .strobe = NULL, + .write_ctrl = dss_write_ctrl, + .read_status = dss_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 55e7f1984..1da97adfa 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -74,7 +74,6 @@ public: virtual void write(uint16_t addr, uint8_t data) = 0; virtual void generate(int32_t *data, uint32_t num_samples) = 0; - virtual void generate_resampled(int32_t *data, uint32_t num_samples) = 0; virtual int32_t *update() = 0; virtual uint8_t read(uint16_t addr) = 0; virtual void set_clock(uint32_t clock) = 0; @@ -82,6 +81,7 @@ public: protected: int32_t m_buffer[MUSICBUFLEN * 2]; int m_buf_pos; + int *m_buf_pos_global; int8_t m_flags; fm_type m_type; uint32_t m_samplerate; @@ -99,11 +99,12 @@ public: { memset(m_samples, 0, sizeof(m_samples)); memset(m_oldsamples, 0, sizeof(m_oldsamples)); - m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); - m_clock_us = 1000000.0 / (double) m_clock; - m_subtract[0] = 80.0; - m_subtract[1] = 320.0; - m_type = type; + m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); + m_clock_us = 1000000.0 / (double) m_clock; + m_subtract[0] = 80.0; + m_subtract[1] = 320.0; + m_type = type; + m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global; if (m_type == FM_YMF278B) { if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) { @@ -170,9 +171,10 @@ public: } } +#if 0 virtual void generate_resampled(int32_t *data, uint32_t num_samples) override { - if (m_samplerate == FREQ_49716) { + if ((m_samplerate == FREQ_49716) || (m_samplerate == FREQ_44100)) { generate(data, num_samples); return; } @@ -210,29 +212,18 @@ public: m_samplecnt += 1 << RSM_FRAC; } } +#endif virtual int32_t *update() override { - if (m_samplerate == FREQ_49716) { - if (m_buf_pos >= music_pos_global) - return m_buffer; + if (m_buf_pos >= *m_buf_pos_global) + return m_buffer; - generate(&m_buffer[m_buf_pos * 2], music_pos_global - m_buf_pos); + generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); - for (; m_buf_pos < music_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; - } - } else { - if (m_buf_pos >= sound_pos_global) - return m_buffer; - - generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); - - for (; m_buf_pos < sound_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; - } + for (; m_buf_pos < *m_buf_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; } return m_buffer; @@ -343,11 +334,11 @@ ymfm_drv_init(const device_t *info) case FM_YMF289B: /* According to the datasheet, we should be using 33868800, but YMFM appears to cheat and does it using the same values as the YMF262. */ - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, FREQ_49716); break; case FM_YMF278B: - fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, FREQ_44100); break; } @@ -422,7 +413,8 @@ static void ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) { YMFMChipBase *drv = (YMFMChipBase *) priv; - drv->generate_resampled(data, num_samples); + // drv->generate_resampled(data, num_samples); + drv->generate(data, num_samples); } const device_t ym3812_ymfm_device = { diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 245d9590e..3b649639a 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -414,7 +414,7 @@ optimc_init(const device_t *info) sound_add_handler(optimc_get_buffer, optimc); if (optimc->fm_type == FM_YMF278B) - sound_add_handler(sb_get_music_buffer_sbpro, optimc->sb); + wavetable_add_handler(sb_get_music_buffer_sbpro, optimc->sb); else music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 4530bda86..80d93dcbf 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -92,7 +92,6 @@ #include #include #include -#include #define HAVE_STDARG_H #include "cpu.h" @@ -100,24 +99,86 @@ #include <86box/device.h> #include <86box/dma.h> #include <86box/filters.h> +#include <86box/plat_unused.h> #include <86box/io.h> +#include <86box/mem.h> #include <86box/midi.h> #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> #include <86box/pit_fast.h> +#include <86box/rom.h> +#include <86box/scsi_ncr5380.h> +#include <86box/scsi_ncr53c400.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> -#include <86box/plat_unused.h> +#include <86box/snd_sb_dsp.h> + +typedef struct nsc_mixer_t { + double master_l; + double master_r; + + int bass; + int treble; + + double fm_l; + double fm_r; + double imixer_l; + double imixer_r; + double line_l; + double line_r; + double cd_l; + double cd_r; + double mic_l; + double mic_r; + double pcm_l; + double pcm_r; + double speaker_l; + double speaker_r; + + uint8_t lmc1982_regs[8]; + uint8_t lmc835_regs[32]; + + uint8_t im_state; + uint16_t im_data[4]; +} nsc_mixer_t; + +typedef struct mv508_mixer_t { + double master_l; + double master_r; + + int bass; + int treble; + + double fm_l; + double fm_r; + double imixer_l; + double imixer_r; + double line_l; + double line_r; + double cd_l; + double cd_r; + double mic_l; + double mic_r; + double pcm_l; + double pcm_r; + double speaker_l; + double speaker_r; + double sb_l; + double sb_r; + + uint8_t index; + uint8_t regs[3][128]; +} mv508_mixer_t; typedef struct pas16_t { uint8_t this_id; uint8_t board_id; uint8_t master_ff; - uint8_t irq; + uint8_t has_scsi; uint8_t dma; uint8_t sb_irqdma; uint8_t type; @@ -150,6 +211,10 @@ typedef struct pas16_t { uint8_t midi_data; uint8_t fifo_stat; + uint8_t timeout_count; + uint8_t timeout_status; + uint8_t pad_array[6]; + uint8_t midi_queue[256]; uint16_t base; @@ -170,12 +235,22 @@ typedef struct pas16_t { int midi_uart_in; int sysex; + int irq; + int scsi_irq; + + nsc_mixer_t nsc_mixer; + mv508_mixer_t mv508_mixer; + fm_drv_t opl; sb_dsp_t dsp; mpu_t * mpu; pitf_t * pit; + + ncr53c400_t *scsi; + + pc_timer_t scsi_timer; } pas16_t; static uint8_t pas16_next = 0; @@ -207,45 +282,385 @@ enum { PAS16_FILT_MUTE = 0x20 }; +enum { + STATE_SM_IDLE = 0x00, + STATE_LMC1982_ADDR = 0x10, + STATE_LMC1982_ADDR_0 = 0x10, + STATE_LMC1982_ADDR_1, + STATE_LMC1982_ADDR_2, + STATE_LMC1982_ADDR_3, + STATE_LMC1982_ADDR_4, + STATE_LMC1982_ADDR_5, + STATE_LMC1982_ADDR_6, + STATE_LMC1982_ADDR_7, + STATE_LMC1982_ADDR_OVER, + STATE_LMC1982_DATA = 0x10, + STATE_LMC1982_DATA_0 = 0x20, + STATE_LMC1982_DATA_1, + STATE_LMC1982_DATA_2, + STATE_LMC1982_DATA_3, + STATE_LMC1982_DATA_4, + STATE_LMC1982_DATA_5, + STATE_LMC1982_DATA_6, + STATE_LMC1982_DATA_7, + STATE_LMC1982_DATA_8, + STATE_LMC1982_DATA_9, + STATE_LMC1982_DATA_A, + STATE_LMC1982_DATA_B, + STATE_LMC1982_DATA_C, + STATE_LMC1982_DATA_D, + STATE_LMC1982_DATA_E, + STATE_LMC1982_DATA_F, + STATE_LMC1982_DATA_OVER, + STATE_LMC835_DATA = 0x40, + STATE_LMC835_DATA_0 = 0x40, + STATE_LMC835_DATA_1, + STATE_LMC835_DATA_2, + STATE_LMC835_DATA_3, + STATE_LMC835_DATA_4, + STATE_LMC835_DATA_5, + STATE_LMC835_DATA_6, + STATE_LMC835_DATA_7, + STATE_LMC835_DATA_OVER, +}; + +#define STATE_DATA_MASK 0x07 +#define STATE_DATA_MASK_W 0x0f + +#define LMC1982_ADDR 0x00 +#define LMC1982_DATA 0x01 +#define LMC835_ADDR 0x02 +#define LMC835_DATA 0x03 + +#define LMC835_FLAG_ADDR 0x80 + +#define SERIAL_MIXER_IDENT 0x10 +#define SERIAL_MIXER_STROBE 0x04 +#define SERIAL_MIXER_CLOCK 0x02 +#define SERIAL_MIXER_DATA 0x01 +#define SERIAL_MIXER_RESET_PCM 0x01 + #define PAS16_PCM_AND_DMA_ENA (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA) -double low_fir_pas16_coef[4][SB16_NCoef]; +/* + LMC1982CIN registers (data bits 7 and 6 are always don't care): + - 40 = Mode (0x01 = INPUT2); + - 41 = 0 = Loudness (1 = on, 0 = off), 1 = Stereo Enhance (1 = on, 0 = off) + (0x00); + - 42 = Bass, 00-0c (0x06); + - 43 = Treble, 00-0c (0x06); + - 45 [L] / 44 [R] = Master, 28-00, counting down (0x28, later 0xa8); + - 46 = ???? (0x05 = Stereo). + */ +#define LMC1982_REG_MASK 0xf8 /* LMC1982CIN: Register Mask */ +#define LMC1982_REG_VALID 0x40 /* LMC1982CIN: Register Valid Value */ + +#define LMC1982_REG_ISELECT 0x00 /* LMC1982CIN: Input Select + Mute */ +#define LMC1982_REG_LES 0x01 /* LMC1982CIN: Loudness, Enhanced Stereo */ +#define LMC1982_REG_BASS 0x02 /* LMC1982CIN: Bass */ +#define LMC1982_REG_TREBLE 0x03 /* LMC1982CIN: Treble */ +/* The Windows 95 driver indicates left and right are swapped in the wiring. */ +#define LMC1982_REG_VOL_L 0x04 /* LMC1982CIN: Left Volume */ +#define LMC1982_REG_VOL_R 0x05 /* LMC1982CIN: Right Volume */ +#define LMC1982_REG_MODE 0x06 /* LMC1982CIN: Mode */ +#define LMC1982_REG_DINPUT 0x07 /* LMC1982CIN: Digital Input 1 and 2 */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_ISELECT_MASK 0x03 /* LMC1982CIN: Input Select: Mask */ +#define LMC1982_ISELECT_I1 0x00 /* LMC1982CIN: Input Select: INPUT1 */ +#define LMC1982_ISELECT_I2 0x01 /* LMC1982CIN: Input Select: INPUT2 */ +#define LMC1982_ISELECT_NA 0x02 /* LMC1982CIN: Input Select: N/A */ +#define LMC1982_ISELECT_MUTE 0x03 /* LMC1982CIN: Input Select: MUTE */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_LES_MASK 0x03 /* LMC1982CIN: Loudness, Enhanced Stereo: Mask */ +#define LMC1982_LES_BOTH_OFF 0x00 /* LMC1982CIN: Loudness OFF, Enhanced Stereo OFF */ +#define LMC1982_L_ON_ES_OFF 0x01 /* LMC1982CIN: Loudness ON, Enhanced Stereo OFF */ +#define LMC1982_L_OFF_ES_ON 0x02 /* LMC1982CIN: Loudness OFF, Enhanced Stereo ON */ +#define LMC1982_LES_BOTH_ON 0x03 /* LMC1982CIN: Loudness OFF, Enhanced Stereo ON */ + +/* Bits 7-3: Don't care. */ +#define LMC1982_MODE_MASK 0x07 /* LMC1982CIN: Mode: Mask */ +#define LMC1982_MODE_MONO_L 0x04 /* LMC1982CIN: Mode: Left Mono */ +#define LMC1982_MODE_STEREO 0x05 /* LMC1982CIN: Mode: Stereo */ +#define LMC1982_MODE_MONO_R 0x06 /* LMC1982CIN: Mode: Right Mono */ +#define LMC1982_MODE_MONO_R_2 0x07 /* LMC1982CIN: Mode: Right Mono (Alternate value) */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_DINPUT_MASK 0x03 /* LMC1982CIN: Digital Input 1 and 2: Mask */ +#define LMC1982_DINPUT_DI1 0x01 /* LMC1982CIN: Digital Input 1 */ +#define LMC1982_DINPUT_DI2 0x02 /* LMC1982CIN: Digital Input 2 */ + +/* + LMC835N registers: + - 01 [L] / 08 [R] = FM, 00-2f, bit 6 = clear, but the DOS driver sets + the bit, indicating a volume boost (0x69); + - 02 [L] / 09 [R] = Rec. monitor, 00-2f, bit 6 = clear (0x29); + - 03 [L] / 0A [R] = Line in, 00-2f, bit 6 = clear, except for the DOS + driver (0x69); + - 04 [L] / 0B [R] = CD, 00-2f, bit 6 = clear, except for the DOS driver + (0x69); + - 05 [L] / 0C [R] = Microphone, 00-2f, bit 6 = clear, except for the DOS + driver (0x44); + - 06 [L] / 0D [R] = Wave out, 00-2f, bit 6 = set, except for DOS driver, + which clears the bit (0x29); + - 07 [L] / 0E [R] = PC speaker, 00-2f, bit 6 = clear, except for the DOS + drive (0x06). + The registers for which the DOS driver sets the boost, also have bit 6 + set in the address, despite the fact it should be a don't care - why? + Apparently, no Sound Blaster control. +*/ +#define LMC835_REG_MODE 0x00 /* LMC835N: Mode, not an actual register, but our internal register + to store the mode for Channels A (1-7) and B (8-e). */ + +#define LMC835_REG_FM_L 0x01 /* LMC835N: FM Left */ +#define LMC835_REG_IMIXER_L 0x02 /* LMC835N: Record Monitor Left */ +#define LMC835_REG_LINE_L 0x03 /* LMC835N: Line in Left */ +#define LMC835_REG_CDROM_L 0x04 /* LMC835N: CD Left */ +#define LMC835_REG_MIC_L 0x05 /* LMC835N: Microphone Left */ +#define LMC835_REG_PCM_L 0x06 /* LMC835N: Wave out Left */ +#define LMC835_REG_SPEAKER_L 0x07 /* LMC83N5: PC speaker Left */ + +#define LMC835_REG_FM_R 0x08 /* LMC835N: FM Right */ +#define LMC835_REG_IMIXER_R 0x09 /* LMC835N: Record Monitor Right */ +#define LMC835_REG_LINE_R 0x0a /* LMC835N: Line in Right */ +#define LMC835_REG_CDROM_R 0x0b /* LMC835N: CD Right */ +#define LMC835_REG_MIC_R 0x0c /* LMC835N: Microphone Right */ +#define LMC835_REG_PCM_R 0x0d /* LMC835N: Wave out Right */ +#define LMC835_REG_SPEAKER_R 0x0e /* LMC83N5: PC speaker Right */ + +#define MV508_ADDRESS 0x80 /* Flag indicating it is the address */ +/* + I think this may actually operate as such: + - Bit 6: Mask left channel; + - Bit 5: Mask right channel. + */ +#define MV508_CHANNEL 0x60 +#define MV508_LEFT 0x20 +#define MV508_RIGHT 0x40 +#define MV508_BOTH 0x00 +#define MV508_MIXER 0x10 /* Flag indicating it is a mixer rather than a volume */ + +#define MV508_INPUT_MIX 0x20 /* Flag indicating the selected mixer is input */ + +#define MV508_MASTER_A 0x01 /* Volume: Output */ +#define MV508_MASTER_B 0x02 /* Volume: DSP input */ +#define MV508_BASS 0x03 /* Volume: Bass */ +#define MV508_TREBLE 0x04 /* Volume: Treble */ +#define MV508_MODE 0x05 /* Volume: Mode */ + +#define MV508_LOUDNESS 0x04 /* Mode: Loudness */ +#define MV508_ENH_MASK 0x03 /* Mode: Stereo enhancement bit mask */ +#define MV508_ENH_NONE 0x00 /* Mode: No stereo enhancement */ +#define MV508_ENH_40 0x01 /* Mode: 40% stereo enhancement */ +#define MV508_ENH_60 0x02 /* Mode: 60% stereo enhancement */ +#define MV508_ENH_80 0x03 /* Mode: 80% stereo enhancement */ + +#define MV508_FM 0x00 /* Mixer: FM */ +#define MV508_IMIXER 0x01 /* Mixer: Input mixer (recording monitor) */ +#define MV508_LINE 0x02 /* Mixer: Line in */ +#define MV508_CDROM 0x03 /* Mixer: CD-ROM */ +#define MV508_MIC 0x04 /* Mixer: Microphone */ +#define MV508_PCM 0x05 /* Mixer: PCM */ +#define MV508_SPEAKER 0x06 /* Mixer: PC Speaker */ +#define MV508_SB 0x07 /* Mixer: Sound Blaster DSP */ + +#define MV508_REG_MASTER_A_L (MV508_MASTER_A | MV508_LEFT) +#define MV508_REG_MASTER_A_R (MV508_MASTER_A | MV508_RIGHT) +#define MV508_REG_MASTER_B_L (MV508_MASTER_B | MV508_LEFT) +#define MV508_REG_MASTER_B_R (MV508_MASTER_B | MV508_RIGHT) +#define MV508_REG_BASS (MV508_BASS | MV508_LEFT) +#define MV508_REG_TREBLE (MV508_TREBLE | MV508_LEFT) + +#define MV508_REG_FM_L (MV508_MIXER | MV508_FM | MV508_LEFT) +#define MV508_REG_FM_R (MV508_MIXER | MV508_FM | MV508_RIGHT) +#define MV508_REG_IMIXER_L (MV508_MIXER | MV508_IMIXER | MV508_LEFT) +#define MV508_REG_IMIXER_R (MV508_MIXER | MV508_IMIXER | MV508_RIGHT) +#define MV508_REG_LINE_L (MV508_MIXER | MV508_LINE | MV508_LEFT) +#define MV508_REG_LINE_R (MV508_MIXER | MV508_LINE | MV508_RIGHT) +#define MV508_REG_CDROM_L (MV508_MIXER | MV508_CDROM | MV508_LEFT) +#define MV508_REG_CDROM_R (MV508_MIXER | MV508_CDROM | MV508_RIGHT) +#define MV508_REG_MIC_L (MV508_MIXER | MV508_MIC | MV508_LEFT) +#define MV508_REG_MIC_R (MV508_MIXER | MV508_MIC | MV508_RIGHT) +#define MV508_REG_PCM_L (MV508_MIXER | MV508_PCM | MV508_LEFT) +#define MV508_REG_PCM_R (MV508_MIXER | MV508_PCM | MV508_RIGHT) +#define MV508_REG_SPEAKER_L (MV508_MIXER | MV508_SPEAKER | MV508_LEFT) +#define MV508_REG_SPEAKER_R (MV508_MIXER | MV508_SPEAKER | MV508_RIGHT) +#define MV508_REG_SB_L (MV508_MIXER | MV508_SB | MV508_LEFT) +#define MV508_REG_SB_R (MV508_MIXER | MV508_SB | MV508_RIGHT) + +double low_fir_pas16_coef[SB16_NCoef]; + +/* + Also used for the MVA508. + */ +static double lmc1982_bass_treble_4bits[16]; + +/* + Copied from the Sound Blaster code: -62 dB to 0 dB in 2 dB steps. + Note that these are voltage dB's, so it corresonds in power dB + (formula for conversion to percentage: 10 ^ (dB / 10)) to -31 dB + to 0 dB in 1 dB steps. + + This is used for the MVA508 Volumes. + */ +static const double mva508_att_2dbstep_5bits[] = { + 25.0, 32.0, 41.0, 51.0, 65.0, 82.0, 103.0, 130.0, + 164.0, 206.0, 260.0, 327.0, 412.0, 519.0, 653.0, 822.0, + 1036.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; + +/* + The same but in 1 dB steps, used for the MVA508 Master Volume. + */ +static const double mva508_att_1dbstep_6bits[] = { + 18.0, 25.0, 29.0, 32.0, 36.0, 41.0, 46.0, 51.0, + 58.0, 65.0, 73.0, 82.0, 92.0, 103.0, 116.0, 130.0, + 146.0, 164.0, 184.0, 206.0, 231.0, 260.0, 292.0, 327.0, + 367.0, 412.0, 462.0, 519.0, 582.0, 653.0, 733.0, 822.0, + 923.0, 1036.0, 1162.0, 1304.0, 1463.0, 1641.0, 1842.0, 2067.0, + 2319.0, 2602.0, 2920.0, 3276.0, 3676.0, 4125.0, 4628.0, 5192.0, + 5826.0, 6537.0, 7335.0, 8230.0, 9234.0, 10362.0, 11626.0, 13044.0, + 14636.0, 16422.0, 18426.0, 20674.0, 23197.0, 26027.0, 29204.0, 32767.0 +}; + +/* + In 2 dB steps again, but to -80 dB and counting down (0 = Flat), used + for the LMC1982CIN Master Volume. + */ +static const double lmc1982_att_2dbstep_6bits[] = { + 32767.0, 26027.0, 20674.0, 16422.0, 13044.0, 10362.0, 8230.0, 6537.0, + 5192.0, 4125.0, 3276.0, 2602.0, 2067.0, 1641.0, 1304.0, 1036.0, + 822.0, 653.0, 519.0, 412.0, 327.0, 260.0, 206.0, 164.0, + 130.0, 103.0, 82.0, 65.0, 51.0, 41.0, 32.0, 25.0, + 20.0, 16.0, 13.0, 10.0, 8.0, 6.0, 5.0, 4.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 +}; + +/* + LMC385N attenuation, both +/- 12 dB and +/- 6 dB. + + Since the DOS and Windows 95 driver diverge on boost vs. cut for + the various inputs, I think it is best to just do a 12 dB cut on + the input, and then apply cut or boost as needed. I have factored + in said cut in the below values. + */ +static const double lmc835_att_1dbstep_7bits[128] = { + 0.0, + /* Flat */ + [0x40] = 8230.0, /* Flat */ + /* Boost */ + [0x60] = 9234.0, /* 1 dB Boost */ + [0x50] = 10362.0, /* 2 dB Boost */ + [0x48] = 11626.0, /* 3 dB Boost */ + [0x44] = 13044.0, /* 4 dB Boost */ + [0x42] = 14636.0, /* 5 dB Boost */ + [0x52] = 16422.0, /* 6 dB Boost */ + [0x6a] = 18426.0, /* 7 dB Boost */ + [0x56] = 20674.0, /* 8 dB Boost */ + [0x41] = 23197.0, /* 9 dB Boost */ + [0x69] = 26027.0, /* 10 dB Boost */ + [0x6d] = 29204.0, /* 11 dB Boost */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x5d] = 29204.0, /* 11 dB Boost */ + [0x6f] = 32767.0, /* 12 dB Boost */ + /* Flat */ + /* The datasheet says this should be Flat (1.0) but the + Windows 95 drivers use this as basically mute (12 dB Cut). */ + [0x00] = 2067.0, /* 12 dB Cut */ + /* Cut - D5-D0 = 2F is minimum cut (0 dB) according to Windows 95 */ + [0x20] = 2319.0, /* 11 dB Cut */ + [0x10] = 2602.0, /* 10 dB Cut */ + [0x08] = 2920.0, /* 9 dB Cut */ + [0x04] = 3276.0, /* 8 dB Cut */ + [0x02] = 3676.0, /* 7 dB Cut */ + [0x12] = 4125.0, /* 6 dB Cut */ + [0x2a] = 4628.0, /* 5 dB Cut */ + [0x16] = 5192.0, /* 4 dB Cut */ + [0x01] = 5826.0, /* 3 dB Cut */ + [0x29] = 6537.0, /* 2 dB Cut */ + [0x2d] = 7335.0, /* 1 dB Cut */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x1d] = 7335.0, /* 1 dB Cut */ + [0x2f] = 8230.0, /* Flat */ +}; + +static const double lmc835_att_05dbstep_7bits[128] = { + 0.0 , + /* Flat */ + [0x40] = 8230.0, /* Flat */ + /* Boost */ + [0x60] = 8718.0, /* 0.5 dB Boost */ + [0x50] = 9234.0, /* 1.0 dB Boost */ + [0x48] = 9782.0, /* 1.5 dB Boost */ + [0x44] = 10362.0, /* 2.0 dB Boost */ + [0x42] = 10975.0, /* 2.5 dB Boost */ + [0x52] = 11626.0, /* 3.0 dB Boost */ + [0x6a] = 12315.0, /* 3.5 dB Boost */ + [0x56] = 13044.0, /* 4.0 dB Boost */ + [0x41] = 13817.0, /* 4.5 dB Boost */ + [0x69] = 14636.0, /* 5.0 dB Boost */ + [0x6d] = 15503.0, /* 5.5 dB Boost */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x5d] = 15503.0, /* 5.5 dB Boost */ + [0x6f] = 16422.0, /* 6.0 dB Boost */ + /* Flat */ + /* The datasheet says this should be Flat (1.0) but the + Windows 95 drivers use this as basically mute (12 dB Cut). */ + [0x00] = 4125.0, /* 6.0 dB Cut */ + /* Cut - D5-D0 = 2F is minimum cut (0 dB) according to Windows 95 */ + [0x20] = 4369.0, /* 5.5 dB Cut */ + [0x10] = 4628.0, /* 5.0 dB Cut */ + [0x08] = 4920.0, /* 4.5 dB Cut */ + [0x04] = 5192.0, /* 4.0 dB Cut */ + [0x02] = 5500.0, /* 3.5 dB Cut */ + [0x12] = 5826.0, /* 3.0 dB Cut */ + [0x2a] = 6172.0, /* 2.5 dB Cut */ + [0x16] = 6537.0, /* 2.0 dB Cut */ + [0x01] = 6925.0, /* 1.5 dB Cut */ + [0x29] = 7335.0, /* 1.0 dB Cut */ + [0x2d] = 7770.0, /* 0.5 dB Cut */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x1d] = 7770.0, /* 0.5 dB Cut */ + [0x2f] = 8230.0, /* Flat */ +}; static __inline double -sinc(double x) +sinc(const double x) { return sin(M_PI * x) / (M_PI * x); } static void -recalc_pas16_filter(int c, int playback_freq) +recalc_pas16_filter(const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) FREQ_96000; - double gain; + int n; + const double fC = ((double) playback_freq) / (double) FREQ_96000; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_pas16_coef[c][n] = w * h; + low_fir_pas16_coef[n] = w * h; } - low_fir_pas16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + low_fir_pas16_coef[(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_pas16_coef[c][n]; + gain += low_fir_pas16_coef[n]; /* Normalise filter, to produce unity gain */ for (n = 0; n < SB16_NCoef; n++) - low_fir_pas16_coef[c][n] /= gain; + low_fir_pas16_coef[n] /= gain; } #ifdef ENABLE_PAS16_LOG @@ -276,12 +691,12 @@ pas16_update_irq(pas16_t *pas16) { if (pas16->midi_uart_out && (pas16->midi_stat & 0x18)) { pas16->irq_stat |= PAS16_INT_MIDI; - if (pas16->irq_ena & PAS16_INT_MIDI) + if ((pas16->irq != -1) && (pas16->irq_ena & PAS16_INT_MIDI)) picint(1 << pas16->irq); } if (pas16->midi_uart_in && (pas16->midi_stat & 0x04)) { pas16->irq_stat |= PAS16_INT_MIDI; - if (pas16->irq_ena & PAS16_INT_MIDI) + if ((pas16->irq != -1) && (pas16->irq_ena & PAS16_INT_MIDI)) picint(1 << pas16->irq); } } @@ -291,6 +706,7 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; + ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -300,7 +716,7 @@ pas16_in(uint16_t port, void *priv) break; case 0x0800: - ret = pas16->audio_mixer; + ret = pas16->type ? pas16->audio_mixer : 0xff; break; case 0x0801: ret = pas16->irq_stat & 0xdf; @@ -346,10 +762,47 @@ pas16_in(uint16_t port, void *priv) ret = pas16->fifo_stat; break; + case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ + case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ + if (pas16->has_scsi) { + port = (port & 0x0003) | ((port & 0x2000) >> 11); + ret = ncr5380_read(port, &pas16->scsi->ncr); + } + break; + case 0x2401: /* Board revision */ ret = 0x00; break; + case 0x4000: + ret = pas16->timeout_count; + break; + case 0x4001: + ret = pas16->timeout_status; + break; + + case 0x5c00: + if (pas16->has_scsi) + ret = ncr53c400_simple_read(pas16->scsi); + break; + case 0x5c01: + if (pas16->has_scsi) { + ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; + if (!(ret & 0x80)) { + ncr53c400_callback(pas16->scsi); + if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } + + } + } + break; + case 0x5c03: + if (pas16->has_scsi) + ret = pas16->scsi->ncr.irq_state << 7; + break; + case 0x7c01: ret = pas16->enhancedscsi & ~0x01; break; @@ -375,11 +828,13 @@ pas16_in(uint16_t port, void *priv) break; case 0xec03: -#ifdef NEWER_PAS16 - ret = pas16->type ? 0x0c : 0x06; -#else - ret = pas16->type ? 0x0f : 0x06; -#endif + /* + Operation mode 1: + - 1,0 = CD-ROM (1,1 = SCSI, 1,0 = Sony, 0,0 = N/A); + - 2 = FM (1 = stereo, 0 = mono); + - 3 = Code (1 = 16-bit, 0 = 8-bit). + */ + ret = pas16->type ? pas16->type : 0x06; break; case 0xf000: @@ -477,17 +932,154 @@ pas16_reset_pcm(void *priv) pas16->irq_stat &= 0xd7; - if (!pas16->irq_stat) + if ((pas16->irq != -1) && !pas16->irq_stat) picintc(1 << pas16->irq); } +static void +lmc1982_recalc(nsc_mixer_t *mixer) +{ + /* LMC1982CIN */ + /* According to the Windows 95 driver, the two volumes are swapped. */ + if ((mixer->lmc1982_regs[LMC1982_REG_ISELECT] & LMC1982_ISELECT_MASK) == LMC1982_ISELECT_I2) { + switch (mixer->lmc1982_regs[LMC1982_REG_MODE] & LMC1982_MODE_MASK) { + case LMC1982_MODE_MONO_L: + mixer->master_l = mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_R]] / 32767.0; + break; + case LMC1982_MODE_STEREO: + mixer->master_l = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_R]] / 32767.0; + mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_L]] / 32767.0; + break; + case LMC1982_MODE_MONO_R: + case LMC1982_MODE_MONO_R_2: + mixer->master_l = mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_L]] / 32767.0; + break; + default: + mixer->master_l = mixer->master_r = 0.0; + break; + } + + mixer->bass = mixer->lmc1982_regs[LMC1982_REG_BASS] & 0x0f; + mixer->treble = mixer->lmc1982_regs[LMC1982_REG_TREBLE] & 0x0f; + } else { + mixer->master_l = mixer->master_r = 0.0; + + mixer->bass = 0x06; + mixer->treble = 0x06; + } +} + +static void +lmc835_recalc(nsc_mixer_t *mixer) +{ + /* LMC835N */ + /* Channel A (1-7) */ + const double *lmc835_att = (const double *) ((mixer->lmc835_regs[LMC835_REG_MODE] & 0x20) ? + lmc835_att_05dbstep_7bits : lmc835_att_1dbstep_7bits); + + mixer->fm_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_FM_L] & 0x7f] / 32767.0; + mixer->imixer_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_IMIXER_L] & 0x7f] / 32767.0; + mixer->line_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_LINE_L] & 0x7f] / 32767.0; + mixer->cd_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_CDROM_L] & 0x7f] / 32767.0; + mixer->mic_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_MIC_L] & 0x7f] / 32767.0; + mixer->pcm_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_PCM_L] & 0x7f] / 32767.0; + mixer->speaker_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_SPEAKER_L] & 0x7f] / 32767.0; + + /* Channel B (8-e) */ + lmc835_att = (const double *) ((mixer->lmc835_regs[LMC835_REG_MODE] & 0x08) ? + lmc835_att_05dbstep_7bits : lmc835_att_1dbstep_7bits); + + mixer->fm_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_FM_R] & 0x7f] / 32767.0; + mixer->imixer_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_IMIXER_R] & 0x7f] / 32767.0; + mixer->line_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_LINE_R] & 0x7f] / 32767.0; + mixer->cd_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_CDROM_R] & 0x7f] / 32767.0; + mixer->mic_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_MIC_R] & 0x7f] / 32767.0; + mixer->pcm_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_PCM_R] & 0x7f] / 32767.0; + mixer->speaker_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_SPEAKER_R] & 0x7f] / 32767.0; +} + +static void +mv508_mixer_recalc(mv508_mixer_t *mixer) +{ + mixer->fm_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_FM_L]] / 32767.0; + mixer->fm_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_FM_R]] / 32767.0; + mixer->imixer_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_IMIXER_L]] / 32767.0; + mixer->imixer_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_IMIXER_R]] / 32767.0; + mixer->line_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_LINE_L]] / 32767.0; + mixer->line_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_LINE_R]] / 32767.0; + mixer->cd_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_CDROM_L]] / 32767.0; + mixer->cd_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_CDROM_R]] / 32767.0; + mixer->mic_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_MIC_L]] / 32767.0; + mixer->mic_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_MIC_R]] / 32767.0; + mixer->pcm_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_PCM_L]] / 32767.0; + mixer->pcm_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_PCM_R]] / 32767.0; + mixer->speaker_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SPEAKER_L]] / 32767.0; + mixer->speaker_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SPEAKER_R]] / 32767.0; + mixer->sb_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SB_L]] / 32767.0; + mixer->sb_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SB_R]] / 32767.0; + + mixer->master_l = mva508_att_1dbstep_6bits[mixer->regs[2][MV508_REG_MASTER_A_L]] / 32767.0; + mixer->master_r = mva508_att_1dbstep_6bits[mixer->regs[2][MV508_REG_MASTER_A_R]] / 32767.0; + + mixer->bass = mixer->regs[2][MV508_REG_BASS] & 0x0f; + mixer->treble = mixer->regs[2][MV508_REG_TREBLE] & 0x0f; +} + +static void +pas16_nsc_mixer_reset(nsc_mixer_t *mixer) +{ + mixer->lmc1982_regs[LMC1982_REG_ISELECT] = 0x01; + mixer->lmc1982_regs[LMC1982_REG_LES] = 0x00; + mixer->lmc1982_regs[LMC1982_REG_BASS] = mixer->lmc1982_regs[LMC1982_REG_TREBLE] = 0x06; + mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x28; + mixer->lmc1982_regs[LMC1982_REG_MODE] = 0x05; + + lmc1982_recalc(mixer); + + mixer->lmc835_regs[LMC835_REG_MODE] = 0x00; + + mixer->lmc835_regs[LMC835_REG_FM_L] = mixer->lmc835_regs[LMC835_REG_FM_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_IMIXER_L] = mixer->lmc835_regs[LMC835_REG_IMIXER_R] = 0x29; + mixer->lmc835_regs[LMC835_REG_LINE_L] = mixer->lmc835_regs[LMC835_REG_LINE_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_CDROM_L] = mixer->lmc835_regs[LMC835_REG_CDROM_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_MIC_L] = mixer->lmc835_regs[LMC835_REG_MIC_R] = 0x44; + mixer->lmc835_regs[LMC835_REG_PCM_L] = mixer->lmc835_regs[LMC835_REG_PCM_R] = 0x29; + mixer->lmc835_regs[LMC835_REG_SPEAKER_L] = mixer->lmc835_regs[LMC835_REG_SPEAKER_R] = 0x06; + + lmc835_recalc(mixer); +} + +static void +pas16_mv508_mixer_reset(mv508_mixer_t *mixer) +{ + /* Based on the Linux driver - TODO: The actual card's defaults. */ + mixer->regs[0][MV508_REG_FM_L] = mixer->regs[0][MV508_REG_FM_R] = 0x18; + mixer->regs[0][MV508_REG_IMIXER_L] = mixer->regs[0][MV508_REG_IMIXER_R] = 0x1f; + mixer->regs[0][MV508_REG_LINE_L] = mixer->regs[0][MV508_REG_LINE_R] = 0x17; + mixer->regs[0][MV508_REG_CDROM_L] = mixer->regs[0][MV508_REG_CDROM_R] = 0x17; + mixer->regs[0][MV508_REG_MIC_L] = mixer->regs[0][MV508_REG_MIC_R] = 0x17; + mixer->regs[0][MV508_REG_PCM_L] = mixer->regs[0][MV508_REG_PCM_R] = 0x17; + mixer->regs[0][MV508_REG_SPEAKER_L] = mixer->regs[0][MV508_REG_SPEAKER_R] = 0x0f; + mixer->regs[0][MV508_REG_SB_L] = mixer->regs[0][MV508_REG_SB_R] = 0x17; + + mixer->regs[2][MV508_REG_MASTER_A_L] = mixer->regs[2][MV508_REG_MASTER_A_R] = 0x1f; + + mixer->regs[2][MV508_REG_BASS] = 0x06; + mixer->regs[2][MV508_REG_TREBLE] = 0x06; + + mv508_mixer_recalc(mixer); +} + static void pas16_reset_regs(void *priv) { pas16_t *pas16 = (pas16_t *) priv; + nsc_mixer_t *nsc_mixer = &pas16->nsc_mixer; + mv508_mixer_t *mv508_mixer = &pas16->mv508_mixer; pitf_t *pit = (pitf_t *) pas16->pit; - picintc(1 << pas16->irq); + if (pas16->irq != -1) + picintc(1 << pas16->irq); pas16->sys_conf_1 &= 0xfd; @@ -509,6 +1101,11 @@ pas16_reset_regs(void *priv) pas16->irq_ena = 0x00; pas16->irq_stat = 0x00; + + if (pas16->type) + pas16_mv508_mixer_reset(mv508_mixer); + else + pas16_nsc_mixer_reset(nsc_mixer); } static void @@ -518,7 +1115,8 @@ pas16_reset_common(void *priv) pas16_reset_regs(pas16); - picintc(1 << pas16->irq); + if (pas16->irq != -1) + picintc(1 << pas16->irq); pas16_io_handler(pas16, 0); pas16->base = 0x0000; @@ -545,10 +1143,70 @@ pas16_reset(void *priv) sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); } +static int +pas16_irq_convert(uint8_t val) +{ + int ret = val; + + if (ret == 0) + ret = -1; + else if (ret <= 6) + ret++; + else if (ret < 0x0b) + ret += 3; + else + ret += 4; + + return ret; +} + +static void +lmc1982_update_reg(nsc_mixer_t *mixer) +{ + pas16_log("LMC1982CIN register %02X = %04X\n", + mixer->im_data[LMC1982_ADDR], mixer->im_data[LMC1982_DATA]); + + if ((mixer->im_data[LMC1982_ADDR] & LMC1982_REG_MASK) == LMC1982_REG_VALID) { + mixer->im_data[LMC1982_ADDR] &= ~LMC1982_REG_MASK; + mixer->lmc1982_regs[mixer->im_data[LMC1982_ADDR]] = mixer->im_data[LMC1982_DATA] & 0xff; + lmc1982_recalc(mixer); + } + + mixer->im_state = STATE_SM_IDLE; +} + +static void +lmc835_update_reg(nsc_mixer_t *mixer) +{ + pas16_log("LMC835N register %02X = %02X\n", + mixer->im_data[LMC835_ADDR], mixer->im_data[LMC835_DATA]); + + mixer->lmc835_regs[LMC835_REG_MODE] = mixer->im_data[LMC835_ADDR] & 0xf0; + mixer->im_data[LMC835_ADDR] &= 0x0f; + if ((mixer->im_data[LMC835_ADDR] >= 0x01) && (mixer->im_data[LMC835_ADDR] <= 0x0e)) + mixer->lmc835_regs[mixer->im_data[LMC835_ADDR] & 0x0f] = mixer->im_data[LMC835_DATA]; + lmc835_recalc(mixer); +} + +static void +pas16_timeout_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + + pas16->timeout_status |= 0x80; + + if ((pas16->timeout_status & 0x08) && (pas16->irq != -1)) + picint(1 << pas16->irq); + + timer_advance_u64(&pas16->scsi_timer, (pas16->timeout_count & 0x3f) * PASSCSICONST); +} + static void pas16_out(uint16_t port, uint8_t val, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pas16_t * pas16 = (pas16_t *) priv; + nsc_mixer_t * nsc_mixer = &pas16->nsc_mixer; + mv508_mixer_t *mv508_mixer = &pas16->mv508_mixer; pas16_log("[%04X:%08X] PAS16: [W] %04X (%04X) = %02X\n", CS, cpu_state.pc, port, port - pas16->base, val); @@ -560,14 +1218,178 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->opl.write(port + 0x0388, val, pas16->opl.priv); break; + case 0x0400 ... 0x0402: + break; + case 0x0403: + if (val & MV508_ADDRESS) + mv508_mixer->index = val & ~MV508_ADDRESS; + else { + uint8_t bank; + uint8_t mask; + + pas16_log("MVA508 register %02X = %02X\n", + mv508_mixer->index, val); + + if (mv508_mixer->index & MV508_MIXER) { + bank = !!(val & MV508_INPUT_MIX); + mask = 0x1f; + } else { + bank = 2; + mask = 0x3f; + } + + if (mv508_mixer->index & MV508_CHANNEL) + mv508_mixer->regs[bank][mv508_mixer->index] = val & mask; + else { + mv508_mixer->regs[bank][mv508_mixer->index | MV508_LEFT] = val & mask; + mv508_mixer->regs[bank][mv508_mixer->index | MV508_RIGHT] = val & mask; + } + + mv508_mixer_recalc(mv508_mixer); + } + break; + case 0x0800: - pas16->audio_mixer = val; - if (!(val & 0x01)) + if (pas16->type && !(val & SERIAL_MIXER_RESET_PCM)) { + pas16->audio_mixer = val; pas16_reset_pcm(pas16); + } else if (!pas16->type) { + switch (nsc_mixer->im_state) { + default: + break; + case STATE_SM_IDLE: + /* Transmission initiated. */ + if (val & SERIAL_MIXER_IDENT) { + if (!(val & SERIAL_MIXER_CLOCK) && (pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* Prepare for receiving LMC835N data. */ + nsc_mixer->im_data[LMC835_DATA] = 0x0000; + nsc_mixer->im_state |= STATE_LMC835_DATA; + } + } else { + if ((pas16->audio_mixer & SERIAL_MIXER_IDENT)) { + /* + Prepare for receiving the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] = 0x0000; + nsc_mixer->im_state |= STATE_LMC1982_ADDR; + } + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the least siginificant bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + } + break; + case STATE_LMC1982_ADDR_0: + if (val & SERIAL_MIXER_IDENT) { + /* + IDENT went high in LM1982CIN address state 0, + behave as if we were in the idle state. + */ + if (!(val & SERIAL_MIXER_CLOCK) && (pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + nsc_mixer->im_data[LMC835_DATA] = 0x0000; + nsc_mixer->im_state = STATE_LMC835_DATA_0; + } + } else if ((val & SERIAL_MIXER_CLOCK) && + !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the least siginificant bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_ADDR_1 ... STATE_LMC1982_ADDR_7: + if ((val & 0x02) && !(pas16->audio_mixer & 0x02)) { + /* + Clock the next bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_ADDR_OVER: + /* + Prepare for receiving the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] = 0x0000; + nsc_mixer->im_state = STATE_LMC1982_DATA_0; + break; + case STATE_LMC1982_DATA_0 ... STATE_LMC1982_DATA_7: + case STATE_LMC1982_DATA_9 ... STATE_LMC1982_DATA_F: + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK_W)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_DATA_8: + if (val & SERIAL_MIXER_IDENT) { + if (!(pas16->audio_mixer & SERIAL_MIXER_IDENT)) + /* + LMC1982CIN data transfer ended after 8 bits, process the data and + reset the state back to idle. + */ + lmc1982_update_reg(nsc_mixer); + else if ((val & SERIAL_MIXER_CLOCK) && + !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK_W)); + nsc_mixer->im_state++; + } + } + break; + case STATE_LMC1982_DATA_OVER: + if ((val & SERIAL_MIXER_IDENT) && !(pas16->audio_mixer & SERIAL_MIXER_IDENT)) + /* + LMC1982CIN data transfer ended, process the data and reset the state + back to idle. + */ + lmc1982_update_reg(nsc_mixer); + break; + case STATE_LMC835_DATA_0 ... STATE_LMC835_DATA_7: + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC835N data. + */ + nsc_mixer->im_data[LMC835_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC835_DATA_OVER: + if ((val & SERIAL_MIXER_STROBE) && !(pas16->audio_mixer & SERIAL_MIXER_STROBE)) { + if (nsc_mixer->im_data[LMC835_DATA] & LMC835_FLAG_ADDR) + /* + The LMC835N data is an address, copy it into its own space for usage + when processing it at the end and strip bits 7 (it's the address/data + indicator) and 6 (it's a "don't care" bit). + */ + nsc_mixer->im_data[LMC835_ADDR] = nsc_mixer->im_data[LMC835_DATA] & 0x7f; + else + lmc835_update_reg(nsc_mixer); + nsc_mixer->im_state = STATE_SM_IDLE; + } + break; + } + + pas16->audio_mixer = val; + } break; case 0x0801: pas16->irq_stat &= ~val; - if (!(pas16->irq_stat & 0x1f)) + if ((pas16->irq != -1) && !(pas16->irq_stat & 0x1f)) picintc(1 << pas16->irq); break; case 0x0802: @@ -593,22 +1415,22 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->filter = 0; break; case 0x01: - recalc_pas16_filter(0, 17897); + recalc_pas16_filter(17897); break; case 0x02: - recalc_pas16_filter(0, 15909); + recalc_pas16_filter(15909); break; case 0x04: - recalc_pas16_filter(0, 2982); + recalc_pas16_filter(2982); break; case 0x09: - recalc_pas16_filter(0, 11931); + recalc_pas16_filter(11931); break; case 0x11: - recalc_pas16_filter(0, 8948); + recalc_pas16_filter(8948); break; case 0x19: - recalc_pas16_filter(0, 5965); + recalc_pas16_filter(5965); break; } } else @@ -618,13 +1440,11 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->irq_ena = val & 0x1f; pas16->irq_stat &= ((val & 0x1f) | 0xe0); - if (!(pas16->irq_stat & 0x1f)) + if ((pas16->irq != -1) && !(pas16->irq_stat & 0x1f)) picintc(1 << pas16->irq); break; case 0x0c00: - pas16_update(pas16); - break; case 0x0c01: pas16_update(pas16); break; @@ -647,9 +1467,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) if ((val & 0x60) == 0x60) { pas16->midi_uart_out = 0; pas16->midi_uart_in = 0; - } else if (val & 0x18) - pas16->midi_uart_out = 1; - else if (val & 0x04) + } else if ((val & 0x1c) == 0x04) pas16->midi_uart_in = 1; else pas16->midi_uart_out = 1; @@ -672,6 +1490,45 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->fifo_stat = val; break; + case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ + case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ + if (pas16->has_scsi) { + port = (port & 0x0003) | ((port & 0x2000) >> 11); + ncr5380_write(port, val, &pas16->scsi->ncr); + } + break; + + case 0x4000: + if (pas16->has_scsi) { + pas16->timeout_count = val; + if (timer_is_enabled(&pas16->scsi_timer)) + timer_disable(&pas16->scsi_timer); + timer_set_delay_u64(&pas16->scsi_timer, (val & 0x3f) * PASSCSICONST); + } + break; + + case 0x4001: + if (pas16->has_scsi) { + pas16->timeout_status = val & 0x7f; + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + } + break; + + case 0x5c00: + if (pas16->has_scsi) + ncr53c400_simple_write(val, pas16->scsi); + break; + case 0x5c03: + if (pas16->has_scsi) { + if (val & 0x80) { + pas16->scsi->ncr.irq_state = 0; + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + } + } + break; + case 0x7c01: pas16->enhancedscsi = val; break; @@ -701,6 +1558,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8003: pas16->sys_conf_4 = val; + if (pas16->has_scsi && (pas16->scsi_irq != -1) && !(val & 0x20)) + picintc(1 << pas16->scsi_irq); break; case 0xbc00: @@ -723,13 +1582,15 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf002: pas16->io_conf_3 = val; - pas16->irq = val & 0x0f; - if (pas16->irq <= 6) - pas16->irq++; - else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) - pas16->irq += 3; - else - pas16->irq += 4; + if (pas16->irq != -1) + picintc(1 << pas16->irq); + pas16->irq = pas16_irq_convert(val & 0x0f); + if (pas16->has_scsi) { + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + pas16->scsi_irq = pas16_irq_convert(val >> 4); + ncr5380_set_irq(&pas16->scsi->ncr, pas16->scsi_irq); + } pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; @@ -822,19 +1683,17 @@ pas16_dma_channel_read(pas16_t *pas16, int channel) } static uint16_t -pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) +pas16_dma_readb(pas16_t *pas16) { - uint16_t ret; + const uint16_t ret = pas16_dma_channel_read(pas16, pas16->dma); - ret = pas16_dma_channel_read(pas16, pas16->dma); - - pas16->ticks += timer1_ticks; + pas16->ticks++; return ret; } static uint16_t -pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) +pas16_dma_readw(pas16_t *pas16, const uint8_t timer1_ticks) { uint16_t ret; @@ -853,29 +1712,23 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) static uint16_t pas16_readdmab(pas16_t *pas16) { - uint16_t ret; - if (pas16->dma >= 5) { if (pas16->dma8_ff) pas16->dma8_dat >>= 8; else - pas16->dma8_dat = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16); pas16->dma8_ff = !pas16->dma8_ff; } else - pas16->dma8_dat = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16); - ret = ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; - - return ret; + return ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; } static uint16_t pas16_readdmaw_mono(pas16_t *pas16) { - uint16_t ret; - - ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); + const uint16_t ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); return ret; } @@ -930,11 +1783,10 @@ pas16_readdma_stereo(pas16_t *pas16) } static void -pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer0(const int new_out, UNUSED(int old_out), void *priv) { - pitf_t *pit = (pitf_t *) priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; - uint16_t temp; + const pitf_t *pit = (const pitf_t *) priv; + pas16_t * pas16 = (pas16_t *) pit->dev_priv; if (!pas16->pit->counters[0].gate) return; @@ -945,6 +1797,8 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16_update_irq(pas16); if (((pas16->pcm_ctrl & PAS16_PCM_ENA) == PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + uint16_t temp; + pas16->ticks = 0; if (pas16->pcm_ctrl & PAS16_PCM_MONO) { @@ -981,7 +1835,8 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16->irq_stat |= PAS16_INT_SAMP; if (pas16->irq_ena & PAS16_INT_SAMP) { pas16_log("INT SAMP.\n"); - picint(1 << pas16->irq); + if (pas16->irq != -1) + picint(1 << pas16->irq); } pas16_update(pas16); @@ -989,10 +1844,10 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) } static void -pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer1(const int new_out, UNUSED(int old_out), void *priv) { - pitf_t *pit = (pitf_t * )priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; + const pitf_t *pit = (pitf_t * )priv; + pas16_t * pas16 = (pas16_t *) pit->dev_priv; if (!pas16->pit->counters[1].gate) return; @@ -1002,7 +1857,8 @@ pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) if (pas16->irq_ena & PAS16_INT_PCM) { pas16->irq_stat |= PAS16_INT_PCM; pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); - picint(1 << pas16->irq); + if (pas16->irq != -1) + picint(1 << pas16->irq); } } } @@ -1054,7 +1910,7 @@ pas16_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) pas16->sysex = 1; for (uint32_t i = 0; i < len; i++) { if (pas16->midi_r == pas16->midi_w) - return (len - i); + return (int) (len - i); pas16->midi_queue[pas16->midi_w++] = buffer[i]; pas16->midi_w &= 0xff; } @@ -1072,38 +1928,258 @@ pas16_update(pas16_t *pas16) } } else { for (; pas16->pos < sound_pos_global; pas16->pos++) { - pas16->pcm_buffer[0][pas16->pos] = 0; - pas16->pcm_buffer[1][pas16->pos] = 0; -#ifdef CROSS_CHANNEL - if (pas16->pcm_ctrl & 0x08) - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; - if (pas16->pcm_ctrl & 0x04) - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_r; - if (pas16->pcm_ctrl & 0x02) - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_l; - if (pas16->pcm_ctrl & 0x01) - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; -#else - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; -#endif + pas16->pcm_buffer[0][pas16->pos] = (int16_t) pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] = (int16_t) pas16->pcm_dat_r; } } } void -pas16_get_buffer(int32_t *buffer, int len, void *priv) +pasplus_get_buffer(int32_t *buffer, int len, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pas16_t * pas16 = (pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); - for (int c = 0; c < len * 2; c++) { - buffer[c] += (int32_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; - if (pas16->filter) - buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1]) / 1.3) / 2.0; + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l += pas16->dsp.buffer[c]; + out_r += pas16->dsp.buffer[c + 1]; + + if (pas16->filter) { + /* We divide by 3 to get the volume down to normal. */ + out_l += low_fir_pas16(0, (double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l; + out_r += low_fir_pas16(1, (double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r; + } else { + out_l += ((double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l; + out_r += ((double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r; + } + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(0, 0, out_l) * bass_treble); + out_r += (low_iir(0, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(0, 0, out_l) * bass_treble); + out_r += (high_iir(0, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + pas16->pos = 0; + pas16->dsp.pos = 0; +} + +void +pasplus_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(1, 0, out_l) * bass_treble); + out_r += (low_iir(1, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(1, 0, out_l) * bass_treble); + out_r += (high_iir(1, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + pas16->opl.reset_buffer(pas16->opl.priv); +} + +void +pasplus_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (*buffer) * cd * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(2, channel, c) * bass_treble); else - buffer[c] += ((pas16->pcm_buffer[c & 1][c >> 1] / 1.3) / 2); + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pasplus_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const double spk = channel ? mixer->speaker_r : mixer->speaker_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (*buffer) * spk * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pas16_get_buffer(int32_t *buffer, int len, void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + + sb_dsp_update(&pas16->dsp); + pas16_update(pas16); + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l += (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; + out_r += (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; + + if (pas16->filter) { + /* We divide by 3 to get the volume down to normal. */ + out_l += (low_fir_pas16(0, (double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l) / 3.0; + out_r += (low_fir_pas16(1, (double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r) / 3.0; + } else { + out_l += (((double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l) / 3.0; + out_r += (((double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r) / 3.0; + } + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(0, 0, out_l) * bass_treble); + out_r += (low_iir(0, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(0, 0, out_l) * bass_treble); + out_r += (high_iir(0, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } pas16->pos = 0; @@ -1113,15 +2189,127 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) void pas16_get_music_buffer(int32_t *buffer, int len, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; - const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); - for (int c = 0; c < len * 2; c++) - buffer[c] += opl_buf[c]; + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(1, 0, out_l) * bass_treble); + out_r += (low_iir(1, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(1, 0, out_l) * bass_treble); + out_r += (high_iir(1, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } pas16->opl.reset_buffer(pas16->opl.priv); } +void +pas16_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (((*buffer) * cd) / 3.0) * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pas16_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const double spk = channel ? mixer->speaker_r : mixer->speaker_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (((*buffer) * spk) / 3.0) * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + static void pas16_speed_changed(void *priv) { @@ -1141,12 +2329,13 @@ pas16_init(const device_t *info) } pas16->type = info->local & 0xff; + pas16->has_scsi = (!pas16->type) || (pas16->type & 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); - mpu401_init(pas16->mpu, 0, 0, M_INTELLIGENT, device_get_config_int("receive_input401")); + mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->sb_compat_base = 0x0000; @@ -1154,10 +2343,22 @@ pas16_init(const device_t *info) io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pas16->this_id = 0xbc + pas16_next; + if (pas16->has_scsi) { + pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); + other_scsi_present++; + } + pas16->pit = device_add(&i8254_ext_io_fast_device); pas16_reset(pas16); pas16->pit->dev_priv = pas16; pas16->irq = pas16->type ? 10 : 5; + pas16->io_conf_3 = pas16->type ? 0x07 : 0x04; + if (pas16->has_scsi) { + pas16->scsi_irq = pas16->type ? 11 : 7; + pas16->io_conf_3 |= (pas16->type ? 0x80 : 0x60); + ncr5380_set_irq(&pas16->scsi->ncr, pas16->scsi_irq); + } pas16->dma = 3; for (uint8_t i = 0; i < 3; i++) pitf_ctr_set_gate(pas16->pit, i, 0); @@ -1168,12 +2369,34 @@ pas16_init(const device_t *info) pitf_ctr_set_using_timer(pas16->pit, 1, 0); pitf_ctr_set_using_timer(pas16->pit, 2, 0); - sound_add_handler(pas16_get_buffer, pas16); - music_add_handler(pas16_get_music_buffer, pas16); + if (pas16->type) { + sound_add_handler(pas16_get_buffer, pas16); + music_add_handler(pas16_get_music_buffer, pas16); + sound_set_cd_audio_filter(pas16_filter_cd_audio, pas16); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(pas16_filter_pc_speaker, pas16); + } else { + sound_add_handler(pasplus_get_buffer, pas16); + music_add_handler(pasplus_get_music_buffer, pas16); + sound_set_cd_audio_filter(pasplus_filter_cd_audio, pas16); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(pasplus_filter_pc_speaker, pas16); + } if (device_get_config_int("receive_input")) midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + for (uint8_t i = 0; i < 16; i++) { + if (i < 6) + lmc1982_bass_treble_4bits[i] = pow(10.0, (-((double) (12 - (i << 1))) / 10.0)); + else if (i == 6) + lmc1982_bass_treble_4bits[i] = 0.0; + else if ((i > 6) && (i <= 12)) + lmc1982_bass_treble_4bits[i] = 1.0 - pow(10.0, ((double) ((i - 6) << 1) / 10.0)); + else + lmc1982_bass_treble_4bits[i] = 1.0 - pow(10.0, 1.2); + } + pas16_next++; return pas16; @@ -1190,6 +2413,13 @@ pas16_close(void *priv) } static const device_config_t pas16_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input401", .description = "Receive input (MPU-401)", @@ -1221,12 +2451,25 @@ const device_t pasplus_device = { .config = pas16_config }; - const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .local = 0x0f, + .init = pas16_init, + .close = pas16_close, + .reset = pas16_reset, + { .available = NULL }, + .speed_changed = pas16_speed_changed, + .force_redraw = NULL, + .config = pas16_config +}; + +const device_t pas16d_device = { + .name = "Pro Audio Spectrum 16", + .internal_name = "pas16", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0x0c, .init = pas16_init, .close = pas16_close, .reset = pas16_reset, diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 13baa3621..9dc7724a4 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -43,6 +43,7 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +#define PNP_ROM_SB_16_PNP "roms/sound/creative/CTL0024A.BIN" #define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" #define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" #define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" @@ -50,6 +51,10 @@ #define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" #define PNP_ROM_SB_AWE64 "roms/sound/creative/CTL009DA.BIN" #define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" +/* TODO: Find real ESS PnP ROM dumps. */ +#define PNP_ROM_ESS0100 "roms/sound/ess/ESS0100.BIN" +#define PNP_ROM_ESS0102 "roms/sound/ess/ESS0102.BIN" +#define PNP_ROM_ESS0968 "roms/sound/ess/ESS0968.BIN" /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ @@ -99,92 +104,6 @@ static const double sb_att_3dbstep_3bits[] = { static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; static const int sb_pro_mcv_irqs[4] = { 7, 5, 3, 3 }; -/* Each card in the SB16 family has a million variants, and it shows in the large variety of device IDs for the PnP models. - This ROM was reconstructed in a best-effort basis around a pnpdump output log found in a forum. */ -static uint8_t sb_16_pnp_rom[] = { - // clang-format off - 0x0e, 0x8c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0024, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x11, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', '1', '6', ' ', 'P', 'n', 'P', /* ANSI identifier */ - - 0x16, 0x0e, 0x8c, 0x00, 0x31, 0x00, 0x65, /* logical device CTL0031, supports vendor-specific registers 0x39/0x3A/0x3D/0x3F */ - 0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x20, 0x00, /* IRQ 5 */ - 0x2a, 0x02, 0x08, /* DMA 1, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0x20, 0x12, /* DMA 5, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x01, 0x10, /* I/O 0x220, decodes 16-bit, 1-byte alignment, 16 addresses */ - 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x01, 0x02, /* I/O 0x330, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x38, /* end dependent functions */ - - 0x16, 0x0e, 0x8c, 0x20, 0x11, 0x00, 0x5a, /* logical device CTL2011, supports vendor-specific registers 0x39/0x3B/0x3C/0x3E */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x82, 0x03, 0x00, 'I', 'D', 'E', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x02, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x02, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x8c, /* IRQ 10/11/15 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x01, 0x08, 0x08, /* I/O 0x100-0x1F8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x03, 0xfe, 0x03, 0x02, 0x02, /* I/O 0x300-0x3FE, decodes 16-bit, 2-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0x00, 0x80, /* IRQ 15 */ - 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x01, 0x08, /* I/O 0x170, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x76, 0x03, 0x76, 0x03, 0x01, 0x02, /* I/O 0x376, decodes 16-bit, 1-byte alignment, 1 addresses */ - 0x38, /* end dependent functions */ - - 0x16, 0x41, 0xd0, 0xff, 0xff, 0x00, 0xda, /* logical device PNPFFFF, supports vendor-specific registers 0x38/0x39/0x3B/0x3C/0x3E */ - 0x82, 0x08, 0x00, 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x01, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 1 address */ - - 0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */ - 0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */ - 0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ - // clang-format on -}; - #ifdef ENABLE_SB_LOG int sb_do_log = ENABLE_SB_LOG; @@ -207,11 +126,9 @@ sb_log(const char *fmt, ...) static void sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double out_mono = 0.0; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double out_mono; sb_dsp_update(&sb->dsp); @@ -219,9 +136,8 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) cms_update(&sb->cms); for (int c = 0; c < len * 2; c += 2) { - out_mono = 0.0; - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; @@ -261,25 +177,17 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) static void sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double out_mono = 0.0; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; - - if (!sb->opl_enabled) - return; + const sb_t *sb = (const sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + const int32_t *opl_buf = NULL; opl_buf = sb->opl.update(sb->opl.priv); for (int c = 0; c < len * 2; c += 2) { - out_mono = 0.0; - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; - if (sb->opl_enabled) - out_mono = ((double) opl_buf[c]) * 0.7171630859375; + const double out_mono = ((double) opl_buf[c]) * 0.7171630859375; out_l += out_mono; out_r += out_mono; @@ -318,18 +226,16 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) } void -sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_buffer_sbpro(int32_t *buffer, const int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; sb_dsp_update(&sb->dsp); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { @@ -354,11 +260,11 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; const int32_t *opl2_buf = NULL; if (!sb->opl_enabled) @@ -380,7 +286,8 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) /* Two chips for LEFT and RIGHT channels. Each chip stores data into the LEFT channel only (no sample alternating.) */ out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; + if (opl2_buf != NULL) + out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; } else { out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; @@ -404,42 +311,27 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) void sbpro_filter_cd_audio(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + double c = ((*buffer * cd) / 3.0) * master; - c = (*buffer * cd) / 3.0; - *buffer = c * master; + *buffer = c; } static void sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int c_emu8k = 0; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; sb_dsp_update(&sb->dsp); - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); - - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } + double out_l = 0.0; + double out_r = 0.0; if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ @@ -460,7 +352,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_l > 8) out_l += (low_iir(0, 0, out_l) * bass_treble); - else if (mixer->bass_l < 8) + else out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); } @@ -469,7 +361,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_r > 8) out_r += (low_iir(0, 1, out_r) * bass_treble); - else if (mixer->bass_r < 8) + else out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } @@ -478,7 +370,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_l > 8) out_l += (high_iir(0, 0, out_l) * bass_treble); - else if (mixer->treble_l < 8) + else out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); } @@ -487,7 +379,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_r > 8) out_r += (high_iir(0, 1, out_r) * bass_treble); - else if (mixer->treble_r < 8) + else out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } @@ -496,31 +388,23 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } sb->dsp.pos = 0; - - if (sb->dsp.sb_type > SB16) - sb->emu8k.pos = 0; } static void -sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) +sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int dsp_rec_pos = sb->dsp.record_pos_write; - int c_record; - int32_t in_l; - int32_t in_r; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const int dsp_rec_pos = sb->dsp.record_pos_write; double bass_treble; - const int32_t *opl_buf = NULL; + const int32_t *opl_buf = NULL; if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->opl_enabled) { out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; @@ -528,10 +412,10 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ - in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; + int32_t in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? + ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; + int32_t in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? + ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; out_l *= mixer->master_l; out_r *= mixer->master_r; @@ -543,7 +427,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_l > 8) out_l += (low_iir(1, 0, out_l) * bass_treble); - else if (mixer->bass_l < 8) + else out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); } @@ -552,7 +436,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_r > 8) out_r += (low_iir(1, 1, out_r) * bass_treble); - else if (mixer->bass_r < 8) + else out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); } @@ -561,7 +445,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_l > 8) out_l += (high_iir(1, 0, out_l) * bass_treble); - else if (mixer->treble_l < 8) + else out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); } @@ -570,12 +454,13 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_r > 8) out_r += (high_iir(1, 1, out_r) * bass_treble); - else if (mixer->treble_r < 8) + else out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); } if (sb->dsp.sb_enable_i) { - c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); + const int c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); + in_l <<= mixer->input_gain_L; in_r <<= mixer->input_gain_R; @@ -590,8 +475,8 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) else if (in_r > 32767) in_r = 32767; - sb->dsp.record_buffer[c_record & 0xffff] = in_l; - sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r; + sb->dsp.record_buffer[c_record & 0xffff] = (int16_t) in_l; + sb->dsp.record_buffer[(c_record + 1) & 0xffff] = (int16_t) in_r; } buffer[c] += (int32_t) (out_l * mixer->output_gain_L); @@ -605,21 +490,82 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb->opl.reset_buffer(sb->opl.priv); } +static void +sb_get_wavetable_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double bass_treble; + + emu8k_update(&sb->emu8k); + + for (int c = 0; c < len * 2; c += 2) { + double out_l = 0.0; + double out_r = 0.0; + + out_l += (((double) sb->emu8k.buffer[c]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c + 1]) * mixer->fm_r); + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_l]; + + if (mixer->bass_l > 8) + out_l += (low_iir(4, 0, out_l) * bass_treble); + else + out_l = (out_l *bass_treble + low_cut_iir(4, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->bass_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_r]; + + if (mixer->bass_r > 8) + out_r += (low_iir(4, 1, out_r) * bass_treble); + else + out_r = (out_r *bass_treble + low_cut_iir(4, 1, out_r) * (1.0 - bass_treble)); + } + + if (mixer->treble_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_l]; + + if (mixer->treble_l > 8) + out_l += (high_iir(4, 0, out_l) * bass_treble); + else + out_l = (out_l *bass_treble + high_cut_iir(4, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->treble_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_r]; + + if (mixer->treble_r > 8) + out_r += (high_iir(4, 1, out_r) * bass_treble); + else + out_r = (out_l *bass_treble + high_cut_iir(4, 1, out_r) * (1.0 - bass_treble)); + } + + buffer[c] += (int32_t) (out_l * mixer->output_gain_L); + buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); + } + + sb->emu8k.pos = 0; +} + void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + const int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); - - c = ((*buffer) * cd) / 3.0; - c *= master; + double c = (((*buffer) * cd) / 3.0) * master; /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the CPU usage. */ @@ -628,7 +574,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) if (bass > 8) c += (low_iir(2, channel, c) * bass_treble); - else if (bass < 8) + else c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); } @@ -637,7 +583,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) if (treble > 8) c += (high_iir(2, channel, c) * bass_treble); - else if (treble < 8) + else c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); } @@ -647,15 +593,15 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) void sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double spk = mixer->speaker; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const double spk = mixer->speaker; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + const int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + double c; if (mixer->output_filter) c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; @@ -670,7 +616,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) if (bass > 8) c += (low_iir(3, channel, c) * bass_treble); - else if (bass < 8) + else c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); } @@ -679,7 +625,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) if (treble > 8) c += (high_iir(3, channel, c) * bass_treble); - else if (treble < 8) + else c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); } @@ -691,14 +637,12 @@ sb_get_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; - double out_l = 0.0; - double out_r = 0.0; sb_dsp_update(&ess->dsp); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { @@ -765,6 +709,24 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) *buffer = c * master; } +void +ess_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double c; + double spk = mixer->speaker; + double master = channel ? mixer->master_r : mixer->master_l; + + if (mixer->output_filter) + c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; + else + c = ((*buffer) * spk) / 3.0; + c *= master; + + *buffer = c; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -839,7 +801,10 @@ void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *sb = (sb_t *) priv; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + sb_ct1345_mixer_t *mixer = (sb == NULL) ? NULL : &sb->mixer_sbpro; + + if (mixer == NULL) + return; if (!(addr & 1)) { mixer->index = val; @@ -977,7 +942,10 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *sb = (sb_t *) priv; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + sb_ct1745_mixer_t *mixer = (sb == NULL) ? NULL : &sb->mixer_sb16; + + if (mixer == NULL) + return; if (!(addr & 1)) mixer->index = val; @@ -1207,7 +1175,6 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) { const sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp; uint8_t ret = 0xff; if (!(addr & 1)) @@ -1310,6 +1277,8 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; } switch (sb->dsp.sb_16_dmanum) { + default: + break; case 5: ret |= 0x20; break; @@ -1331,8 +1300,8 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) I haven't seen this making any difference, but I'm keeping it for now. */ /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | - ((sb->dsp.sb_irq401) ? 4 : 0); + const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | + ((sb->dsp.sb_irq401) ? 4 : 0); if (sb->dsp.sb_type >= SBAWE32) ret = temp | 0x80; else @@ -1398,15 +1367,22 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) void sb_ct1745_mixer_reset(sb_t *sb) { - sb_ct1745_mixer_write(4, 0, sb); - sb_ct1745_mixer_write(5, 0, sb); + if (sb != NULL) { + sb_ct1745_mixer_write(4, 0, sb); + sb_ct1745_mixer_write(5, 0, sb); + } } void ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *ess = (sb_t *) priv; - ess_mixer_t *mixer = &ess->mixer_ess; + ess_mixer_t *mixer = (ess == NULL) ? NULL : &ess->mixer_ess; + + sb_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + if (mixer == NULL) + return; if (!(addr & 1)) { mixer->index = val; @@ -1506,20 +1482,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ - case 0x30: - case 0x32: - case 0x36: - case 0x38: + case 0x30: case 0x32: case 0x36: case 0x38: case 0x3e: mixer->regs[mixer->index - 0x10] = (val & 0xee); break; - case 0x3a: - case 0x3c: - break; - - case 0x00: - case 0x04: + case 0x00: case 0x04: case 0x3a: case 0x3c: break; case 0x64: @@ -1529,6 +1497,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + sb_log("mpu401_base_addr = %04X\n", mpu401_base_addr); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { @@ -1545,6 +1514,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } } switch ((mixer->regs[0x40] >> 5) & 0x7) { + default: + break; case 0: mpu401_change_addr(ess->mpu, 0x00); mpu401_setirq(ess->mpu, -1); @@ -1600,31 +1571,24 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; mixer->speaker = sb_att_3dbstep_3bits[mixer->regs[0x3c] & 0x07] / 32767.0; - - /* TODO: PC Speaker volume */ } } uint8_t ess_mixer_read(uint16_t addr, void *priv) { - sb_t *ess = (sb_t *) priv; - ess_mixer_t *mixer = &ess->mixer_ess; + const sb_t * ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + uint8_t ret = 0x0a; if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) { + ret = mixer->index; + else switch (mixer->index) { case 0x00: - case 0x04: case 0x0a: case 0x0c: case 0x0e: case 0x14: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: case 0x02: case 0x06: case 0x30: @@ -1632,25 +1596,37 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; + + case 0x04: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + ret = mixer->regs[mixer->index] | 0x11; + break; case 0x40: - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - mixer->ess_id_str_pos++; - if (mixer->ess_id_str_pos >= 4) - mixer->ess_id_str_pos = 0; - return val; - } else { - return mixer->regs[mixer->index]; - } + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else + ret = 0x0a; + break; + + /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ + case 0x64: + ret = 0x00; + break; default: sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0x0a; + sb_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } void @@ -1806,12 +1782,9 @@ sb_16_reply_mca_read(int port, void *priv) } static void -sb_16_reply_mca_write(int port, uint8_t val, void *priv) +sb_16_reply_mca_write(const int port, const uint8_t val, void *priv) { uint16_t addr; - uint16_t mpu401_addr; - int low_dma; - int high_dma; sb_t *sb = (sb_t *) priv; if (port < 0x102) @@ -1865,6 +1838,8 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) sb->pos_regs[port & 7] = val; if (sb->pos_regs[2] & 1) { + uint16_t mpu401_addr; + switch (sb->pos_regs[2] & 0xc4) { case 4: addr = 0x220; @@ -1883,6 +1858,7 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) addr = 0; break; } + switch (sb->pos_regs[2] & 0x18) { case 8: mpu401_addr = 0x330; @@ -1935,8 +1911,8 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) break; } - low_dma = sb->pos_regs[3] & 3; - high_dma = (sb->pos_regs[3] >> 4) & 7; + const int low_dma = sb->pos_regs[3] & 3; + int high_dma = (sb->pos_regs[3] >> 4) & 7; if (!high_dma) high_dma = low_dma; @@ -1984,13 +1960,16 @@ sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv) } static void -sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; uint16_t addr = sb->dsp.sb_addr; - uint8_t val; switch (ld) { + default: + case 4: /* StereoEnhance (32) */ + break; + case 0: /* Audio */ io_removehandler(addr, 0x0004, sb->opl.read, NULL, NULL, @@ -2022,6 +2001,8 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) mpu401_change_addr(sb->mpu, 0); if (config->activate) { + uint8_t val = config->irq[0].irq; + addr = config->io[0].base; if (addr != ISAPNP_IO_DISABLED) { io_sethandler(addr, 0x0004, @@ -2053,7 +2034,6 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) sb->opl.priv); } - val = config->irq[0].irq; if (val != ISAPNP_IRQ_DISABLED) sb_dsp_setirq(&sb->dsp, val); @@ -2086,17 +2066,11 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) case 3: /* Game */ gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); break; - - case 4: /* StereoEnhance (32) */ - break; - - default: - break; } } static void -sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2112,7 +2086,7 @@ sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void * } static void -sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe32_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2133,7 +2107,7 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } static void -sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2154,7 +2128,7 @@ sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } static void -sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_gold_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2173,6 +2147,333 @@ sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, voi } } +static void +ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *config, void *priv) +{ + sb_t *ess = (sb_t *) priv; + uint16_t addr = ess->dsp.sb_addr; + uint8_t val; + + switch (ld) { + case 0: /* Audio */ + io_removehandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + ess->mixer_ess.ess_id_str[2] = 0x00; + ess->mixer_ess.ess_id_str[3] = 0x00; + + addr = ess->opl_pnp_addr; + if (addr) { + ess->opl_pnp_addr = 0; + io_removehandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + if (ess->pnp == 3) + mpu401_change_addr(ess->mpu, 0); + + sb_dsp_setaddr(&ess->dsp, 0); + sb_dsp_setirq(&ess->dsp, 0); + if (ess->pnp == 3) + mpu401_setirq(ess->mpu, -1); + sb_dsp_setdma8(&ess->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_8(&ess->dsp, ISAPNP_DMA_DISABLED); + + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + sb_dsp_setaddr(&ess->dsp, addr); + + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + } + + addr = config->io[1].base; + if (addr != ISAPNP_IO_DISABLED) { + ess->opl_pnp_addr = addr; + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + if (ess->pnp == 3) { + addr = config->io[2].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(ess->mpu, addr); + } + + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) { + sb_dsp_setirq(&ess->dsp, val); + if (ess->pnp == 3) + mpu401_setirq(ess->mpu, val); + } + + val = config->dma[0].dma; + if (val != ISAPNP_DMA_DISABLED) { + sb_dsp_setdma8(&ess->dsp, val); + sb_dsp_setdma16_8(&ess->dsp, val); + } + } + break; + + case 1: + if (ess->pnp == 3) { /* Game */ + gameport_remap(ess->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + } else { /* MPU-401 */ + mpu401_change_addr(ess->mpu, 0); + mpu401_setirq(ess->mpu, -1); + + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(ess->mpu, addr); + + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) + mpu401_setirq(ess->mpu, val); + } + } + break; + + case 2: + if (ess->pnp == 3) /* IDE */ + ide_pnp_config_changed_1addr(0, config, (void *) 3); + else /* Game */ + gameport_remap(ess->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; + + case 3: + if (ess->pnp <= 2) /* IDE */ + ide_pnp_config_changed_1addr(0, config, (void *) 3); + break; + + default: + break; + } +} + +/* This function is common to all the ESS MCA cards. */ +static uint8_t +ess_x688_mca_read(const int port, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const uint8_t ret = ess->pos_regs[port & 7]; + + sb_log("ess_mca_read: port=%04x ret=%02x\n", port, ret); + + return ret; +} + +static void +ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + + if (port < 0x102) + return; + + sb_log("ess_soundpiper_mca_write: port=%04x val=%02x\n", port, val); + + if (ess->dsp.sb_addr != 0x0000) { + io_removehandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, 0); + gameport_remap(ess->gameport, 0); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, 0); + + ess->pos_regs[port & 7] = val; + + if (ess->pos_regs[2] & 1) { + switch (ess->pos_regs[2] & 0x0e) { + default: + ess->dsp.sb_addr = 0x0000; + break; + case 0x08: + ess->dsp.sb_addr = 0x0240; + break; + case 0x0c: + ess->dsp.sb_addr = 0x0220; + break; + } + + if (ess->dsp.sb_addr != 0x0000) { + io_sethandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, ess->pos_regs[3] & 0x02 ? 0x0330 : 0); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, ess->dsp.sb_addr); + gameport_remap(ess->gameport, (ess->pos_regs[3] & 0x01) ? 0x200 : 0); + } + + switch (ess->pos_regs[3] & 0xc0) { + default: + break; + case 0x80: + sb_dsp_setirq(&ess->dsp, 9); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 9); + break; + case 0xa0: + sb_dsp_setirq(&ess->dsp, 5); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 5); + break; + case 0xc0: + sb_dsp_setirq(&ess->dsp, 7); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 7); + break; + case 0xe0: + sb_dsp_setirq(&ess->dsp, 10); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 10); + break; + } + + if (ess->pos_regs[3] & 0x04) { + sb_dsp_setdma8(&ess->dsp, ess->pos_regs[2] >> 4); + sb_dsp_setdma16_8(&ess->dsp, ess->pos_regs[2] >> 4); + } +} + +static void +ess_chipchat_mca_write(int port, uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + + if (port < 0x102) + return; + + sb_log("ess_chipchat_mca_write: port=%04x val=%02x\n", port, val); + + if (ess->dsp.sb_addr != 0x0000) { + io_removehandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, 0); + gameport_remap(ess->gameport, 0); + + mpu401_change_addr(ess->mpu, 0); + + ess->pos_regs[port & 7] = val; + + if (ess->pos_regs[2] & 1) { + ess->dsp.sb_addr = (ess->pos_regs[2] == 0x51) ? 0x0220 : 0x0000; + + if (ess->dsp.sb_addr != 0x0000) { + io_sethandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, (ess->pos_regs[2] == 0x51) ? 0x0330 : 0); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, ess->dsp.sb_addr); + gameport_remap(ess->gameport, (ess->pos_regs[2] == 0x51) ? 0x200 : 0); + } + + if (ess->pos_regs[2] == 0x51) { + sb_dsp_setirq(&ess->dsp, 7); + mpu401_setirq(ess->mpu, 7); + + sb_dsp_setdma8(&ess->dsp, 1); + sb_dsp_setdma16_8(&ess->dsp, 1); + } +} + void * sb_1_init(UNUSED(const device_t *info)) { @@ -2180,8 +2481,8 @@ sb_1_init(UNUSED(const device_t *info)) 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t * sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); @@ -2231,8 +2532,8 @@ sb_15_init(UNUSED(const device_t *info)) 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t * sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); @@ -2550,8 +2851,7 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sbpro, sb); + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); /* I/O handlers activated in sb_pro_mcv_write */ @@ -2593,17 +2893,17 @@ sb_pro_compat_init(UNUSED(const device_t *info)) static void * sb_16_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t mpu_addr = device_get_config_hex16("base401"); + sb_t *sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); + const uint16_t mpu_addr = device_get_config_hex16("base401"); memset(sb, 0x00, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - fm_driver_get(info->local, &sb->opl); + fm_driver_get((int) (intptr_t) info->local, &sb->opl); - sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B)); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2633,12 +2933,8 @@ sb_16_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) { - if (info->local == FM_YMF289B) - sound_add_handler(sb_get_music_buffer_sb16_awe32, sb); - else - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); - } + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2679,8 +2975,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2705,6 +3000,12 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) return sb; } +static int +sb_16_pnp_available(void) +{ + return rom_present(PNP_ROM_SB_16_PNP); +} + static void * sb_16_pnp_init(UNUSED(const device_t *info)) { @@ -2723,8 +3024,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2740,8 +3040,19 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); device_add(&ide_qua_pnp_device); + other_ide_present++; - isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + uint8_t *pnp_rom = NULL; + + FILE *fp = rom_fopen(PNP_ROM_SB_16_PNP, "rb"); + if (fp) { + if (fread(sb->pnp_rom, 1, 390, fp) == 390) + pnp_rom = sb->pnp_rom; + fclose(fp); + } + + isapnp_add_card(pnp_rom, 390, sb_16_pnp_config_changed, + NULL, NULL, NULL, sb); sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_setaddr(&sb->dsp, 0); @@ -2790,8 +3101,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2833,7 +3143,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) switch (info->local) { case 0: case 1: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, + isapnp_add_card(pnp_rom, 512, sb_vibra16_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -2868,14 +3178,14 @@ sb_16_compat_init(const device_t *info) sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); + sb->opl_enabled = 1; sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); - mpu401_init(sb->mpu, 0, 0, M_UART, info->local); + mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local); sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb->gameport = gameport_add(&gameport_pnp_device); @@ -2968,6 +3278,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sound_add_handler(sb_get_buffer_sb16_awe32, sb); if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + wavetable_add_handler(sb_get_wavetable_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -3014,8 +3325,8 @@ sb_awe32_pnp_init(const device_t *info) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + wavetable_add_handler(sb_get_wavetable_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -3032,8 +3343,10 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - if ((info->local != 2) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) { device_add(&ide_qua_pnp_device); + other_ide_present++; + } const char *pnp_rom_file = NULL; switch (info->local) { @@ -3112,15 +3425,19 @@ sb_awe32_pnp_init(const device_t *info) } static void * -ess_1688_init(UNUSED(const device_t *info)) +ess_x688_init(UNUSED(const device_t *info)) { sb_t *ess = calloc(sizeof(sb_t), 1); - uint16_t addr = device_get_config_hex16("base"); + const uint16_t addr = device_get_config_hex16("base"); + const uint16_t ide_ctrl = (const uint16_t) device_get_config_int("ide_ctrl"); + const uint16_t ide_base = ide_ctrl & 0x0fff; + const uint16_t ide_side = ide_base + 0x0206; + const uint16_t ide_irq = ide_ctrl >> 12; - fm_driver_get(FM_ESFM, &ess->opl); + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); @@ -3152,26 +3469,196 @@ ess_1688_init(UNUSED(const device_t *info)) sound_add_handler(sb_get_buffer_ess, ess); music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); - if (device_get_config_int("receive_input")) { + if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + if (info->local) { + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); } - ess->mixer_ess.ess_id_str[0] = 0x16; - ess->mixer_ess.ess_id_str[1] = 0x88; - ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_ess.ess_id_str[3] = addr & 0xff; - - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - /* NOTE: The MPU is initialized disabled and with no IRQ assigned. - * It will be later initialized by the guest OS's drivers. */ - mpu401_init(ess->mpu, 0, -1, M_UART, 1); - sb_dsp_set_mpu(&ess->dsp, ess->mpu); - ess->gameport = gameport_add(&gameport_pnp_device); ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); + if (ide_base > 0x0000) { + device_add(&ide_qua_pnp_device); + ide_set_base(4, ide_base); + ide_set_side(4, ide_side); + ide_set_irq(4, ide_irq); + other_ide_present++; + } + + return ess; +} + +static int +ess_688_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0100); +} + +static int +ess_1688_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0102); +} + +static int +ess_1688_968_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0968); +} + +static void * +ess_x688_pnp_init(UNUSED(const device_t *info)) +{ + sb_t *ess = calloc(sizeof(sb_t), 1); + int len = 512; + + ess->pnp = 1 + (int) info->local; + + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + ess->mixer_enabled = 1; + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + /* Not on ES688. */ + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = 0x00; + ess->mixer_ess.ess_id_str[3] = 0x00; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + + device_add(&ide_qua_pnp_device); + other_ide_present++; + + const char *pnp_rom_file = NULL; + switch (info->local) { + case 0: + pnp_rom_file = PNP_ROM_ESS0100; + len = 145; + break; + + case 1: + pnp_rom_file = PNP_ROM_ESS0102; + len = 145; + break; + + case 2: + pnp_rom_file = PNP_ROM_ESS0968; + len = 135; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(ess->pnp_rom, 1, len, fp) == len) + pnp_rom = ess->pnp_rom; + fclose(fp); + } + } + + isapnp_add_card(pnp_rom, len, ess_x688_pnp_config_changed, + NULL, NULL, NULL, ess); + + sb_dsp_setaddr(&ess->dsp, 0); + sb_dsp_setirq(&ess->dsp, 0); + sb_dsp_setdma8(&ess->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_8(&ess->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(ess->mpu, 0); + + ess->gameport_addr = 0; + gameport_remap(ess->gameport, 0); + + ide_remove_handlers(3); + + return ess; +} + +static void * +ess_x688_mca_init(UNUSED(const device_t *info)) +{ + sb_t *ess = calloc(1, sizeof(sb_t)); + + ess->opl_enabled = 1; + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + ess->mixer_enabled = 1; + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); + + if (info->local) { + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + } + + ess->gameport = gameport_add(&gameport_device); + + mpu401_change_addr(ess->mpu, 0); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + ess->gameport_addr = 0; + gameport_remap(ess->gameport, 0); + + /* I/O handlers activated in sb_pro_mcv_write */ + if (info->local == 2) { + mca_add(ess_x688_mca_read, ess_chipchat_mca_write, sb_mcv_feedb, NULL, ess); + ess->pos_regs[0] = 0x50; + ess->pos_regs[1] = 0x51; + } else { + mca_add(ess_x688_mca_read, ess_soundpiper_mca_write, sb_mcv_feedb, NULL, ess); + ess->pos_regs[0] = 0x30; + ess->pos_regs[1] = 0x51; + } + return ess; } @@ -4444,6 +4931,130 @@ static const device_config_t sb_awe64_gold_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t ess_688_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x230", + .value = 0x230 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x250", + .value = 0x250 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "ide_ctrl", + .description = "IDE Controller", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "Disabled", + .value = 0x0000 + }, + { + .description = "0x170, IRQ 15", + .value = 0xf170 + }, + { + .description = "0x1E8, IRQ 11", + .value = 0xb1e8 + }, + { + .description = "0x168, IRQ 9", + .value = 0x9168 + }, + { + .description = "0x168, IRQ 10", + .value = 0xa168 + }, + { .description = "" } + } + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + static const device_config_t ess_1688_config[] = { { .name = "base", @@ -4526,18 +5137,95 @@ static const device_config_t ess_1688_config[] = { } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, + .name = "ide_ctrl", + .description = "IDE Controller", + .type = CONFIG_HEX16, .default_string = "", - .default_int = 1 + .default_int = 0x0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "Disabled", + .value = 0x0000 + }, + { + .description = "0x170, IRQ 15", + .value = 0xf170 + }, + { + .description = "0x1E8, IRQ 11", + .value = 0xb1e8 + }, + { + .description = "0x168, IRQ 9", + .value = 0x9168 + }, + { + .description = "0x168, IRQ 10", + .value = 0xa168 + }, + { .description = "" } + } }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 0 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_config_t ess_688_pnp_config[] = { + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_config_t ess_1688_pnp_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -4761,7 +5449,7 @@ const device_t sb_16_pnp_device = { .init = sb_16_pnp_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + { .available = sb_16_pnp_available }, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -4879,12 +5567,40 @@ const device_t sb_awe64_gold_device = { .config = sb_awe64_gold_config }; +const device_t ess_688_device = { + .name = "ESS AudioDrive ES688", + .internal_name = "ess_es688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_x688_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_config +}; + +const device_t ess_ess0100_pnp_device = { + .name = "ESS AudioDrive ES688 (ESS0100) PnP", + .internal_name = "ess_ess0100_pnp", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_688_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_pnp_config +}; + const device_t ess_1688_device = { .name = "ESS AudioDrive ES1688", .internal_name = "ess_es1688", .flags = DEVICE_ISA, - .local = 0, - .init = ess_1688_init, + .local = 1, + .init = ess_x688_init, .close = sb_close, .reset = NULL, { .available = NULL }, @@ -4892,3 +5608,75 @@ const device_t ess_1688_device = { .force_redraw = NULL, .config = ess_1688_config }; + +const device_t ess_ess0102_pnp_device = { + .name = "ESS AudioDrive ES1688 (ESS0102) PnP", + .internal_name = "ess_ess0102_pnp", + .flags = DEVICE_ISA, + .local = 1, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_1688_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_ess0968_pnp_device = { + .name = "ESS AudioDrive ES1688 (ESS0968) PnP", + .internal_name = "ess_ess0968_pnp", + .flags = DEVICE_ISA, + .local = 2, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_1688_968_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_soundpiper_16_mca_device = { + .name = "SoundPiper 16 (ESS AudioDrive ES688) MCA", + .internal_name = "soundpiper_16_mca", + .flags = DEVICE_MCA, + .local = 0, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_pnp_config +}; + +const device_t ess_soundpiper_32_mca_device = { + .name = "SoundPiper 32 (ESS AudioDrive ES1688) MCA", + .internal_name = "soundpiper_32_mca", + .flags = DEVICE_MCA, + .local = 1, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_chipchat_16_mca_device = { + .name = "ChipChat 16 (ESS AudioDrive ES1688) MCA", + .internal_name = "chipchat_16_mca", + .flags = DEVICE_MCA, + .local = 2, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + + diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 927a06d8c..9c148339d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -37,38 +37,44 @@ #define ESPCM_3 5 /* ESPCM_2? */ #define ESPCM_1 7 -#define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes +#define ESPCM_4E 8 /* For differentiating between 4-bit encoding and decoding modes. */ -/*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ +/* The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb. */ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 +enum { + DSP_S_NORMAL = 0, + DSP_S_RESET, + DSP_S_RESET_WAIT +}; + void pollsb(void *priv); void sb_poll_i(void *priv); static int sbe2dat[4][9] = { - {0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106}, - { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, - { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151}, - { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } + { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, + { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, + { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, + { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } }; static int sb_commands[256] = { - -1, 2, -1, 0, 1, 2, -1, 0, 1, -1, -1, -1, -1, -1, 2, 1, - 1, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, -1, 0, -1, -1, 0, - 0, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, + -1, 2, -1, 0, 1, 2, -1, 0, 1, -1, -1, -1, -1, -1, 2, 1, + 1, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, -1, 0, -1, -1, 0, + 0, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 2, 2, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, + 1, 2, 2, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1, -1, 0, -1, 0, - 2, 2, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, - 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1, -1, 0, -1, 0, + 2, 2, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, - 1, 0, 1, 0, 1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, + 1, 0, 1, 0, 1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 }; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; @@ -76,33 +82,33 @@ uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0 /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; uint8_t adjustMap4[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 }; int8_t scaleMap26[40] = { - 0, 1, 2, 3, 0, -1, -2, -3, - 1, 3, 5, 7, -1, -3, -5, -7, - 2, 6, 10, 14, -2, -6, -10, -14, + 0, 1, 2, 3, 0, -1, -2, -3, + 1, 3, 5, 7, -1, -3, -5, -7, + 2, 6, 10, 14, -2, -6, -10, -14, 4, 12, 20, 28, -4, -12, -20, -28, 5, 15, 25, 35, -5, -15, -25, -35 }; uint8_t adjustMap26[40] = { - 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, @@ -110,15 +116,17 @@ uint8_t adjustMap26[40] = { }; int8_t scaleMap2[24] = { - 0, 1, 0, -1, 1, 3, -1, -3, - 2, 6, -2, -6, 4, 12, -4, -12, + 0, 1, 0, -1, 1, 3, -1, -3, + 2, 6, -2, -6, 4, 12, -4, -12, 8, 24, -8, -24, 6, 48, -16, -48 }; uint8_t adjustMap2[24] = { - 0, 4, 0, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 4, 252, 4, 252, 4, 252, 4, + 0, 4, 0, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, 252, 0, 252, 0 }; @@ -240,7 +248,7 @@ uint16_t espcm3_dpcm_tables[1024] = }; // clang-format on -double low_fir_sb16_coef[4][SB16_NCoef]; +double low_fir_sb16_coef[5][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -269,20 +277,18 @@ sinc(double x) } static void -recalc_sb16_filter(int c, int playback_freq) +recalc_sb16_filter(const int c, const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) FREQ_96000; - double gain; + int n; + const double fC = ((double) playback_freq) / (double) FREQ_96000; for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ low_fir_sb16_coef[c][n] = w * h; @@ -290,7 +296,7 @@ recalc_sb16_filter(int c, int playback_freq) low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) gain += low_fir_sb16_coef[c][n]; @@ -300,38 +306,36 @@ recalc_sb16_filter(int c, int playback_freq) } static void -recalc_opl_filter(int c, int playback_freq) +recalc_opl_filter(const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); - double gain; + int n; + const double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_sb16_coef[c][n] = w * h; + low_fir_sb16_coef[1][n] = w * h; } - low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + low_fir_sb16_coef[1][(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_sb16_coef[c][n]; + gain += low_fir_sb16_coef[1][n]; /* Normalise filter, to produce unity gain */ for (n = 0; n < SB16_NCoef; n++) - low_fir_sb16_coef[c][n] /= gain; + low_fir_sb16_coef[1][n] /= gain; } static void -sb_irq_update_pic(void *priv, int set) +sb_irq_update_pic(void *priv, const int set) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; if (set) @@ -368,11 +372,9 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) return; /* NOTE: not on ES1688 or ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 - && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire - { + if (IS_ESS(dsp) && (dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) && !(ESSreg(0xB1) & 0x10)) + /* If ESS playback, and IRQ disabled, do not fire. */ return; - } switch (bit) { default: @@ -391,7 +393,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) } /* NOTE: not on ES1688, apparently; investigate on ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) { + if (IS_ESS(dsp) && (dsp->sb_subtype > SB_SUBTYPE_ESS_ES1688)) { /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire @@ -420,7 +422,7 @@ sb_irqc(sb_dsp_t *dsp, int irq8) } static void -sb_dsp_irq_update(void *priv, int set) +sb_dsp_irq_update(void *priv, const int set) { sb_dsp_t *dsp = (sb_dsp_t *) priv; @@ -509,14 +511,14 @@ void sb_dsp_speed_changed(sb_dsp_t *dsp) { if (dsp->sb_timeo < 256) - dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); + dsp->sblatcho = (double) (TIMER_USEC * (256 - dsp->sb_timeo)); else - dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timeo - 256))); + dsp->sblatcho = ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_timeo - 256))); if (dsp->sb_timei < 256) - dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); + dsp->sblatchi = (double) (TIMER_USEC * (256 - dsp->sb_timei)); else - dsp->sblatchi = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timei - 256))); + dsp->sblatchi = ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_timei - 256))); } void @@ -527,18 +529,16 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) } static unsigned int -sb_ess_get_dma_counter(sb_dsp_t *dsp) +sb_ess_get_dma_counter(const sb_dsp_t *dsp) { - unsigned int c; - - c = (unsigned int) ESSreg(0xA5) << 8U; + unsigned int c = (unsigned int) ESSreg(0xA5) << 8U; c |= (unsigned int) ESSreg(0xA4); return c; } static unsigned int -sb_ess_get_dma_len(sb_dsp_t *dsp) +sb_ess_get_dma_len(const sb_dsp_t *dsp) { return 0x10000U - sb_ess_get_dma_counter(dsp); } @@ -554,12 +554,13 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_autoinit = autoinit; dsp->sb_8_pause = 0; dsp->sb_8_enable = 1; + dsp->dma_ff = 0; if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0; dsp->sb_8_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; } else { @@ -572,7 +573,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); } /* This will be set later for ESS playback/record modes. */ @@ -592,7 +593,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_enable = 0; dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -603,7 +604,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); @@ -623,9 +624,9 @@ sb_start_dma_ess(sb_dsp_t *dsp) real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; if (!!(ESSreg(0xB8) & 8)) - sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, (int) len); else - sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, (int) len); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); @@ -644,7 +645,7 @@ sb_ess_update_dma_status(sb_dsp_t *dsp) { bool dma_en = (ESSreg(0xB8) & 1) ? true : false; - // if the DRQ is disabled, do not start + /* If the DRQ is disabled, do not start. */ if (!(ESSreg(0xB2) & 0x40)) dma_en = false; @@ -660,9 +661,28 @@ sb_ess_update_dma_status(sb_dsp_t *dsp) int sb_8_read_dma(void *priv) { - const sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_t *dsp = (sb_dsp_t *) priv; + int ret; - return dma_channel_read(dsp->sb_8_dmanum); + if (dsp->sb_8_dmanum >= 4) { + if (dsp->dma_ff) { + uint32_t temp = (dsp->dma_data & 0xff00) >> 8; + temp |= (dsp->dma_data & 0xffff0000); + ret = (int) temp; + } else { + dsp->dma_data = dma_channel_read(dsp->sb_8_dmanum); + + if (dsp->dma_data == DMA_NODATA) + return DMA_NODATA; + + ret = dsp->dma_data & 0xff; + } + + dsp->dma_ff = !dsp->dma_ff; + } else + ret = dma_channel_read(dsp->sb_8_dmanum); + + return ret; } int @@ -690,8 +710,8 @@ sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + int ret; + int dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -699,19 +719,18 @@ sb_16_read_dma(void *priv) if (dsp->sb_16_dma_enabled) { /* High DMA channel enabled, either translation is enabled or 16-bit transfers are not supported. */ - if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) - dma_ch = dsp->sb_16_8_dmanum; + dma_ch = dsp->sb_16_8_dmanum; } else /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; - temp = dma_channel_read(dma_ch); + int temp = dma_channel_read(dma_ch); ret = temp; if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { temp = dma_channel_read(dma_ch); if (temp == DMA_NODATA) ret = DMA_NODATA; else { - dma_flags = temp & DMA_OVER; + const int dma_flags = temp & DMA_OVER; temp &= ~DMA_OVER; ret |= (temp << 8) | dma_flags; } @@ -725,9 +744,8 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - - int temp, ret = 0; int dma_ch = dsp->sb_16_dmanum; + int ret; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; @@ -735,12 +753,11 @@ sb_16_write_dma(void *priv, uint16_t val) if (dsp->sb_16_dma_enabled) { /* High DMA channel enabled, either translation is enabled or 16-bit transfers are not supported. */ - if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) - dma_ch = dsp->sb_16_8_dmanum; + dma_ch = dsp->sb_16_8_dmanum; } else /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; - temp = dma_channel_write(dma_ch, val & 0xff); + int temp = dma_channel_write(dma_ch, val & 0xff); ret = temp; if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { temp = dma_channel_write(dma_ch, val >> 8); @@ -760,6 +777,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_irqnum) { + default: + break; case 9: t |= 0x0; break; @@ -781,6 +800,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_8_dmanum) { + default: + break; case 0: t |= 0x5; break; @@ -843,17 +864,17 @@ sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported) } void -sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) +sb_dsp_setdma16_translate(sb_dsp_t *dsp, const int translate) { sb_dsp_log("16-bit to 8-bit translation now: %sabled\n", translate ? "en" : "dis"); dsp->sb_16_dma_translate = translate; } static void -sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +sb_ess_update_reg_a2(sb_dsp_t *dsp, const uint8_t val) { - double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; - int temp = (int) freq; + const double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + const int temp = (int) freq; ESSreg(0xA2) = val; if (dsp->sb_freq != temp) @@ -866,7 +887,7 @@ sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { - double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; + const double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); @@ -877,36 +898,32 @@ sb_ess_update_filter_freq(sb_dsp_t *dsp) } static uint8_t -sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +sb_ess_read_reg(const sb_dsp_t *dsp, const uint8_t reg) { - switch (reg) { - default: - return ESSreg(reg); - } + return ESSreg(reg); } static void sb_ess_update_autolen(sb_dsp_t *dsp) { - dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); + dsp->sb_8_autolen = dsp->sb_16_autolen = (int) sb_ess_get_dma_len(dsp); } static void -sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +sb_ess_write_reg(sb_dsp_t *dsp, const uint8_t reg, uint8_t data) { - uint8_t chg = 0x00; + uint8_t chg; switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ { - double temp; ESSreg(reg) = data; if (data & 0x80) - dsp->sb_freq = 795500UL / (256ul - data); + dsp->sb_freq = (int) (795500UL / (256ul - data)); else - dsp->sb_freq = 397700UL / (128ul - data); - temp = 1000000.0 / dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_freq = (int) (397700UL / (128ul - data)); + const double temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = ((double) TIMER_USEC * temp); dsp->sb_timei = dsp->sb_timeo; break; @@ -953,6 +970,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xB1: /* Legacy Audio Interrupt Control */ ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable switch (data & 0x0C) { + default: + break; case 0x00: dsp->sb_irqnum = 2; break; @@ -972,6 +991,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable switch (data & 0x0C) { + default: + break; case 0x00: dsp->sb_8_dmanum = -1; break; @@ -1033,9 +1054,9 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) { if (dsp->sb_16_enable || dsp->sb_8_enable) { if (dsp->sb_16_enable) - dsp->sb_16_length = sb_ess_get_dma_len(dsp); + dsp->sb_16_length = (int) sb_ess_get_dma_len(dsp); if (dsp->sb_8_enable) - dsp->sb_8_length = sb_ess_get_dma_len(dsp); + dsp->sb_8_length = (int) sb_ess_get_dma_len(dsp); } else dsp->ess_reload_len = 1; } @@ -1122,8 +1143,9 @@ sb_exec_command(sb_dsp_t *dsp) } /* else DSP Status (Obsolete) */ break; case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } break; case 0x07: break; @@ -1209,7 +1231,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); - dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; + dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (int16_t) ((dsp->sb_data[0] ^ 0x80) << 8); // FIXME: What does the ESS AudioDrive do to its filter/sample rate divider registers when emulating this Sound Blaster command? ESSreg(0xA1) = 128 - (397700 / 22050); ESSreg(0xA2) = 256 - (7160000 / (82 * ((4 * 22050) / 10))); @@ -1249,10 +1271,10 @@ sb_exec_command(sb_dsp_t *dsp) mode does not imply such samplerate. Position is increased in sb_poll_i(). */ if (!timer_is_enabled(&dsp->input_timer)) { dsp->sb_timei = 256 - 22; - dsp->sblatchi = TIMER_USEC * 22; + dsp->sblatchi = (double) ((double) TIMER_USEC * 22.0); temp = 1000000 / 22; dsp->sb_freq = temp; - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } break; case 0x24: /* 8-bit single cycle DMA input */ @@ -1275,7 +1297,6 @@ sb_exec_command(sb_dsp_t *dsp) dsp->uart_irq = 1; break; case 0x32: /* MIDI Read Timestamp Poll */ - break; case 0x33: /* MIDI Read Timestamp Interrupt */ break; case 0x34: /* MIDI In poll */ @@ -1302,7 +1323,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x40: /* Set time constant */ dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; - dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); + dsp->sblatcho = dsp->sblatchi = (double) (TIMER_USEC * (256 - dsp->sb_data[0])); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); @@ -1316,21 +1337,20 @@ sb_exec_command(sb_dsp_t *dsp) case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ if (dsp->sb_type >= SB16) { - dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); + dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); - dsp->sb_timeo = 256LL + dsp->sb_freq; + dsp->sb_timeo = 256 + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; dsp->sb_timei = dsp->sb_timeo; - if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) + if (dsp->sb_freq != temp) recalc_sb16_filter(0, dsp->sb_freq); dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; } break; case 0x45: /* Continue Auto-Initialize DMA, 8-bit */ - break; case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ break; case 0x48: /* Set DSP block transfer size */ @@ -1427,7 +1447,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x80: /* Pause DAC */ dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho)); break; case 0x90: /* High speed 8-bit autoinit DMA output */ if (dsp->sb_type >= SB2) @@ -1511,7 +1531,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_pause = 1; break; case 0xD1: /* Speaker on */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { if (dsp->sb_type < SB15) dsp->sb_8_pause = 1; else if (dsp->sb_type < SB16) @@ -1520,7 +1540,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { if (dsp->sb_type < SB15) dsp->sb_8_pause = 1; else if (dsp->sb_type < SB16) @@ -1578,7 +1598,10 @@ sb_exec_command(sb_dsp_t *dsp) } dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; dsp->sbe2count++; - dsp->dma_writeb(dsp->dma_priv, dsp->sbe2); + if (dsp->dma_writeb(dsp->dma_priv, dsp->sbe2)) + /* Undocumented behavior: If write to DMA fails, the byte is written + to the CPU instead. The NT 3.1 Sound Blaster Pro driver relies on this. */ + sb_add_data(dsp, dsp->sbe2); break; case 0xE3: /* DSP copyright */ if (dsp->sb_type >= SB16) { @@ -1598,6 +1621,10 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; case SB_SUBTYPE_ESS_ES1688: // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); @@ -1664,24 +1691,34 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8051_ram[0x30] = dsp->sb_command; } +static void +sb_do_reset(sb_dsp_t *dsp, const uint8_t v) +{ + if (((v & 1) != 0) && (dsp->state != DSP_S_RESET)) { + sb_dsp_reset(dsp); + dsp->sb_read_rp = dsp->sb_read_wp = 0; + dsp->state = DSP_S_RESET; + } else if (((v & 1) == 0) && (dsp->state == DSP_S_RESET)) { + dsp->state = DSP_S_RESET_WAIT; + dsp->sb_read_rp = dsp->sb_read_wp = 0; + sb_add_data(dsp, 0xaa); + } +} + void sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v); + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) + if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE))) a &= 0xfffe; switch (a & 0xF) { case 6: /* Reset */ - if (!dsp->uart_midi) { - if (!(v & 1) && (dsp->sbreset & 1)) { - sb_dsp_reset(dsp); - sb_add_data(dsp, 0xAA); - } - dsp->sbreset = v; - } + sb_do_reset(dsp, v); if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); @@ -1759,79 +1796,101 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) { + if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF))) /* Exception: ESS AudioDrive does not alias port base+0xf */ - if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) { a &= 0xfffe; - } - } switch (a & 0xf) { + case 0x6: + ret = 0xff; + break; case 0xA: /* Read data */ - if (dsp->mpu && dsp->uart_midi) { + if (dsp->mpu && dsp->uart_midi) ret = MPU401_ReadData(dsp->mpu); - } else { - dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; + else { if (dsp->sb_read_rp != dsp->sb_read_wp) { + dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; dsp->sb_read_rp++; dsp->sb_read_rp &= 0xff; } - return dsp->sbreaddat; + ret = dsp->sbreaddat; } + /* Advance the state just in case something reads from here + without reading the status first. */ + if (dsp->state == DSP_S_RESET_WAIT) + dsp->state = DSP_S_NORMAL; break; case 0xC: /* Write data ready */ - if (dsp->sb_8_enable || dsp->sb_type >= SB16) - dsp->busy_count = (dsp->busy_count + 1) & 3; - else - dsp->busy_count = 0; - if (IS_ESS(dsp)) { - if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - } - uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; - uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; /* Unimplemented */ - uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ - uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ - uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ - uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + if (dsp->state == DSP_S_NORMAL) { + if (dsp->sb_8_enable || dsp->sb_type >= SB16) + dsp->busy_count = (dsp->busy_count + 1) & 3; + else + dsp->busy_count = 0; + if (IS_ESS(dsp)) { + if (dsp->wb_full || (dsp->busy_count & 2)) + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; - } - if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x80\n"); - return 0x80; + const uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + const uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + const uint8_t fifo_full = 0; /* Unimplemented */ + const uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ + const uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ + const uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; + const uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ + const uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + + ret = busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + } else if (dsp->wb_full || (dsp->busy_count & 2)) { + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); + if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x80\n"); + ret = 0x80; + } else { + sb_dsp_log("SB Write Data Creative read 0xff\n"); + if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = 0xaa; + else + ret = 0xff; + } + } else if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x00\n"); + ret = 0x00; } else { - sb_dsp_log("SB Write Data Creative read 0xff\n"); - return 0xff; + sb_dsp_log("SB Write Data Creative read 0x7f\n"); + if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = 0x2a; + else + ret = 0x7f; } - } - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x00\n"); - ret = 0x00; - } else { - sb_dsp_log("SB Write Data Creative read 0x7f\n"); - ret = 0x7f; - } + } else + ret = 0xff; break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); dsp->sb_irq8 = dsp->sb_irq16 = 0; dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; - /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ + /* + Only bit 7 is defined but aztech diagnostics fail if the others are set. + Keep the original behavior to not interfere with what's already working. + */ if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); + sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", + (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; } else { sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); - ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa; + else + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + } + if (dsp->state == DSP_S_RESET_WAIT) { + ret &= 0x7f; + dsp->state = DSP_S_NORMAL; } break; case 0xF: /* 16-bit ack */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -1844,6 +1903,8 @@ sb_read(uint16_t a, void *priv) break; } + sb_dsp_log("[%04X:%08X] DSP: [R] %04X = %02X\n", CS, cpu_state.pc, a, ret); + return ret; } @@ -1891,7 +1952,7 @@ sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) for (uint32_t i = 0; i < len; i++) { if (dsp->sb_read_rp == dsp->sb_read_wp) { sb_dsp_log("Length sysex SB = %d\n", len - i); - return (len - i); + return (int) (len - i); } sb_add_data(dsp, buffer[i]); @@ -1952,13 +2013,13 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { /* OPL3 or dual OPL2 is stereo. */ if (dsp->sb_has_real_opl) - recalc_opl_filter(1, FREQ_49716 * 2); + recalc_opl_filter(FREQ_49716 * 2); else recalc_sb16_filter(1, FREQ_48000 * 2); } else { /* OPL2 is mono. */ if (dsp->sb_has_real_opl) - recalc_opl_filter(1, FREQ_49716); + recalc_opl_filter(FREQ_49716); else recalc_sb16_filter(1, FREQ_48000); } @@ -1966,6 +2027,8 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) recalc_sb16_filter(2, FREQ_44100 * 2); /* PC speaker is mono. */ recalc_sb16_filter(3, 18939); + /* E-MU 8000 is stereo. */ + recalc_sb16_filter(4, FREQ_44100 * 2); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); @@ -2061,7 +2124,7 @@ pollsb(void *priv) int ref; int data[2]; - timer_advance_u64(&dsp->output_timer, dsp->sblatcho); + timer_advance_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); if (dsp->sb_8_enable && dsp->sb_pausetime < 0 && dsp->sb_8_output) { sb_dsp_update(dsp); @@ -2073,7 +2136,7 @@ pollsb(void *priv) auto-init DMA but programs the DMA controller to single cycle */ if (data[0] == DMA_NODATA) break; - dsp->sbdat = (data[0] ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((data[0] ^ 0x80) << 8); if (dsp->stereo) { sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2093,7 +2156,7 @@ pollsb(void *priv) data[0] = dsp->dma_readb(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdat = data[0] << 8; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); @@ -2114,8 +2177,8 @@ pollsb(void *priv) data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; + dsp->sbdatl = (int16_t) ((data[0] ^ 0x80) << 8); + dsp->sbdatr = (int16_t) ((data[1] ^ 0x80) << 8); dsp->sb_8_length -= 2; dsp->ess_dma_counter += 2; } @@ -2126,8 +2189,8 @@ pollsb(void *priv) data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; + dsp->sbdatl = (int16_t) (data[0] << 8); + dsp->sbdatr = (int16_t) (data[1] << 8); dsp->sb_8_length -= 2; dsp->ess_dma_counter += 2; } @@ -2152,8 +2215,8 @@ pollsb(void *priv) else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap4[tempi]) & 0xff); + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; @@ -2198,9 +2261,9 @@ pollsb(void *priv) dsp->sbref = 0x00; else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap26[tempi]) & 0xff); - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; if (dsp->sbdacpos >= 3) { @@ -2238,9 +2301,9 @@ pollsb(void *priv) dsp->sbref = 0x00; else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap2[tempi]) & 0xff); - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; if (dsp->sbdacpos >= 4) { @@ -2296,8 +2359,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) espcm_range_map[tempi]; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2392,8 +2455,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) (espcm_range_map[tempi]); + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2444,8 +2507,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) espcm_range_map[tempi]; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2499,7 +2562,7 @@ pollsb(void *priv) data[0] = dsp->dma_readw(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; + dsp->sbdatl = dsp->sbdatr = (int16_t) ((data[0] & 0xffff) ^ 0x8000); dsp->sb_16_length--; dsp->ess_dma_counter += 2; break; @@ -2507,7 +2570,7 @@ pollsb(void *priv) data[0] = dsp->dma_readw(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdatl = dsp->sbdatr = data[0]; + dsp->sbdatl = dsp->sbdatr = (int16_t) (data[0] & 0xffff); dsp->sb_16_length--; dsp->ess_dma_counter += 2; break; @@ -2516,8 +2579,8 @@ pollsb(void *priv) data[1] = dsp->dma_readw(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0] ^ 0x8000; - dsp->sbdatr = data[1] ^ 0x8000; + dsp->sbdatl = (int16_t) ((data[0] & 0xffff) ^ 0x8000); + dsp->sbdatr = (int16_t) ((data[1] & 0xffff) ^ 0x8000); dsp->sb_16_length -= 2; dsp->ess_dma_counter += 4; break; @@ -2526,8 +2589,8 @@ pollsb(void *priv) data[1] = dsp->dma_readw(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0]; - dsp->sbdatr = data[1]; + dsp->sbdatl = (int16_t) (data[0] & 0xffff); + dsp->sbdatr = (int16_t) (data[1] & 0xffff); dsp->sb_16_length -= 2; dsp->ess_dma_counter += 4; break; @@ -2583,7 +2646,7 @@ sb_poll_i(void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; int processed = 0; - timer_advance_u64(&dsp->input_timer, dsp->sblatchi); + timer_advance_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { switch (dsp->sb_8_format) { @@ -2618,16 +2681,17 @@ sb_poll_i(void *priv) dsp->record_pos_read &= 0xFFFF; break; case ESPCM_4E: - // I assume the real hardware double-buffers the blocks or something like that. - // We're not gonna do that here. - dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; + /* + I assume the real hardware double-buffers the blocks or something like that. + We're not gonna do that here. + */ + dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = (int8_t) (dsp->record_buffer[dsp->record_pos_read] >> 8); dsp->espcm_sample_idx++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; if (dsp->espcm_sample_idx >= 19) { - int i, table_addr, sigma, last_sigma; + int i, table_addr; int8_t min_sample = 127, max_sample = -128, s; - uint8_t b; for (i = 0; i < 19; i++) { s = dsp->espcm_sample_buffer[i]; @@ -2639,14 +2703,19 @@ sb_poll_i(void *priv) } } if (min_sample < 0) { - min_sample = -min_sample; + if (min_sample == -128) + min_sample = 127; /* Clip it to make it fit into int8_t. */ + else + min_sample = (int8_t) -min_sample; } if (max_sample < 0) { - max_sample = -max_sample; + if (max_sample == -128) + max_sample = 127; /* Clip it to make it fit into int8_t. */ + else + max_sample = (int8_t) -max_sample; } - if (min_sample > max_sample) { + if (min_sample > max_sample) max_sample = min_sample; - } for (table_addr = 15; table_addr < 256; table_addr += 16) { if (max_sample <= espcm_range_map[table_addr]) { @@ -2656,11 +2725,11 @@ sb_poll_i(void *priv) dsp->espcm_range = table_addr >> 4; for (i = 0; i < 19; i++) { + int last_sigma = 9999; table_addr = dsp->espcm_range << 4; - last_sigma = 9999; s = dsp->espcm_sample_buffer[i]; for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) { - sigma = espcm_range_map[table_addr] - s; + int sigma = espcm_range_map[table_addr] - s; if (sigma < 0) { sigma = -sigma; } @@ -2673,7 +2742,7 @@ sb_poll_i(void *priv) dsp->espcm_code_buffer[i] = table_addr & 0x0F; } - b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); + uint8_t b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); dsp->dma_writeb(dsp->dma_priv, b); dsp->sb_8_length--; dsp->ess_dma_counter++; diff --git a/src/sound/sound.c b/src/sound/sound.c index cf7a7a33c..0611909d8 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -22,25 +22,20 @@ #include #include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/cdrom.h> #include <86box/device.h> #include <86box/filters.h> -#include <86box/hdc_ide.h> #include <86box/machine.h> #include <86box/midi.h> #include <86box/plat.h> #include <86box/thread.h> #include <86box/snd_ac97.h> -#include <86box/snd_azt2316a.h> #include <86box/timer.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> -#include <86box/snd_opl.h> -#include <86box/snd_sb_dsp.h> typedef struct { const device_t *device; @@ -54,10 +49,15 @@ typedef struct { int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 }; int sound_pos_global = 0; int music_pos_global = 0; +int wavetable_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; + static sound_handler_t music_handlers[8]; +static sound_handler_t wavetable_handlers[8]; + +static double cd_audio_volume_lut[256]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; @@ -68,12 +68,18 @@ static int16_t *outbuffer_ex_int16; static int32_t *outbuffer_m; static float *outbuffer_m_ex; static int16_t *outbuffer_m_ex_int16; +static int32_t *outbuffer_w; +static float *outbuffer_w_ex; +static int16_t *outbuffer_w_ex_int16; static int sound_handlers_num; static int music_handlers_num; +static int wavetable_handlers_num; static pc_timer_t sound_poll_timer; static uint64_t sound_poll_latch; static pc_timer_t music_poll_timer; static uint64_t music_poll_latch; +static pc_timer_t wavetable_poll_timer; +static uint64_t wavetable_poll_latch; static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; static float cd_out_buffer[CD_BUFLEN * 2]; @@ -120,52 +126,59 @@ static const device_t sound_internal_device = { static const SOUND_CARD sound_cards[] = { // clang-format off - { &sound_none_device }, - { &sound_internal_device }, - { &acermagic_s20_device }, - { &mirosound_pcm10_device }, - { &adlib_device }, - { &adgold_device }, - { &azt2316a_device }, - { &azt1605_device }, - { &cms_device }, - { &cs4235_device }, - { &cs4236b_device }, - { &gus_device }, - { &sb_1_device }, - { &sb_15_device }, - { &sb_2_device }, - { &sb_pro_v1_device }, - { &sb_pro_v2_device }, - { &sb_16_device }, - { &sb_16_pnp_device }, - { &sb_32_pnp_device }, - { &sb_awe32_device }, - { &sb_awe32_pnp_device }, - { &sb_awe64_value_device }, - { &sb_awe64_device }, - { &sb_awe64_gold_device }, - { &sb_vibra16c_device }, - { &sb_vibra16s_device }, - { &sb_vibra16xv_device }, - { &ssi2001_device }, - { &pasplus_device }, - { &pas16_device }, - { &pssj_isa_device }, - { &tndy_device }, - { &wss_device }, - { &adlib_mca_device }, - { &ncr_business_audio_device }, - { &sb_mcv_device }, - { &sb_pro_mcv_device }, - { &sb_16_reply_mca_device }, - { &cmi8338_device }, - { &cmi8738_device }, - { &es1371_device }, - { &ad1881_device }, - { &cs4297a_device }, - { &ess_1688_device }, - { NULL } + { &sound_none_device }, + { &sound_internal_device }, + { &acermagic_s20_device }, + { &mirosound_pcm10_device }, + { &adlib_device }, + { &adgold_device }, + { &azt2316a_device }, + { &azt1605_device }, + { &cms_device }, + { &cs4235_device }, + { &cs4236b_device }, + { &gus_device }, + { &sb_1_device }, + { &sb_15_device }, + { &sb_2_device }, + { &sb_pro_v1_device }, + { &sb_pro_v2_device }, + { &sb_16_device }, + { &sb_16_pnp_device }, + { &sb_32_pnp_device }, + { &sb_awe32_device }, + { &sb_awe32_pnp_device }, + { &sb_awe64_value_device }, + { &sb_awe64_device }, + { &sb_awe64_gold_device }, + { &sb_vibra16c_device }, + { &sb_vibra16s_device }, + { &sb_vibra16xv_device }, + { &ssi2001_device }, + { &pasplus_device }, + { &pas16_device }, + { &pssj_isa_device }, + { &tndy_device }, + { &wss_device }, + { &adlib_mca_device }, + { &ess_chipchat_16_mca_device }, + { &ncr_business_audio_device }, + { &sb_mcv_device }, + { &sb_pro_mcv_device }, + { &sb_16_reply_mca_device }, + { &ess_soundpiper_16_mca_device }, + { &ess_soundpiper_32_mca_device }, + { &cmi8338_device }, + { &cmi8738_device }, + { &es1371_device }, + { &ad1881_device }, + { &cs4297a_device }, + { &ess_688_device }, + { &ess_ess0100_pnp_device }, + { &ess_1688_device }, + { &ess_ess0102_pnp_device }, + { &ess_ess0968_pnp_device }, + { NULL } // clang-format on }; @@ -205,7 +218,7 @@ sound_card_getdevice(int card) int sound_card_has_config(int card) { - if (!sound_cards[card].device) + if (sound_cards[card].device == NULL) return 0; return device_has_config(sound_cards[card].device) ? 1 : 0; } @@ -234,13 +247,13 @@ void sound_card_init(void) { if ((sound_card_current[0] > SOUND_INTERNAL) && (sound_cards[sound_card_current[0]].device)) - device_add(sound_cards[sound_card_current[0]].device); + device_add_inst(sound_cards[sound_card_current[0]].device, 1); if ((sound_card_current[1] > SOUND_INTERNAL) && (sound_cards[sound_card_current[1]].device)) - device_add(sound_cards[sound_card_current[1]].device); + device_add_inst(sound_cards[sound_card_current[1]].device, 2); if ((sound_card_current[2] > SOUND_INTERNAL) && (sound_cards[sound_card_current[2]].device)) - device_add(sound_cards[sound_card_current[2]].device); + device_add_inst(sound_cards[sound_card_current[2]].device, 3); if ((sound_card_current[3] > SOUND_INTERNAL) && (sound_cards[sound_card_current[3]].device)) - device_add(sound_cards[sound_card_current[3]].device); + device_add_inst(sound_cards[sound_card_current[3]].device, 4); } void @@ -262,9 +275,7 @@ sound_cd_clean_buffers(void) static void sound_cd_thread(UNUSED(void *param)) { - uint32_t lba; - int r; - int pre; + int temp_buffer[2]; int channel_select[2]; double audio_vol_l; double audio_vol_r; @@ -281,47 +292,35 @@ sound_cd_thread(UNUSED(void *param)) sound_cd_clean_buffers(); + temp_buffer[0] = temp_buffer[1] = 0; + for (uint8_t i = 0; i < CDROM_NUM; i++) { if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY)) continue; - lba = cdrom[i].seek_pos; - r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); - if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r) + const uint32_t lba = cdrom[i].seek_pos; + const int r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); + if (!cdrom[i].sound_on || !r) continue; - pre = cdrom_is_pre(&(cdrom[i]), lba); + const int pre = cdrom_is_pre(&(cdrom[i]), lba); + if (cdrom[i].get_volume) { - audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0)); - audio_vol_r = (float) (cdrom[i].get_volume(cdrom[i].priv, 1)); + audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)]; + audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)]; } else { - audio_vol_l = 255.0; - audio_vol_r = 255.0; + audio_vol_l = cd_audio_volume_lut[255]; + audio_vol_r = cd_audio_volume_lut[255]; } - /* Calculate attenuation per the specification. */ - if (audio_vol_l >= 255.0) - audio_vol_l = 1.0; - else if (audio_vol_l > 0.0) - audio_vol_l = (48.0 + (20.0 * log(audio_vol_l / 256.0))) / 48.0; - else - audio_vol_l = 0.0; - - if (audio_vol_r >= 255.0) - audio_vol_r = 1.0; - else if (audio_vol_r > 0.0) - audio_vol_r = (48.0 + (20.0 * log(audio_vol_r / 256.0))) / 48.0; - else - audio_vol_r = 0.0; - if (cdrom[i].get_channel) { - channel_select[0] = cdrom[i].get_channel(cdrom[i].priv, 0); - channel_select[1] = cdrom[i].get_channel(cdrom[i].priv, 1); + channel_select[0] = (int) cdrom[i].get_channel(cdrom[i].priv, 0); + channel_select[1] = (int) cdrom[i].get_channel(cdrom[i].priv, 1); } else { channel_select[0] = 1; channel_select[1] = 2; } - for (uint16_t c = 0; c < CD_BUFLEN * 2; c += 2) { + for (int c = 0; c < CD_BUFLEN * 2; c += 2) { /*Apply ATAPI channel select*/ cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0; @@ -359,17 +358,20 @@ sound_cd_thread(UNUSED(void *param)) cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0); cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0); } else { - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + temp_buffer[0] += (int) trunc(cd_buffer_temp[0]); + temp_buffer[1] += (int) trunc(cd_buffer_temp[1]); - cd_out_buffer_int16[c] += (int16_t) cd_buffer_temp[0]; - cd_out_buffer_int16[c + 1] += (int16_t) cd_buffer_temp[1]; + if (temp_buffer[0] > 32767) + temp_buffer[0] = 32767; + if (temp_buffer[0] < -32768) + temp_buffer[0] = -32768; + if (temp_buffer[1] > 32767) + temp_buffer[1] = 32767; + if (temp_buffer[1] < -32768) + temp_buffer[1] = -32768; + + cd_out_buffer_int16[c] = (int16_t) temp_buffer[0]; + cd_out_buffer_int16[c + 1] = (int16_t) temp_buffer[1]; } } } @@ -425,6 +427,28 @@ music_realloc_buffers(void) } } +static void +wavetable_realloc_buffers(void) +{ + if (outbuffer_w_ex != NULL) { + free(outbuffer_w_ex); + outbuffer_w_ex = NULL; + } + + if (outbuffer_w_ex_int16 != NULL) { + free(outbuffer_w_ex_int16); + outbuffer_w_ex_int16 = NULL; + } + + if (sound_is_float) { + outbuffer_w_ex = calloc(WTBUFLEN * 2, sizeof(float)); + memset(outbuffer_w_ex, 0x00, WTBUFLEN * 2 * sizeof(float)); + } else { + outbuffer_w_ex_int16 = calloc(WTBUFLEN * 2, sizeof(int16_t)); + memset(outbuffer_w_ex_int16, 0x00, WTBUFLEN * 2 * sizeof(int16_t)); + } +} + void sound_init(void) { @@ -436,6 +460,9 @@ sound_init(void) outbuffer_m_ex = NULL; outbuffer_m_ex_int16 = NULL; + outbuffer_w_ex = NULL; + outbuffer_w_ex_int16 = NULL; + outbuffer = NULL; outbuffer = calloc(SOUNDBUFLEN * 2, sizeof(int32_t)); memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); @@ -444,6 +471,22 @@ sound_init(void) outbuffer_m = calloc(MUSICBUFLEN * 2, sizeof(int32_t)); memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + outbuffer_w = NULL; + outbuffer_w = calloc(WTBUFLEN * 2, sizeof(int32_t)); + memset(outbuffer_w, 0x00, WTBUFLEN * 2 * sizeof(int32_t)); + + for (uint16_t i = 0; i < 256; i++) { + double di = (double) i; + + if (di >= 255.0) + di = 1.0; + else if (di > 0.0) + di = (48.0 + (20.0 * log(di / 256.0))) / 48.0; + else + di = 0.0; + + cd_audio_volume_lut[i] = di; + } for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type != CDROM_BUS_DISABLED) @@ -484,6 +527,14 @@ music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void music_handlers_num++; } +void +wavetable_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv) +{ + wavetable_handlers[wavetable_handlers_num].get_buffer = get_buffer; + wavetable_handlers[wavetable_handlers_num].priv = priv; + wavetable_handlers_num++; +} + void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) { @@ -527,7 +578,7 @@ sound_poll(UNUSED(void *priv)) if (outbuffer[c] < -32768) outbuffer[c] = -32768; - outbuffer_ex_int16[c] = outbuffer[c]; + outbuffer_ex_int16[c] = (int16_t) outbuffer[c]; } } @@ -571,7 +622,7 @@ music_poll(UNUSED(void *priv)) if (outbuffer_m[c] < -32768) outbuffer_m[c] = -32768; - outbuffer_m_ex_int16[c] = outbuffer_m[c]; + outbuffer_m_ex_int16[c] = (int16_t) outbuffer_m[c]; } } @@ -584,12 +635,50 @@ music_poll(UNUSED(void *priv)) } } +void +wavetable_poll(UNUSED(void *priv)) +{ + timer_advance_u64(&wavetable_poll_timer, wavetable_poll_latch); + + wavetable_pos_global++; + if (wavetable_pos_global == WTBUFLEN) { + int c; + + memset(outbuffer_w, 0x00, WTBUFLEN * 2 * sizeof(int32_t)); + + for (c = 0; c < wavetable_handlers_num; c++) + wavetable_handlers[c].get_buffer(outbuffer_w, WTBUFLEN, wavetable_handlers[c].priv); + + for (c = 0; c < WTBUFLEN * 2; c++) { + if (sound_is_float) + outbuffer_w_ex[c] = ((float) outbuffer_w[c]) / (float) 32768.0; + else { + if (outbuffer_w[c] > 32767) + outbuffer_w[c] = 32767; + if (outbuffer_w[c] < -32768) + outbuffer_w[c] = -32768; + + outbuffer_w_ex_int16[c] = (int16_t) outbuffer_w[c]; + } + } + + if (sound_is_float) + givealbuffer_wt(outbuffer_w_ex); + else + givealbuffer_wt(outbuffer_w_ex_int16); + + wavetable_pos_global = 0; + } +} + void sound_speed_changed(void) { sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); music_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) MUSIC_FREQ)); + + wavetable_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) WT_FREQ)); } void @@ -599,6 +688,8 @@ sound_reset(void) music_realloc_buffers(); + wavetable_realloc_buffers(); + midi_out_device_init(); midi_in_device_init(); @@ -614,6 +705,11 @@ sound_reset(void) music_handlers_num = 0; memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t)); + timer_add(&wavetable_poll_timer, wavetable_poll, NULL, 1); + + wavetable_handlers_num = 0; + memset(wavetable_handlers, 0x00, 8 * sizeof(sound_handler_t)); + filter_cd_audio = NULL; filter_cd_audio_p = NULL; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 78c3e2d35..9b341f574 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -52,6 +52,7 @@ static IXAudio2 *xaudio2 = NULL; static IXAudio2MasteringVoice *mastervoice = NULL; static IXAudio2SourceVoice *srcvoice = NULL; static IXAudio2SourceVoice *srcvoicemusic = NULL; +static IXAudio2SourceVoice *srcvoicewt = NULL; static IXAudio2SourceVoice *srcvoicemidi = NULL; static IXAudio2SourceVoice *srcvoicecd = NULL; @@ -169,27 +170,34 @@ inital(void) fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + + fmt.nSamplesPerSec = WT_FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicewt, &fmt, 0, 2.0f, &callbacks, NULL, NULL); fmt.nSamplesPerSec = CD_FREQ; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicewt, 0, XAUDIO2_COMMIT_NOW); const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) { + if ((strcmp(mdn, "none") != 0) && (strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME) != 0)) { fmt.nSamplesPerSec = midi_freq; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); } initialized = 1; @@ -202,17 +210,20 @@ closeal(void) if (!initialized) return; initialized = 0; - IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); - IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); - IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); + (void) IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); + (void) IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); + (void) IXAudio2SourceVoice_Stop(srcvoicewt, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicewt); + (void) IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); if (srcvoicemidi) { - IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); + (void) IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); } + IXAudio2SourceVoice_DestroyVoice(srcvoicewt); IXAudio2SourceVoice_DestroyVoice(srcvoicecd); IXAudio2SourceVoice_DestroyVoice(srcvoicemusic); IXAudio2SourceVoice_DestroyVoice(srcvoice); @@ -229,12 +240,13 @@ closeal(void) } void -givealbuffer_common(void *buf, IXAudio2SourceVoice *sourcevoice, size_t buflen) +givealbuffer_common(const void *buf, IXAudio2SourceVoice *sourcevoice, const size_t buflen) { if (!initialized) return; - IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), XAUDIO2_COMMIT_NOW); + (void) IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), + XAUDIO2_COMMIT_NOW); XAUDIO2_BUFFER buffer = { 0 }; buffer.Flags = 0; if (sound_is_float) { @@ -251,37 +263,43 @@ givealbuffer_common(void *buf, IXAudio2SourceVoice *sourcevoice, size_t buflen) buffer.PlayBegin = buffer.PlayLength = 0; buffer.PlayLength = buflen >> 1; buffer.pContext = (void *) buffer.pAudioData; - IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL); + (void) IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL); } void -givealbuffer(void *buf) +givealbuffer(const void *buf) { givealbuffer_common(buf, srcvoice, BUFLEN << 1); } void -givealbuffer_music(void *buf) +givealbuffer_music(const void *buf) { givealbuffer_common(buf, srcvoicemusic, MUSICBUFLEN << 1); } void -givealbuffer_cd(void *buf) +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, srcvoicewt, WTBUFLEN << 1); +} + +void +givealbuffer_cd(const void *buf) { if (srcvoicecd) givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1); } void -al_set_midi(int freq, int buf_size) +al_set_midi(const int freq, const int buf_size) { midi_freq = freq; midi_buf_size = buf_size; if (initialized && srcvoicemidi) { - IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); + (void) IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); srcvoicemidi = NULL; WAVEFORMATEX fmt; @@ -297,13 +315,13 @@ al_set_midi(int freq, int buf_size) fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.cbSize = 0; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); } } void -givealbuffer_midi(void *buf, uint32_t size) +givealbuffer_midi(const void *buf, const uint32_t size) { givealbuffer_common(buf, srcvoicemidi, size); } From e3c2c01f9124672d98b62e71ff67345147aefd98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:47:54 +0200 Subject: [PATCH 469/690] Commented out a call to lpt_reset() in device.c. --- src/device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device.c b/src/device.c index 14380f6c5..5e3b394c2 100644 --- a/src/device.c +++ b/src/device.c @@ -348,9 +348,11 @@ device_reset_all(uint32_t match_flags) } } +#ifdef UNCOMMENT_LATER /* TODO: Actually convert the LPT devices to device_t's. */ if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI)) lpt_reset(); +#endif } void * From ad8173df733a9016cc50c040b7b022e3549c5c00 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:50:47 +0200 Subject: [PATCH 470/690] Disambiguated the Pro Audio Spectrum 16D from 16. --- src/sound/snd_pas16.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 80d93dcbf..65046f0fe 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -2466,8 +2466,8 @@ const device_t pas16_device = { }; const device_t pas16d_device = { - .name = "Pro Audio Spectrum 16", - .internal_name = "pas16", + .name = "Pro Audio Spectrum 16D", + .internal_name = "pas16d", .flags = DEVICE_ISA | DEVICE_AT, .local = 0x0c, .init = pas16_init, From 895c1cad668a6e56656beeef2c11a8296e5605c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:52:54 +0200 Subject: [PATCH 471/690] Actually add the Pro Audio Spectrum 16D to the sound cards table. --- src/include/86box/sound.h | 3 ++- src/sound/sound.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 9ede638e5..9896b5422 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -189,9 +189,10 @@ extern const device_t ps1snd_device; /* Innovation SSI-2001 */ extern const device_t ssi2001_device; -/* Pro Audio Spectrum 16 */ +/* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; extern const device_t pas16_device; +extern const device_t pas16d_device; /* Tandy PSSJ */ extern const device_t pssj_device; diff --git a/src/sound/sound.c b/src/sound/sound.c index 0611909d8..f527cbc61 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -157,6 +157,7 @@ static const SOUND_CARD sound_cards[] = { { &ssi2001_device }, { &pasplus_device }, { &pas16_device }, + { &pas16d_device }, { &pssj_isa_device }, { &tndy_device }, { &wss_device }, From 907daed3b116289a5125c2b5ad0678eb1e36bd58 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:01:33 +0200 Subject: [PATCH 472/690] Removed a commented out section from scsi/scsi.c. --- src/scsi/scsi.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index aecbcadec..23c3e65f3 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -171,11 +171,6 @@ scsi_card_init(void) { int max = SCSI_CARD_MAX; - /* On-board SCSI controllers get the first bus, so if one is present, - increase our instance number here. */ - // if (machine_has_flags(machine, MACHINE_SCSI)) - // max--; - /* Do not initialize any controllers if we have do not have any SCSI bus left. */ if (max > 0) { From 93ffbdee51c8441e801d90430fb7b4b200f6bf06 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:06:31 +0200 Subject: [PATCH 473/690] Reverted the LPT DAC and DSS changes. --- src/sound/snd_lpt_dac.c | 54 +++++++++++++++-------------------------- src/sound/snd_lpt_dss.c | 23 ++++++++---------- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 8d7dbba4e..8fb526f14 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -5,14 +5,12 @@ #include #include "cpu.h" - -#include #include <86box/86box.h> #include <86box/filters.h> -#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct lpt_dac_t { @@ -52,14 +50,6 @@ dac_write_data(uint8_t val, void *priv) dac_update(lpt_dac); } -static void -dac_strobe(uint8_t old, uint8_t val, void *priv) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; - - lpt_dac->channel = val; -} - static void dac_write_ctrl(uint8_t val, void *priv) { @@ -120,31 +110,25 @@ dac_close(void *priv) } const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .autofeed = NULL, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .init = dac_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .read_data = NULL, + .read_status = dac_read_status, + .read_ctrl = NULL }; const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .autofeed = NULL, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .init = dac_stereo_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .read_data = NULL, + .read_status = dac_read_status, + .read_ctrl = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 5e5191e98..bd794fffb 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> -#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct dss_t { @@ -134,16 +134,13 @@ dss_close(void *priv) } const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .autofeed = NULL, - .strobe = NULL, - .write_ctrl = dss_write_ctrl, - .read_status = dss_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "Disney Sound Source", + .internal_name = "dss", + .init = dss_init, + .close = dss_close, + .write_data = dss_write_data, + .write_ctrl = dss_write_ctrl, + .read_data = NULL, + .read_status = dss_read_status, + .read_ctrl = NULL }; From eb968014d99d7cd9d923c8d2185807f3de05f354 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:41:45 +0200 Subject: [PATCH 474/690] OpenAL implementation of givealbuffer_wt(). --- src/sound/openal.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sound/openal.c b/src/sound/openal.c index f1ca74182..83bb312ba 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -304,6 +304,12 @@ givealbuffer_music(const void *buf) givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, 1, WTBUFLEN << 1, WT_FREQ); +} + void givealbuffer_cd(const void *buf) { From 660a33fe965ffb4798cc35e26c2825b3fbff1440 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:42:58 +0200 Subject: [PATCH 475/690] OpenAL: Fix the buffers' numeric ID's. --- src/sound/openal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 83bb312ba..a41199b23 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -307,17 +307,17 @@ givealbuffer_music(const void *buf) void givealbuffer_wt(const void *buf) { - givealbuffer_common(buf, 1, WTBUFLEN << 1, WT_FREQ); + givealbuffer_common(buf, 2, WTBUFLEN << 1, WT_FREQ); } void givealbuffer_cd(const void *buf) { - givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); + givealbuffer_common(buf, 3, CD_BUFLEN << 1, CD_FREQ); } void givealbuffer_midi(const void *buf, const uint32_t size) { - givealbuffer_common(buf, 3, (int) size, midi_freq); + givealbuffer_common(buf, 4, (int) size, midi_freq); } From 49824894e8588b97c18841b06e004e0ab117bc4c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 20:08:10 +0200 Subject: [PATCH 476/690] Pro Audio Spectrum: Correct the SCSI flag. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 65046f0fe..feaa31d61 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -2329,7 +2329,7 @@ pas16_init(const device_t *info) } pas16->type = info->local & 0xff; - pas16->has_scsi = (!pas16->type) || (pas16->type & 0x0f); + pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); From 19949b9a769f2e87f1d95c071690dca7bfa35324 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 03:31:14 +0500 Subject: [PATCH 477/690] snd_sb.c: Fix compilation error Variable declarations, unlike statements, aren't allowed after labels (including case labels) according to the C standard, so insert a semicolon to make an empty statement that satisfies the requirement. Oddly, MSYS2/MinGW-w64 GCC, unlike other compilers, including GCC on other systems, seemed to accept them without errors... --- src/sound/snd_sb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 9dc7724a4..80642adbe 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1292,6 +1292,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; case 0x82: + ; /* Empty statement to make compilers happy about the following variable declaration. */ /* The Interrupt status register, addressed as register 82h on the Mixer register map, is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, in which case it should chain to the previous routine. */ From 8d6ea95f1489136316deb439f88a4c2f2483b5c2 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:19:30 +0500 Subject: [PATCH 478/690] workflows: Fix workflows not triggering when the workflow file is updated --- .github/workflows/cmake_linux.yml | 4 ++-- .github/workflows/cmake_macos.yml | 4 ++-- .github/workflows/cmake_windows_llvm.yml | 4 ++-- .github/workflows/cmake_windows_msys2.yml | 4 ++-- .github/workflows/codeql_linux.yml | 4 ++-- .github/workflows/codeql_macos.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 12cb21303..51e577cfd 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index e51c652a4..f5233299b 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml index a49f9488a..cbddf33ea 100644 --- a/.github/workflows/cmake_windows_llvm.yml +++ b/.github/workflows/cmake_windows_llvm.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_llvm.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_llvm.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 0ed29f0b7..21df9f00a 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index d92d11767..54f2c06e6 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index cef8c4828..65633d073 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index da368cd68..069d70fcc 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" From 217fb9ac66461e2e292841e4ccd27336c87ecb6b Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:08:54 +0500 Subject: [PATCH 479/690] workflows: Bump upload-artifact to v4 --- .github/workflows/cmake_linux.yml | 2 +- .github/workflows/cmake_macos.yml | 2 +- .github/workflows/cmake_windows_llvm.yml | 2 +- .github/workflows/cmake_windows_msys2.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 51e577cfd..04238ece0 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -115,7 +115,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index f5233299b..5a9f31a01 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -120,7 +120,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml index cbddf33ea..93f4db241 100644 --- a/.github/workflows/cmake_windows_llvm.yml +++ b/.github/workflows/cmake_windows_llvm.yml @@ -157,7 +157,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 21df9f00a..d3f679a78 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -138,7 +138,7 @@ jobs: run: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' path: build/artifacts/** From c1158affa3551d9df206ed2ffc9853c154908e0e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:09:13 +0500 Subject: [PATCH 480/690] workflows: Bump CodeQL actions to v3 --- .github/workflows/codeql_linux.yml | 4 ++-- .github/workflows/codeql_macos.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index 54f2c06e6..73ccfb214 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -89,7 +89,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -106,6 +106,6 @@ jobs: run: cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 65633d073..6d2c3861f 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -82,7 +82,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -102,6 +102,6 @@ jobs: run: cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 069d70fcc..2b468f996 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -114,7 +114,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -133,6 +133,6 @@ jobs: - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" From 2d0b7f81d36d664a7335205823300d2d7563638f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 May 2024 11:40:07 +0200 Subject: [PATCH 481/690] Pro Audio Spectrum: assorted clean-ups. --- src/sound/snd_pas16.c | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index feaa31d61..859a1fd17 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -115,7 +115,6 @@ #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> -#include <86box/snd_sb_dsp.h> typedef struct nsc_mixer_t { double master_l; @@ -549,7 +548,6 @@ static const double lmc1982_att_2dbstep_6bits[] = { in said cut in the below values. */ static const double lmc835_att_1dbstep_7bits[128] = { - 0.0, /* Flat */ [0x40] = 8230.0, /* Flat */ /* Boost */ @@ -586,10 +584,10 @@ static const double lmc835_att_1dbstep_7bits[128] = { /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ [0x1d] = 7335.0, /* 1 dB Cut */ [0x2f] = 8230.0, /* Flat */ + 0.0 }; static const double lmc835_att_05dbstep_7bits[128] = { - 0.0 , /* Flat */ [0x40] = 8230.0, /* Flat */ /* Boost */ @@ -626,6 +624,7 @@ static const double lmc835_att_05dbstep_7bits[128] = { /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ [0x1d] = 7770.0, /* 0.5 dB Cut */ [0x2f] = 8230.0, /* Flat */ + 0.0 }; static __inline double @@ -1826,7 +1825,7 @@ pas16_pit_timer0(const int new_out, UNUSED(int old_out), void *priv) } if (pas16->ticks) { - for (uint8_t i = 0; i < pas16->ticks; i++) + for (uint16_t i = 0; i < pas16->ticks; i++) pitf_ctr_clock(pas16->pit, 1); pas16->ticks = 0; @@ -1939,18 +1938,13 @@ pasplus_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t * pas16 = (pas16_t *) priv; const nsc_mixer_t *mixer = &pas16->nsc_mixer; - double out_l = 0.0; - double out_r = 0.0; double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l += pas16->dsp.buffer[c]; - out_r += pas16->dsp.buffer[c + 1]; + double out_l = pas16->dsp.buffer[c]; + double out_r = pas16->dsp.buffer[c + 1]; if (pas16->filter) { /* We divide by 3 to get the volume down to normal. */ @@ -2004,16 +1998,11 @@ pasplus_get_music_buffer(int32_t *buffer, int len, void *priv) const pas16_t * pas16 = (const pas16_t *) priv; const nsc_mixer_t *mixer = &pas16->nsc_mixer; const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); - double out_l = 0.0; - double out_r = 0.0; double bass_treble; for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + double out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + double out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ out_l *= mixer->master_l; @@ -2127,18 +2116,13 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t * pas16 = (pas16_t *) priv; const mv508_mixer_t *mixer = &pas16->mv508_mixer; - double out_l = 0.0; - double out_r = 0.0; double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l += (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; - out_r += (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; + double out_l = (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; + double out_r = (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; if (pas16->filter) { /* We divide by 3 to get the volume down to normal. */ @@ -2192,16 +2176,11 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) const pas16_t * pas16 = (const pas16_t *) priv; const mv508_mixer_t *mixer = &pas16->mv508_mixer; const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); - double out_l = 0.0; - double out_r = 0.0; double bass_treble; for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + double out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + double out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ out_l *= mixer->master_l; From ccc788ff9870ec4faba286f1e6cd0fd20e56155a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 May 2024 18:48:44 +0200 Subject: [PATCH 482/690] Timer: Make sure timer_on_auto() to use timer_advance_u64() instead of timer_set_delay_u64() if it's called inside a callback. --- src/include/86box/timer.h | 2 +- src/timer.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index 4ade8aab0..91f903a0f 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -43,7 +43,7 @@ typedef struct pc_timer_t { ts_t ts; #endif int flags; /* The flags are defined above. */ - int pad; + int in_callback; double period; /* This is used for large period timers to count the microseconds and split the period. */ diff --git a/src/timer.c b/src/timer.c index fa8376bde..d7102ffc3 100644 --- a/src/timer.c +++ b/src/timer.c @@ -94,6 +94,7 @@ timer_disable(pc_timer_t *timer) fatal("timer_disable - !timer->next\n"); timer->flags &= ~TIMER_ENABLED; + timer->in_callback = 0; if (timer->prev) timer->prev->next = timer->next; @@ -127,11 +128,15 @@ timer_process(void) 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 not NULL, so that we can - have a NULL callback when no operation - is needed. */ + 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->in_callback = 1; timer->callback(timer->priv); + timer->in_callback = 0; + } } timer_target = timer_head->ts.ts32.integer; @@ -171,10 +176,11 @@ timer_add(pc_timer_t *timer, void (*callback)(void *priv), void *priv, int start { memset(timer, 0, sizeof(pc_timer_t)); - timer->callback = callback; - timer->priv = priv; - timer->flags = 0; - timer->prev = timer->next = NULL; + timer->callback = callback; + timer->in_callback = 0; + timer->priv = priv; + timer->flags = 0; + timer->prev = timer->next = NULL; if (start_timer) timer_set_delay_u64(timer, 0); } @@ -189,6 +195,7 @@ timer_stop(pc_timer_t *timer) timer->period = 0.0; timer_disable(timer); timer->flags &= ~TIMER_SPLIT; + timer->in_callback = 0; } static void @@ -240,7 +247,9 @@ timer_on_auto(pc_timer_t *timer, double period) return; if (period > 0.0) - timer_on(timer, period, timer->period <= 0.0); + /* If the timer is in the callback, signal that, so that timer_advance_u64() + is used instead of timer_set_delay_u64(). */ + timer_on(timer, period, (timer->period <= 0.0) && !timer->in_callback); else timer_stop(timer); } From c4ce5209b41e2b278df140ed46bb0f873f75469d Mon Sep 17 00:00:00 2001 From: Barnacl437 Date: Sun, 5 May 2024 21:15:48 +0700 Subject: [PATCH 483/690] minor fixes/corrections for vi-VN translation --- src/qt/languages/vi-VN.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 9f5421ee9..ee6d77849 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -391,13 +391,13 @@ msgid "Video:" msgstr "Video:" msgid "Voodoo Graphics" -msgstr "Voodoo đồ họa" +msgstr "Đồ họa Voodoo" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A đồ họa" +msgstr "Đồ họa IBM 8514/A" msgid "XGA Graphics" -msgstr "XGA đồ họa" +msgstr "Đồ họa XGA" msgid "Mouse:" msgstr "Chuột:" @@ -442,7 +442,7 @@ msgid "Use FLOAT32 sound" msgstr "Dùng âm FLOAT32" msgid "FM synth driver" -msgstr "Driver bộ tổng hợp (synth) FM" +msgstr "Driver bộ tổng hợp âm FM" msgid "Nuked (more accurate)" msgstr "Nuked (chính xác hơn)" @@ -508,10 +508,10 @@ msgid "Parallel port 4" msgstr "Cổng parallel 4" msgid "HD Controller:" -msgstr "Bộ điều khiển HD:" +msgstr "Bộ điều khiển ổ cứng:" msgid "FD Controller:" -msgstr "Bộ điều khiển FD:" +msgstr "Bộ điều khiển ổ mềm:" msgid "Tertiary IDE Controller" msgstr "Bộ điều khiển IDE thứ ba" @@ -841,7 +841,7 @@ msgid "86Box v" msgstr "86Box v" msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, cùng những người khác.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." msgid "Hardware not available" msgstr "Phần cứng không có sẵn" @@ -889,7 +889,7 @@ msgid "You are loading an unsupported configuration" msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." 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 "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." +msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị coi là phạm quy và đóng." msgid "Continue" msgstr "Tiếp tục" @@ -916,7 +916,7 @@ msgid "Resume execution" msgstr "Tiếp tục chạy thực thi" msgid "Pause execution" -msgstr "Dừng chạy thực thi" +msgstr "Tạm dừng thực thi" msgid "Press Ctrl+Alt+Del" msgstr "Nhấn Ctrl+Alt+Del" From 4c84cccae7f570701c8d787b70d05263a66de410 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 6 May 2024 13:09:08 +0200 Subject: [PATCH 484/690] The Pro Audio Spectrum SCSI controller is now based on the Trantor T128 (which it is considerable closer to), rather than on the 53c400. --- src/disk/mo.c | 4 +- src/disk/zip.c | 4 +- src/include/86box/scsi_device.h | 1 + src/include/86box/scsi_ncr5380.h | 7 +- .../86box/{scsi_ncr53c400.h => scsi_t128.h} | 49 ++--- src/scsi/scsi_cdrom.c | 14 +- src/scsi/scsi_disk.c | 5 +- src/scsi/scsi_ncr5380.c | 64 +++---- src/scsi/scsi_ncr53c400.c | 177 +++++------------- src/scsi/scsi_t128.c | 51 +++-- src/sound/snd_pas16.c | 51 ++--- 11 files changed, 165 insertions(+), 262 deletions(-) rename src/include/86box/{scsi_ncr53c400.h => scsi_t128.h} (55%) diff --git a/src/disk/mo.c b/src/disk/mo.c index c93f4b055..e90267b95 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1677,8 +1677,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x07; /*Optical disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/disk/zip.c b/src/disk/zip.c index 08d3baee3..d4cbd0b41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1865,8 +1865,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x00; /*Hard disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 216fdb2ad..2d6d60ac7 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -309,6 +309,7 @@ #define BUS_BSY 0x40 #define BUS_RST 0x80 #define BUS_ACK 0x200 +/* TODO: Why is this defined to the same value as BUS_ACK?! */ #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 55c3bf3c5..8baa4f9d8 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -109,14 +109,10 @@ typedef struct ncr_t { int data_pos; int irq; - int simple_pseudo_dma; - - uint32_t block_count; double period; void *priv; - void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -131,11 +127,11 @@ extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); -extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; +extern const device_t scsi_pas_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; @@ -145,7 +141,6 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif -extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_t128.h similarity index 55% rename from src/include/86box/scsi_ncr53c400.h rename to src/include/86box/scsi_t128.h index 9a5315990..65148a5d1 100644 --- a/src/include/86box/scsi_ncr53c400.h +++ b/src/include/86box/scsi_t128.h @@ -18,45 +18,34 @@ * Copyright 2017-2024 TheCollector1995. */ -#ifndef SCSI_NCR53C400_H -#define SCSI_NCR53C400_H +#ifndef SCSI_T128_H +#define SCSI_T128_H -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; +typedef struct t128_t { ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; uint8_t buffer[512]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; uint32_t rom_addr; - uint16_t base; - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int simple_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; + int bios_enabled; uint8_t pos_regs[8]; pc_timer_t timer; -} ncr53c400_t; +} t128_t; -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 +extern void t128_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t t128_read(uint32_t addr, void *priv); -extern void ncr53c400_simple_write(uint8_t val, void *priv); -extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); -extern uint8_t ncr53c400_simple_read(void *priv); -extern uint8_t ncr53c400_read(uint32_t addr, void *priv); -extern void ncr53c400_callback(void *priv); +extern void t128_callback(void *priv); -#endif /*SCSI_NCR53C400_H*/ +#endif /*SCSI_T128_H*/ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 8a9f72946..47ba0535e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2794,6 +2794,15 @@ begin: return; } + if (max_len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + scsi_cdrom_buf_free(dev); + return; + } + if (!(cdb[2] & 0x40)) alloc_length = 4; else @@ -3189,7 +3198,10 @@ begin: size_idx = 4; memset(dev->buffer, 0, 8); - dev->buffer[0] = 5; /*CD-ROM*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->buffer[0] = 5; /*CD-ROM*/ dev->buffer[1] = 0x80; /*Removable*/ if (dev->drv->bus_type == CDROM_BUS_SCSI) { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 39a69ea32..f29e85431 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1328,7 +1328,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->temp_buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->temp_buffer[0] = 0; /*SCSI HD*/ dev->temp_buffer[1] = 0; /*Fixed*/ dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d256de764..fefb7b9a2 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -161,8 +161,28 @@ ncr5380_get_bus_host(ncr_t *ncr) if (ncr->icr & ICR_BSY) bus_host |= BUS_BSY; - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; + /* + TODO: See which method of fixing this is the most correct. + + The #define's come from PCem and, for some reason, define + BUS_ATN to the same value as BUS_ACK (0x200). This breaks + the Corel driver for the Pro Audio Spectrum Trantor SCSI + controller, as it first asserts ATN without ACK, then ACK + without ATN, which should by definition result in ACK going + ON and OFF but because of these ambiguous #define's, it + instead manifests as ACK stuck on, therefore never clearing + BUS_REQ and progressing to the next phase. + + Since I have no idea why BUS_ATN was #define's to the same + value as BUS_ACK, and the problem appears to only occur in + the Message Out phase, where ATN is not used, I have decided + to solve this by never asserting ATN in the Message Out phase + for time being. + */ + if (ncr->state != STATE_MESSAGEOUT) { + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; + } if (ncr->icr & ICR_ACK) bus_host |= BUS_ACK; @@ -326,19 +346,6 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } - - if (ncr->simple_pseudo_dma) { - if (dev->phase == SCSI_PHASE_DATA_IN) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 1); - } else if (dev->phase == SCSI_PHASE_DATA_OUT) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 0); - } - } - ncr->new_phase = dev->phase; } } @@ -358,10 +365,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 1); - else - ncr->timer(ncr->priv, ncr->period); + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -388,10 +392,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - if (!ncr->simple_pseudo_dma) - ncr->timer(ncr->priv, ncr->period); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 0); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; @@ -517,21 +518,6 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } -uint8_t -ncr5380_drq(ncr_t *ncr) -{ - uint8_t ret = 0; - int bus; - - ncr5380_bus_read(ncr); - bus = ncr->cur_bus; - - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - ret = 1; - - return ret; -} - uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { @@ -579,6 +565,8 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ret |= BUS_SEL; if (ncr->icr & ICR_BSY) ret |= BUS_BSY; + // if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN) + // ret &= ~BUS_REQ; break; case 5: /* Bus and Status register */ diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index f4bd9de59..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,7 +41,6 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -49,14 +48,43 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B, - ROM_PAS + ROM_T130B }; +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -75,29 +103,8 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif -void -ncr53c400_simple_write(uint8_t val, void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ncr400->buffer[ncr400->buffer_host_pos++] = val; - - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr400->busy = 1; - - ncr53c400_callback(priv); - } - } -} - /* Memory-mapped I/O WRITE handler. */ -void +static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -185,30 +192,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } -uint8_t -ncr53c400_simple_read(void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t ret = 0xff; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); - ncr53c400_callback(priv); - } - } - - return ret; -} - /* Memory-mapped I/O READ handler. */ -uint8_t +static uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -400,34 +385,6 @@ t130b_in(uint16_t port, void *priv) return ret; } -static void -ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t val = send ? CTRL_DATA_DIR : 0x00; - - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); - - ncr400->block_count_loaded = 1; - - if (ncr400->status_ctrl & CTRL_DATA_DIR) { - ncr400->buffer_host_pos = MIN(512, dev->buffer_length); - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr400->buffer_host_pos = 0; - ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { - memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); - ncr53c400_log("DMA buffer init\n"); - ncr->timer(ncr->priv, ncr->period); - } - ncr53c400_log("NCR DMA init\n"); -} - static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -455,21 +412,17 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -void +static void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; - int blocks_left; uint8_t c; uint8_t temp; - const int buf_len = ncr400->simple_ctrl ? 512 : 128; - ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); - - if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) + if (ncr->dma_mode != DMA_IDLE) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -488,7 +441,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (ncr400->status_ctrl & CTRL_DATA_DIR) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -522,20 +475,14 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -552,7 +499,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -568,10 +515,8 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) { - ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); + if (ncr->cur_bus & BUS_REQ) break; - } } /* Data ready. */ @@ -586,19 +531,13 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -623,8 +562,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - if (ncr400->simple_ctrl) - ncr400->block_count_loaded = 0; } } @@ -719,6 +656,7 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; + case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -777,13 +715,6 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; - case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ - ncr400->simple_ctrl = 1; - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr->simple_pseudo_dma = 1; - ncr->dma_init_ext = ncr53c400_dma_init_ext; - break; - default: break; } @@ -1076,17 +1007,3 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; - -const device_t scsi_pas_device = { - .name = "Pro Audio Spectrum Plus/16 SCSI", - .internal_name = "scsi_pas", - .flags = DEVICE_ISA, - .local = ROM_PAS, - .init = ncr53c400_init, - .close = ncr53c400_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index b13511eac..7e42a089d 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -41,31 +41,10 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_t128.h> #define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -typedef struct t128_t { - ncr_t ncr; - rom_t bios_rom; - mem_mapping_t mapping; - - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - uint32_t rom_addr; - - int bios_enabled; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} t128_t; - #ifdef ENABLE_T128_LOG int t128_do_log = ENABLE_T128_LOG; @@ -85,7 +64,7 @@ t128_log(const char *fmt, ...) #endif /* Memory-mapped I/O WRITE handler. */ -static void +void t128_write(uint32_t addr, uint8_t val, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -122,7 +101,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t t128_read(uint32_t addr, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -243,7 +222,7 @@ t128_timer_on_auto(void *ext_priv, double period) timer_on_auto(&t128->timer, period); } -static void +void t128_callback(void *priv) { t128_t *t128 = (void *) priv; @@ -506,7 +485,7 @@ t128_init(const device_t *info) t128->pos_regs[0] = 0x8c; t128->pos_regs[1] = 0x50; mca_add(t228_read, t228_write, t228_feedb, NULL, t128); - } else { + } else if (info->local == 0) { ncr->irq = device_get_config_int("irq"); t128->rom_addr = device_get_config_hex20("bios_addr"); t128->bios_enabled = device_get_config_int("boot"); @@ -525,12 +504,13 @@ t128_init(const device_t *info) ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->timer = t128_timer_on_auto; - t128->status = 0x04; + t128->status = 0x00 /*0x04*/; t128->host_pos = 512; if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; - timer_add(&t128->timer, t128_callback, t128, 0); + if (info->local == 0) + timer_add(&t128->timer, t128_callback, t128, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); @@ -616,6 +596,7 @@ const device_t scsi_t128_device = { .config = t128_config }; + const device_t scsi_t228_device = { .name = "Trantor T228", .internal_name = "t228", @@ -629,3 +610,17 @@ const device_t scsi_t228_device = { .force_redraw = NULL, .config = NULL }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = 1, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 859a1fd17..243332257 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -108,8 +108,9 @@ #include <86box/pit.h> #include <86box/pit_fast.h> #include <86box/rom.h> +#include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> +#include <86box/scsi_t128.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -247,7 +248,7 @@ typedef struct pas16_t { pitf_t * pit; - ncr53c400_t *scsi; + t128_t * scsi; pc_timer_t scsi_timer; } pas16_t; @@ -705,7 +706,6 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; - ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -763,10 +763,8 @@ pas16_in(uint16_t port, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ret = ncr5380_read(port, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ret = ncr5380_read((port & 0x0003) | ((port & 0x2000) >> 11), &pas16->scsi->ncr); break; case 0x2401: /* Board revision */ @@ -782,20 +780,12 @@ pas16_in(uint16_t port, void *priv) case 0x5c00: if (pas16->has_scsi) - ret = ncr53c400_simple_read(pas16->scsi); + ret = t128_read(0x1e00, pas16->scsi); break; case 0x5c01: - if (pas16->has_scsi) { - ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; - if (!(ret & 0x80)) { - ncr53c400_callback(pas16->scsi); - if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - timer_stop(&pas16->scsi_timer); - pas16->timeout_status &= 0x7f; - } - - } - } + if (pas16->has_scsi) + /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */ + ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; break; case 0x5c03: if (pas16->has_scsi) @@ -1187,6 +1177,20 @@ lmc835_update_reg(nsc_mixer_t *mixer) lmc835_recalc(mixer); } +static void +pas16_scsi_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + t128_t * dev = pas16->scsi; + + t128_callback(pas16->scsi); + + if ((dev->ncr.dma_mode != DMA_IDLE) && (dev->status & 0x04)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } +} + static void pas16_timeout_callback(void *priv) { @@ -1491,10 +1495,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ncr5380_write(port, val, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ncr5380_write((port & 0x0003) | ((port & 0x2000) >> 11), val, &pas16->scsi->ncr); break; case 0x4000: @@ -1516,7 +1518,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x5c00: if (pas16->has_scsi) - ncr53c400_simple_write(val, pas16->scsi); + t128_write(0x1e00, val, pas16->scsi); break; case 0x5c03: if (pas16->has_scsi) { @@ -2324,6 +2326,7 @@ pas16_init(const device_t *info) if (pas16->has_scsi) { pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi->timer, pas16_scsi_callback, pas16, 0); timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); other_scsi_present++; } From 71c16a4481fc3657c4f36468688b511de684dd07 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 6 May 2024 13:24:04 +0200 Subject: [PATCH 485/690] Remove the previous kludge and #define BUS_ACK to 0x100 so it's different from BUS_ATN. --- src/include/86box/scsi_device.h | 3 +-- src/scsi/scsi_ncr5380.c | 24 ++---------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 2d6d60ac7..64d3bc853 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -308,8 +308,7 @@ #define BUS_REQ 0x20 #define BUS_BSY 0x40 #define BUS_RST 0x80 -#define BUS_ACK 0x200 -/* TODO: Why is this defined to the same value as BUS_ACK?! */ +#define BUS_ACK 0x100 #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index fefb7b9a2..527ff373f 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -161,28 +161,8 @@ ncr5380_get_bus_host(ncr_t *ncr) if (ncr->icr & ICR_BSY) bus_host |= BUS_BSY; - /* - TODO: See which method of fixing this is the most correct. - - The #define's come from PCem and, for some reason, define - BUS_ATN to the same value as BUS_ACK (0x200). This breaks - the Corel driver for the Pro Audio Spectrum Trantor SCSI - controller, as it first asserts ATN without ACK, then ACK - without ATN, which should by definition result in ACK going - ON and OFF but because of these ambiguous #define's, it - instead manifests as ACK stuck on, therefore never clearing - BUS_REQ and progressing to the next phase. - - Since I have no idea why BUS_ATN was #define's to the same - value as BUS_ACK, and the problem appears to only occur in - the Message Out phase, where ATN is not used, I have decided - to solve this by never asserting ATN in the Message Out phase - for time being. - */ - if (ncr->state != STATE_MESSAGEOUT) { - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; - } + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; if (ncr->icr & ICR_ACK) bus_host |= BUS_ACK; From 509305f2f1efdccaff5b837571e7010913ac01dd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 May 2024 20:09:30 +0200 Subject: [PATCH 486/690] Make the SMC FDC37c935 Super I/O chip on the HP Brio 80xx and Packard Bell PB810 correctly use port 370h instead of the standard 3F0h, fixes #4427. --- src/include/86box/sio.h | 1 + src/machine/m_at_socket7.c | 4 ++-- src/sio/sio_fdc37c93x.c | 30 +++++++++++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index c7098cfdb..d5fc88fb4 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,7 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37c935_370_device; extern const device_t fdc37c935_no_nvr_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7bbf49edf..9e2ed9a26 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -657,7 +657,7 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&sst_flash_29ee020_device); return ret; @@ -726,7 +726,7 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&intel_flash_bxt_device); return ret; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 7d8e12795..97fcb3fbd 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -54,6 +54,7 @@ typedef struct fdc37c93x_t { uint8_t is_apm; uint8_t has_nvr; uint8_t tries; + uint8_t port_370; uint8_t gpio_regs[2]; uint8_t auxio_reg; uint8_t regs[48]; @@ -785,7 +786,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = 0xF0; + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xF0; dev->regs[0x27] = 0x03; for (uint8_t i = 0; i < 11; i++) @@ -940,13 +941,14 @@ fdc37c93x_init(const device_t *info) dev->fdc = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; - dev->is_apm = (info->local >> 8) & 0x01; - is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); + dev->chip_id = info->local & 0xff; + dev->is_apm = (info->local >> 8) & 0x01; + is_compaq = (info->local >> 8) & 0x02; + dev->has_nvr = !((info->local >> 8) & 0x04); + dev->port_370 = ((info->local >> 8) & 0x08); dev->gpio_regs[0] = 0xff; #if 0 @@ -1053,6 +1055,20 @@ const device_t fdc37c935_device = { .config = NULL }; +const device_t fdc37c935_370_device = { + .name = "SMC FDC37C935 Super I/O (Port 370h)", + .internal_name = "fdc37c935_370", + .flags = 0, + .local = 0x802, + .init = fdc37c93x_init, + .close = fdc37c93x_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c935_no_nvr_device = { .name = "SMC FDC37C935 Super I/O", .internal_name = "fdc37c935", From c89e92fafd3204899956b2180c590272d6fe8546 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 00:34:51 +0200 Subject: [PATCH 487/690] Fixed the BCM SQ-588 with a kludged, fixes #4431. --- src/chipset/sis_85c50x.c | 2 ++ src/device/kbc_at.c | 43 +++++++++++++++++++----------------- src/include/86box/keyboard.h | 2 ++ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 8ec0498ff..137ddb5cf 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -39,6 +39,7 @@ #include <86box/spd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/keyboard.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -257,6 +258,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) break; case 0x5b: dev->pci_conf[addr] = val; + kbc_at_set_fast_reset(!!(val & 0x40)); break; case 0x60: /* SMI */ if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) { diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d8b308d6b..f596211cf 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -202,6 +202,14 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +static uint8_t fast_reset = 0x00; + +void +kbc_at_set_fast_reset(const uint8_t new_fast_reset) +{ + fast_reset = new_fast_reset; +} + #ifdef ENABLE_KBC_AT_LOG int kbc_at_do_log = ENABLE_KBC_AT_LOG; @@ -748,7 +756,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if (!cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + /* TODO: The fast reset flag's condition should be reversed - the BCM SQ-588 + enables the flag and the CPURST on soft reset flag but expects this + to still soft reset instead. */ + if ((fast_reset || !cpu_cpurst_on_sr) && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); @@ -765,11 +776,12 @@ write_p2(atkbc_t *dev, uint8_t val) flushmmucache(); if (kbc_ven == KBC_VEN_ALI) smbase = 0x00030000; + /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L and can find out what they actually did to make it boot from FFFFF0 correctly despite A20 being gated when the CPU is reset, this will have to do. */ - else if (kbc_ven == KBC_VEN_SIEMENS) + if (kbc_ven == KBC_VEN_SIEMENS) is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } @@ -778,10 +790,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* Do this here to avoid an infinite reset loop. */ dev->p2 = val; - if (cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + if (!fast_reset && cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ - pclog("write_p2(): Pulse reset!\n"); + kbc_at_log("write_p2(): Pulse reset!\n"); dma_reset(); dma_set_at(1); @@ -1833,24 +1845,8 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { kbc_at_log("ATkbc: write P2\n"); -#if 0 - /* Fast A20 - ignore all other bits. */ - val = (val & 0x02) | (dev->p2 & 0xfd); - - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - val &= ~0x0c; - val |= (dev->p2 & 0x0c); - } - - write_p2_fast_a20(dev, val | 0x01); -#else /* Fast A20 - ignore all other bits. */ write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); -#endif dev->wantdata = 0; dev->state = STATE_MAIN_IBF; @@ -1866,6 +1862,11 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) dev->state = STATE_KBC_PARAM; dev->command = 0xd1; return; + } else if (fast_reset && ((val & 0xf0) == 0xf0)) { + pulse_output(dev, val & 0x0f); + + dev->state = STATE_MAIN_IBF; + return; } break; @@ -2113,6 +2114,8 @@ kbc_at_init(const device_t *info) /* The actual keyboard. */ device_add(&keyboard_at_generic_device); + fast_reset = 0x00; + return dev; } diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0d8b2e745..94146d692 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -276,7 +276,9 @@ extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); +extern void kbc_at_set_fast_reset(uint8_t new_fast_reset); extern void kbc_at_handler(int set, void *priv); + extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); From 2912e7d746ab2aacad60f255f304becc5fe84078 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 03:23:00 +0200 Subject: [PATCH 488/690] E-MU 8000: Remove some useless clipping - the audio already gets clipped before being passed to the output buffer, so this is no longer necessary. --- src/sound/snd_emu8k.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index cc01ff6dd..5f13d2f8e 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2124,21 +2124,6 @@ emu8k_update(emu8k_t *emu8k) emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, wavetable_pos_global - emu8k->pos); emu8k_work_eq(buf, wavetable_pos_global - emu8k->pos); - // Clip signal - for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - /* Update EMU clock. */ emu8k->wc += (wavetable_pos_global - emu8k->pos); From 404def23e8fa7db9b1702a4d2740613753af8c01 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 03:35:51 +0200 Subject: [PATCH 489/690] Voodoo 3 1000 and Velocity 200: Hardcoded to 16 MB because our BIOS'es are 16 MB-only BIOS'es with the RAM amount check gutted out, closes #4406. --- src/video/vid_voodoo_banshee.c | 63 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index bbd14a4a0..5b6dbb434 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3103,6 +3103,61 @@ static const device_config_t banshee_sgram_config[] = { } }; +static const device_config_t banshee_sgram_16mbonly_config[] = { + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 2 + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, +#endif + { + .type = CONFIG_END + } +}; + static const device_config_t banshee_sdram_config[] = { { .name = "bilinear", @@ -3181,7 +3236,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int #endif mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */ else if (has_sgram) { - if (banshee->type == TYPE_VELOCITY100) + if ((banshee->type == TYPE_V3_1000) || (banshee->type == TYPE_VELOCITY200)) + mem_size = 16; /* Our Voodoo 3 1000 and Velocity 200 bios'es are hardcoded to 16 MB. */ + else if (banshee->type == TYPE_VELOCITY100) mem_size = 8; /* Velocity 100 only supports 8 MB */ else mem_size = device_get_config_int("memory"); @@ -3600,7 +3657,7 @@ const device_t voodoo_3_1000_agp_device = { { .available = v3_1000_agp_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config }; const device_t voodoo_3_2000_device = { @@ -3768,5 +3825,5 @@ const device_t velocity_200_agp_device = { { .available = velocity_200_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config }; From dd77ae1b779b4b80d51ebc1dfb3f4e5dadbe4dce Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 8 May 2024 13:55:21 -0400 Subject: [PATCH 490/690] qt: Clean up warning in DeviceConfig --- src/qt/qt_deviceconfig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index def3a4385..b031e6544 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -134,7 +134,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; int value = 0; - auto selected = static_cast(blank.toStdString().c_str()); + auto selected = blank; switch (config_major_type) { default: @@ -246,7 +246,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) p += !!rom_present(const_cast(bios->files[d])); if (p == bios->files_no) { const int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) + if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) currentIndex = row; } q++; From b159cd5b12ed7106c8de7479320a280a136ddff7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 23:42:20 +0200 Subject: [PATCH 491/690] Implemented the Phoenix keyboard controller with a Packard Bell specific workaround, fixes #4415. --- src/device/kbc_at.c | 235 ++++++++++++++++++++++++++++++++++- src/include/86box/keyboard.h | 1 + src/machine/m_at_386dx_486.c | 6 +- 3 files changed, 237 insertions(+), 5 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index f596211cf..85c0ff04a 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -133,9 +133,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; + uint8_t suppress_cmd_intr; uint8_t pad; uint8_t pad0; - uint8_t pad1; uint8_t mem[0x100]; @@ -202,6 +202,11 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +static const uint8_t multikey_vars[0x0b] = { + 0x0a, + 0x03, 0x1e, 0x27, 0x28, 0x29, 0x38, 0x39, 0x18, 0x19, 0x35 +}; + static uint8_t fast_reset = 0x00; void @@ -367,7 +372,7 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) picint_common(1 << 12, 0, 1, NULL); picint_common(1 << 1, 0, 0, NULL); } else { - if (dev->mem[0x20] & 0x01) + if ((!dev->suppress_cmd_intr || (dev->channel == 1)) && (dev->mem[0x20] & 0x01)) picint_common(1 << 1, 0, 1, NULL); picint_common(1 << 12, 0, 0, NULL); } @@ -1348,6 +1353,206 @@ write64_ami(void *priv, uint8_t val) return write64_generic(dev, val); } +static uint8_t +write60_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (dev->command) { + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + if (val == 0x00) + dev->command_phase = 0; + else { + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + } + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->mem[0x3a] = val; + dev->command_phase = 0; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->mem_addr = val; + dev->command_phase = 0; + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->mem[dev->mem_addr] = val; + dev->command_phase = 0; + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) + dev->mem[multikey_vars[dev->mem_addr]] = val; + else if (dev->mem_addr == 0x29) + dev->suppress_cmd_intr = !val; + dev->command_phase = 0; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->p1 |= val; + dev->command_phase = 0; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->p1 &= ~val; + dev->command_phase = 0; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + write_p2(dev, dev->p2 | val); + dev->command_phase = 0; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + write_p2(dev, dev->p2 & ~val); + dev->command_phase = 0; + return 0; + + default: + break; + } + + return 1; +} + +static uint8_t +write64_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (val) { + case 0x00 ... 0x1f: + kbc_at_log("ATkbc: Phoenix - alias read from %08X\n", val); + kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00); + return 0; + + case 0x40 ... 0x5f: + kbc_at_log("ATkbc: Phoenix - alias write to %08X\n", dev->command); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xa2: /* Test Extended Password */ + kbc_at_log("ATkbc: Phoenix - Test Extended Password\n"); + kbc_at_queue_add(dev, 0xf1); /* Extended Password not loaded */ + return 0; + + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb9: /* Get Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory Access Index\n"); + kbc_at_queue_add(dev, dev->mem_addr); + return 0; + + case 0xba: /* Get Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory\n"); + kbc_at_queue_add(dev, dev->mem[dev->mem_addr]); + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xbc: /* Get MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Get MultiKey Variable\n"); + if (dev->mem_addr == 0) + kbc_at_queue_add(dev, multikey_vars[dev->mem_addr]); + else if (dev->mem_addr <= multikey_vars[dev->mem_addr]) + kbc_at_queue_add(dev, dev->mem[multikey_vars[dev->mem_addr]]); + else + kbc_at_queue_add(dev, 0xff); + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + /* TODO: Handle these three commands properly - configurable + revision level and proper CPU bits. */ + case 0xd5: /* Read MultiKey code revision level */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey code revision level\n"); + kbc_at_queue_add(dev, 0x04); + kbc_at_queue_add(dev, 0x16); + return 0; + + case 0xd6: /* Read Version Information */ + kbc_at_log("ATkbc: Phoenix - Read Version Information\n"); + kbc_at_queue_add(dev, 0x81); + kbc_at_queue_add(dev, 0xac); + return 0; + + case 0xd7: /* Read MultiKey model numbers */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n"); + kbc_at_queue_add(dev, 0x02); + kbc_at_queue_add(dev, 0x87); + kbc_at_queue_add(dev, 0x02); + return 0; + + default: + break; + } + + return write64_generic(dev, val); +} + static uint8_t write64_siemens(void *priv, uint8_t val) { @@ -1895,6 +2100,11 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); + /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ + if (dev->suppress_cmd_intr) { + picint_common(1 << 1, 0, 1, NULL); + dev->suppress_cmd_intr = 0; + } if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -1937,6 +2147,8 @@ kbc_at_reset(void *priv) kbc_at_queue_reset(dev); + dev->suppress_cmd_intr = 0; + dev->sc_or = 0; dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; @@ -2086,6 +2298,11 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_ami; break; + case KBC_VEN_PHOENIX: + dev->write60_ven = write60_phoenix; + dev->write64_ven = write64_phoenix; + break; + case KBC_VEN_QUADTEL: dev->write60_ven = write60_quadtel; dev->write64_ven = write64_quadtel; @@ -2301,6 +2518,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_phoenix_device = { + .name = "PS/2 Keyboard (Phoenix)", + .internal_name = "keyboard_ps2_phoenix", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_tg_ami_device = { .name = "PS/2 Keyboard (TriGem AMI)", .internal_name = "keyboard_ps2_tg_ami", diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 94146d692..79665c9a9 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -245,6 +245,7 @@ extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; +extern const device_t keyboard_ps2_phoenix_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d4cd5fe16..d494a7302 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -704,11 +704,11 @@ machine_at_pb450_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&gd5428_vlb_onboard_device); - device_add(&opti602_device); device_add(&opti895_device); + device_add(&opti602_device); device_add(&opti822_device); - device_add(&keyboard_ps2_ami_device); - device_add(&fdc37c661_ide_device); + device_add(&keyboard_ps2_phoenix_device); + device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_sec_device); device_add(&intel_flash_bxt_device); device_add(&phoenix_486_jumper_pci_device); From 4fe7ee9675d2c6936597442ed8c0a0576cee4336 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 23:44:43 +0200 Subject: [PATCH 492/690] Added a PC Partner MB500N specific workaround to the i4x0 cache control register write. --- src/chipset/intel_4x0.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 8abbe50c1..26a973be0 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,7 +518,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0b); + if (!strcmp(machine_get_internal_name(), "mb500n")) + regs[0x52] = val; + else + regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; From b0542322bfd7bc84fe8572f7536fe48a96e70b57 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 00:47:45 +0200 Subject: [PATCH 493/690] Fixed DRB DIMM splitting (AMI Apollo now boots with 8 MB RAM), and extended the MB500N workaround to MR BIOS'es as well. --- src/chipset/intel_4x0.c | 2 +- src/mem/spd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 26a973be0..9a2635b12 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,7 +518,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - if (!strcmp(machine_get_internal_name(), "mb500n")) + if (!strcmp(machine_get_internal_name(), "mb500n") || (strstr(machine_get_internal_name(), "mr") != NULL)) regs[0x52] = val; else regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); diff --git a/src/mem/spd.c b/src/mem/spd.c index a3bcba46d..a0896a05a 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -136,7 +136,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m /* Look for a module to split. */ split = 0; for (row = 0; row < slot_count; row++) { - if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) + if ((rows[row] <= (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) continue; /* no module here, module is too small to be split, or asymmetric module */ /* Find next empty row. */ From 179c4fc279634c29c59cc78d749be37938e22ee0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:28:54 +0200 Subject: [PATCH 494/690] SiS 471: Register 69h is read/write, not read/write clear, fixes hangs in SMM on the DEC Venturis 4xx. --- src/chipset/sis_85c4xx.c | 4 +--- src/machine/m_at_386dx_486.c | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index cf4ff42d7..f80ecf99e 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -174,9 +174,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x23: if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) { valxor = val ^ dev->regs[rel_reg]; - if (rel_reg == 0x19) - dev->regs[rel_reg] &= ~val; - else if (rel_reg == 0x00) + if (rel_reg == 0x00) dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0); else dev->regs[rel_reg] = val; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d494a7302..1a6a6db67 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -702,7 +702,7 @@ machine_at_pb450_init(const machine_t *model) pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5428_vlb_onboard_device); + device_add(machine_get_vid_device(machine)); device_add(&opti895_device); device_add(&opti602_device); @@ -2223,10 +2223,10 @@ machine_at_dvent4xx_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_cmd640_vlb_pri_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_phoenix_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_phoenix_trio32_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); return ret; } From 3995d1d786de2889d3d61b1a8dadc88b1841a137 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:29:18 +0200 Subject: [PATCH 495/690] Some Machine table entry fixes. --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3aafe237c..2f1d690e7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6522,10 +6522,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &gd5428_vlb_onboard_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -6804,10 +6804,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &s3_phoenix_trio32_onboard_vlb_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio32_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, From a4fe16c9a02e1cd70f978827d64d97f39ce59fc3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:41:24 +0200 Subject: [PATCH 496/690] AT KBC: Do not attempt to remove the I/O handlers if they had not been set first, fixes crash when attempting to use the Compaq Presario 4500. --- src/device/kbc_at.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 85c0ff04a..7a720f948 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -164,6 +164,8 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL }; static uint8_t kbc_ami_revision = '8'; static uint8_t kbc_award_revision = 0x42; +static uint8_t kbc_handler_set = 0; + static void (*kbc_at_do_poll)(atkbc_t *dev); /* Non-translated to translated scan codes. */ @@ -2202,10 +2204,14 @@ kbc_at_close(void *priv) void kbc_at_handler(int set, void *priv) { - io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + if (kbc_handler_set) { + io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + } - if (set) { + kbc_handler_set = set; + + if (kbc_handler_set) { io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); } @@ -2228,6 +2234,7 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; + kbc_handler_set = 0; kbc_at_handler(1, dev); timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); From 72ff4501f7ecda6be2a003f9cd725e6d6f6dc4ec Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 18:02:27 +0200 Subject: [PATCH 497/690] IDE: Hard disks now have a valid default configuration, per ATA-2 and later. --- src/disk/hdc_ide.c | 47 ++++++++++++++++++++++++++++--------- src/include/86box/hdc_ide.h | 2 +- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d203a52e8..3793f778b 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -516,24 +516,29 @@ ide_hd_identify(const ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; const ide_bm_t *bm = ide_boards[ide->board]->bm; - const uint32_t d_spt = ide->spt; uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - uint32_t d_hpc; - uint32_t d_tracks; device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); - if (ide->hpc <= 16) { + uint32_t d_hpc = ide->hpc; + uint32_t d_spt = ide->spt; + uint32_t d_tracks; + + if ((ide->hpc <= 16) && (ide->spt <= 63)) { /* HPC <= 16, report as needed. */ d_tracks = ide->tracks; - d_hpc = ide->hpc; } else { /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; + if (ide->hpc > 16) + d_hpc = 16; + if (ide->spt > 63) + d_spt = 63; + d_tracks = (ide->tracks * ide->hpc * ide->spt) / (16 * 63); + if (d_tracks > 16383) + d_tracks = 16383; } /* Specify default CHS translation */ @@ -579,7 +584,7 @@ ide_hd_identify(const ide_t *ide) */ ide->buffer[53] = 1; - if (ide->cfg_spt != 0) { + if (ide->params_specified) { ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; ide->buffer[55] = ide->cfg_hpc; ide->buffer[56] = ide->cfg_spt; @@ -2427,10 +2432,12 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) err = ABRT_ERR; else { - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ + /* Only accept after RESET or DIAG. */ + if (ide->params_specified) { ide->cfg_spt = ide->tf->secount; ide->cfg_hpc = ide->tf->head + 1; + + ide->params_specified = 1; } ide->command = 0x00; ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2744,8 +2751,26 @@ ide_board_setup(const int board) dev->tf->error = 1; if (dev->type != IDE_HDD) dev->cfg_spt = dev->cfg_hpc = 0; - if (dev->type == IDE_HDD) + if (dev->type == IDE_HDD) { dev->blocksize = hdd[dev->hdd_num].max_multiple_block; + + /* Calculate the default heads and sectors. */ + uint32_t d_hpc = dev->hpc; + uint32_t d_spt = dev->spt; + + if ((dev->hpc > 16) || (dev->spt > 63)) { + /* HPC > 16, convert to 16 HPC. */ + if (dev->hpc > 16) + d_hpc = 16; + if (dev->spt > 63) + d_spt = 63; + } + + dev->cfg_spt = d_spt; + dev->cfg_hpc = d_hpc; + } + + dev->params_specified = 0; } } diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 4ee808d69..9094f7f00 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -82,7 +82,7 @@ typedef struct ide_s { uint8_t selected; uint8_t command; uint8_t head; - uint8_t pad; + uint8_t params_specified; int type; int board; int irqstat; From 62193ab2591d431d888bc3010a376646ab39b946 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 18:10:32 +0200 Subject: [PATCH 498/690] Intel i4x0: Extended the old register 52h behavior to all 430FX, 430HX, 430VX, and 430TX machines. --- src/chipset/intel_4x0.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 9a2635b12..2f6afa940 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,15 +518,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - if (!strcmp(machine_get_internal_name(), "mb500n") || (strstr(machine_get_internal_name(), "mr") != NULL)) - regs[0x52] = val; - else - regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); + regs[0x52] = (regs[0x52] & 0x04) | (val & 0xfb); cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; case INTEL_430HX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0f); + regs[0x52] = val; cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; From 544ea87764c62916b63f11c5791030aca3ecfb99 Mon Sep 17 00:00:00 2001 From: luennix <99608219+luennix@users.noreply.github.com> Date: Thu, 9 May 2024 19:57:11 +0300 Subject: [PATCH 499/690] Add the IBM PC 140 (type 6260) --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7_3v.c | 31 +++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f97d1a37c..c0d60c221 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -677,6 +677,7 @@ extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); +extern int machine_at_pc140_6260_init(const machine_t *); extern int machine_at_ms5124_init(const machine_t *); extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index bd66c9a66..b1a9515f3 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -882,3 +882,34 @@ machine_at_5sbm2_init(const machine_t *model) return ret; } + +int +machine_at_pc140_6260_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pc140_6260/LYKT32A.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard video */ + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5436_onboard_pci_device); + + device_add(&sis_5511_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3aafe237c..7fbae3a32 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10856,6 +10856,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has an SMC FDC37C669QF Super I/O. */ + { + .name = "[SiS 5511] IBM PC 140 (type 6260)", + .internal_name = "pc140_6260", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_pc140_6260_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX, CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[SiS 5511] MSI MS-5124", From b22b2af411b63fa93523debfc6a47038058a43fc Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:29:35 +0200 Subject: [PATCH 500/690] ALi M1543(C) and SiS 551x IDE fixes. --- src/chipset/ali1543.c | 4 ++-- src/chipset/sis_5513_ide.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 6f080b15b..5598f30fb 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -782,9 +782,9 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) /* Datasheet erratum: the PCI BAR's actually have different sizes. */ if (addr == 0x20) dev->ide_conf[addr] = (val & 0xe0) | 0x01; - else if ((addr & 0x43) == 0x00) + else if ((addr & 0x07) == 0x00) dev->ide_conf[addr] = (val & 0xf8) | 0x01; - else if ((addr & 0x43) == 0x40) + else if ((addr & 0x07) == 0x04) dev->ide_conf[addr] = (val & 0xfc) | 0x01; else dev->ide_conf[addr] = val; diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c index 130f2abd5..5cbfbdea8 100644 --- a/src/chipset/sis_5513_ide.c +++ b/src/chipset/sis_5513_ide.c @@ -224,6 +224,10 @@ sis_5513_ide_write(int addr, uint8_t val, void *priv) case 0x20 ... 0x21: if (addr == 0x20) dev->pci_conf[addr] = (val & 0xe0) | 0x01; + else if ((addr & 0x07) == 0x00) + dev->pci_conf[addr] = (val & 0xf8) | 0x01; + else if ((addr & 0x07) == 0x04) + dev->pci_conf[addr] = (val & 0xfc) | 0x01; else dev->pci_conf[addr] = val; sis_5513_ide_handler(dev); From b67c234569f4bd743c70dcac0daa14d9b293b7d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:31:58 +0200 Subject: [PATCH 501/690] The PS/2 keyboard controllers now simulate the real hardware behavior of there being a slight delay between OBF and IRQ, fixes, amnong other things, PB640 Windows 95 mouse (and PB450 CMOS Setup now works without the workaround). --- src/device/kbc_at.c | 87 +++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 7a720f948..c0ce537c2 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -108,7 +108,11 @@ enum { STATE_SEND_KBD, /* KBC is sending command to the keyboard. */ STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ - STATE_SCAN_AUX /* KBC is waiting for the auxiliary command response. */ + STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ + STATE_IRQ, /* KBC is raising the IRQ. */ + STATE_KBC_IRQ, + STATE_AUX_IRQ, + STATE_KBC_DELAY_IRQ }; typedef struct atkbc_t { @@ -133,9 +137,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; - uint8_t suppress_cmd_intr; uint8_t pad; uint8_t pad0; + uint8_t pad1; uint8_t mem[0x100]; @@ -352,8 +356,10 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; int temp = (channel == 1) ? kbc_translate(dev, val) : ((int) val); - if (temp == -1) + if (temp == -1) { + dev->state = STATE_MAIN_IBF; return; + } if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TRIGEM_AMI) || (dev->misc_flags & FLAG_PS2)) @@ -369,15 +375,9 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - } else { - if ((!dev->suppress_cmd_intr || (dev->channel == 1)) && (dev->mem[0x20] & 0x01)) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } + dev->state = STATE_AUX_IRQ; + } else if (channel == 1) + dev->state = STATE_IRQ; } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -575,7 +575,6 @@ kbc_scan_kbd_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 1\n", dev->ports[0]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[0]->out_new, 1, 0x00); dev->ports[0]->out_new = -1; - dev->state = STATE_MAIN_IBF; return 1; } @@ -589,7 +588,6 @@ kbc_scan_aux_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 2\n", dev->ports[1]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[1]->out_new, 2, 0x00); dev->ports[1]->out_new = -1; - dev->state = STATE_MAIN_IBF; return 1; } @@ -637,22 +635,20 @@ ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - (void) kbc_scan_kbd_ps2(dev); - dev->state = STATE_MAIN_IBF; + if (!kbc_scan_kbd_ps2(dev)) + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_AUX: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - (void) kbc_scan_aux_ps2(dev); - dev->state = STATE_MAIN_IBF; + if (!kbc_scan_aux_ps2(dev)) + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_BOTH: - if (kbc_scan_kbd_ps2(dev)) - dev->state = STATE_MAIN_IBF; - else + if (!kbc_scan_kbd_ps2(dev)) dev->state = STATE_MAIN_AUX; break; case STATE_KBC_DELAY_OUT: @@ -662,8 +658,29 @@ ps2_main_ibf: #if 0 dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif - dev->state = STATE_MAIN_IBF; dev->pending = 0; + dev->state = STATE_KBC_DELAY_IRQ; + break; + case STATE_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + break; + case STATE_AUX_IRQ: + kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); + if (dev->mem[0x20] & 0x02) + picint_common(1 << 12, 0, 1, NULL); + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + break; + case STATE_KBC_DELAY_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; goto ps2_main_ibf; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ @@ -676,11 +693,18 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; + dev->state = STATE_KBC_IRQ; } break; + case STATE_KBC_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; + break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { @@ -1394,8 +1418,6 @@ write60_phoenix(void *priv, uint8_t val) kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) dev->mem[multikey_vars[dev->mem_addr]] = val; - else if (dev->mem_addr == 0x29) - dev->suppress_cmd_intr = !val; dev->command_phase = 0; return 0; @@ -2006,7 +2028,7 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; - if (strstr(machine_get_internal_name(), "pb") != NULL) + if (strstr(machine_get_internal_name(), "pb41") != NULL) cpu_override_dynarec = 1; if (dev->misc_flags & FLAG_PS2) { @@ -2103,11 +2125,8 @@ kbc_at_read(uint16_t port, void *priv) if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ - if (dev->suppress_cmd_intr) { - picint_common(1 << 1, 0, 1, NULL); - dev->suppress_cmd_intr = 0; - } - if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) + if ((strstr(machine_get_internal_name(), "pb41") != NULL) && + (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -2149,8 +2168,6 @@ kbc_at_reset(void *priv) kbc_at_queue_reset(dev); - dev->suppress_cmd_intr = 0; - dev->sc_or = 0; dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; From 723c4229ed3bb99505034cd506c3cc8b564fdd42 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:33:15 +0200 Subject: [PATCH 502/690] PCI: Force the PCI_ADD_STRICT flag when adding PCI devices, in order to prevent on-board devices from being added onto non-on-board slots. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index 15a119cb7..13b780050 100644 --- a/src/pci.c +++ b/src/pci.c @@ -767,7 +767,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (next_pci_card < PCI_CARDS_NUM) { dev = &pci_card_descs[next_pci_card]; - dev->type = add_type; + dev->type = add_type | PCI_ADD_STRICT; dev->read = read; dev->write = write; dev->priv = priv; From 97b41adc22fc39809685111f8b85ba73434d88d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:49:21 +0200 Subject: [PATCH 503/690] AT KBC: IBM variants now revert to old IRQ behavior. --- src/device/kbc_at.c | 37 ++++++++++++++++++++++++++++++++---- src/include/86box/keyboard.h | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index c0ce537c2..6a5c306e1 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -88,6 +88,7 @@ #define KBC_VEN_ALI 0x28 #define KBC_VEN_SIEMENS 0x2c #define KBC_VEN_COMPAQ 0x30 +#define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c #define FLAG_CLOCK 0x01 @@ -375,9 +376,22 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - dev->state = STATE_AUX_IRQ; - } else if (channel == 1) - dev->state = STATE_IRQ; + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { + if (dev->mem[0x20] & 0x02) + picint_common(1 << 12, 0, 1, NULL); + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_AUX_IRQ; + } else if (channel == 1) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_IRQ; + } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -2275,6 +2289,7 @@ kbc_at_init(const device_t *info) case KBC_VEN_ACER: case KBC_VEN_GENERIC: + case KBC_VEN_IBM: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: case KBC_VEN_COMPAQ: @@ -2570,11 +2585,25 @@ const device_t keyboard_ps2_tg_ami_device = { .config = NULL }; +const device_t keyboard_ps2_mca_1_device = { + .name = "PS/2 Keyboard", + .internal_name = "keyboard_ps2", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_mca_2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_mca_2", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_2 | KBC_VEN_GENERIC, + .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 79665c9a9..5058c821e 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -246,6 +246,7 @@ extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; extern const device_t keyboard_ps2_phoenix_device; +extern const device_t keyboard_ps2_mca_1_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; From c9e27e7e70f1e39d21b550809cd6cf0df7e71534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Fri, 10 May 2024 00:50:23 +0200 Subject: [PATCH 504/690] Update m_ps2_mca.c. --- src/machine/m_ps2_mca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index a6fc30e1c..8ad69e314 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1054,7 +1054,7 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) } mca_init(slots); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); if (has_sec_nvram) device_add(&ps2_nvr_55ls_device); @@ -1228,7 +1228,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots) ps2.split_addr = mem_size * 1024; mca_init(slots); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); ps2.planar_read = model_70_type3_read; ps2.planar_write = model_70_type3_write; @@ -1321,7 +1321,7 @@ ps2_mca_board_model_80_type2_init(void) ps2.split_addr = mem_size * 1024; mca_init(8); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); ps2.planar_read = model_80_read; ps2.planar_write = model_80_write; From 6442c116f80d27d2f6f5478950aaaa48851d4f42 Mon Sep 17 00:00:00 2001 From: Jester Date: Sun, 12 May 2024 00:40:22 +0200 Subject: [PATCH 505/690] Update Olivetti M240 BIOS to 2.11 Dumped BIOS 2.11 Updating the BIOS from 2.04 to 2.11 fixes several bugs: - "Format Failure" message during hard disk formatting under MS DOS - WANGTEK 40 MB streaming tape unit management - I/O errors in floppy disk after an ON/OFF sequence - Clock problems after using "GOSLOW" - Possibility of testing system from a remote work station - Possibility of programming in RTCC - Solves FUJITSU 8284 problem --- src/machine/m_xt_olivetti.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 0b5a3eab0..7806d378b 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -1853,8 +1853,8 @@ machine_xt_m240_init(const machine_t *model) m24_kbd_t *m24_kbd; nvr_t *nvr; - ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pch6_2.04_low.bin", - "roms/machines/m240/olivetti_m240_pch5_2.04_high.bin", + ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pchj_2.11_low.bin", + "roms/machines/m240/olivetti_m240_pchk_2.11_high.bin", 0x000f8000, 32768, 0); if (bios_only || !ret) From d786cf3aa747c71192a239f3606d3d7343869406 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 May 2024 16:48:43 +0200 Subject: [PATCH 506/690] ESS AudioDrive: Fix some regressions and implement DRQ setting in compatibility mode, fixes Windows 3.1x ES1688 drivers. --- src/sound/snd_sb.c | 10 ++++++++-- src/sound/snd_sb_dsp.c | 26 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 80642adbe..364c01557 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1492,7 +1492,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x64: - mixer->regs[mixer->index] &= ~0x8; + mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20; + // mixer->regs[mixer->index] &= ~0x8; break; case 0x40: @@ -1615,9 +1616,13 @@ ess_mixer_read(uint16_t addr, void *priv) ret = 0x0a; break; + case 0x48: + ret = mixer->regs[mixer->index]; + break; + /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ case 0x64: - ret = 0x00; + ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; break; default: @@ -3463,6 +3468,7 @@ ess_x688_init(UNUSED(const device_t *info)) } ess->mixer_enabled = 1; + ess->mixer_ess.regs[0x40] = 0x0a; io_sethandler(addr + 4, 0x0002, ess_mixer_read, NULL, NULL, ess_mixer_write, NULL, NULL, diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 9c148339d..e5c2359a0 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -563,6 +563,8 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -574,6 +576,11 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); + + if (dsp->sb_16_dma_supported) + dma_set_drq(dsp->sb_16_dmanum, 1); + else + dma_set_drq(dsp->sb_16_8_dmanum, 1); } /* This will be set later for ESS playback/record modes. */ @@ -594,6 +601,8 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -605,6 +614,11 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); + + if (dsp->sb_16_dma_supported) + dma_set_drq(dsp->sb_16_dmanum, 1); + else + dma_set_drq(dsp->sb_16_8_dmanum, 1); } memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); @@ -771,7 +785,10 @@ sb_16_write_dma(void *priv, uint16_t val) void sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) { - uint8_t t = 0x00; + sb_t *ess = (sb_t *) dsp->parent; + ess_mixer_t *mixer = &ess->mixer_ess; + uint8_t t = 0x00; + /* IRQ control */ if (legacy) { t |= 0x80; @@ -779,6 +796,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) switch (dsp->sb_irqnum) { default: break; + case 2: case 9: t |= 0x0; break; @@ -793,6 +811,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) break; } ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; + if ((mixer != NULL) && (ess->mpu != NULL) && (((mixer->regs[0x40] >> 5) & 0x7) == 2)) + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); /* DRQ control */ t = 0x00; @@ -1802,7 +1822,7 @@ sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0x6: - ret = 0xff; + ret = IS_ESS(dsp) ? 0x00 : 0xff; break; case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) @@ -1821,7 +1841,7 @@ sb_read(uint16_t a, void *priv) dsp->state = DSP_S_NORMAL; break; case 0xC: /* Write data ready */ - if (dsp->state == DSP_S_NORMAL) { + if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) { if (dsp->sb_8_enable || dsp->sb_type >= SB16) dsp->busy_count = (dsp->busy_count + 1) & 3; else From 01b2d14a49f9c924306951f1e0c6e12b685060c7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 May 2024 19:11:52 +0200 Subject: [PATCH 507/690] PS/2 KBC: Clear IRQ's upon returning to main loop, fixes input in Windows 3.1x on eg. the Soyo 4SAW2. --- src/device/kbc_at.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 6a5c306e1..c630960ae 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -625,6 +625,8 @@ kbc_at_poll_ps2(atkbc_t *dev) fallthrough; case STATE_MAIN_IBF: default: + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); From 3cac44a0337c13555393dd34ffaba551313b073e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 00:42:35 +0200 Subject: [PATCH 508/690] PS/2 KBC: Added a 2-cycle wait before clearing the IRQ's, fixes keyboard during NTLDR. --- src/device/kbc_at.c | 89 ++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index c630960ae..74c5d83d1 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -99,7 +99,7 @@ enum { STATE_RESET = 0, /* KBC reset state, only accepts command AA. */ STATE_KBC_DELAY_OUT, /* KBC is sending one single byte. */ - STATE_KBC_AMI_OUT, /* KBC waiting for OBF - needed for AMIKey commands that require clearing of the output byte. */ + STATE_IRQC_MAIN_IBF, /* KBC checking if the input buffer is full, clear IRQ's first. */ STATE_MAIN_IBF, /* KBC checking if the input buffer is full. */ STATE_MAIN_KBD, /* KBC checking if the keyboard has anything to send. */ STATE_MAIN_AUX, /* KBC checking if the auxiliary has anything to send. */ @@ -113,7 +113,8 @@ enum { STATE_IRQ, /* KBC is raising the IRQ. */ STATE_KBC_IRQ, STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ + STATE_KBC_DELAY_IRQ, + STATE_IRQC_WAIT, }; typedef struct atkbc_t { @@ -371,25 +372,29 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) kbc_at_log("ATkbc: Sending %02X to the output buffer on channel %i...\n", temp, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; + dev->state = STATE_MAIN_IBF; + /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x02) + if (dev->mem[0x20] & 0x02) { picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - } else + dev->state = STATE_IRQC_WAIT; + } + // picint_common(1 << 1, 0, 0, NULL); + } else if (dev->mem[0x20] & 0x02) dev->state = STATE_AUX_IRQ; } else if (channel == 1) { if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - } else + dev->state = STATE_IRQC_WAIT; + } + // picint_common(1 << 12, 0, 0, NULL); + } else if (dev->mem[0x20] & 0x01) dev->state = STATE_IRQ; } } else if (dev->mem[0x20] & 0x01) @@ -499,10 +504,6 @@ kbc_at_poll_at(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_KBC_AMI_OUT: - if (dev->status & STAT_OFULL) - break; - fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -530,9 +531,6 @@ at_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); -#if 0 - dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; -#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto at_main_ibf; @@ -611,6 +609,8 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { + static uint8_t phase = 0; + switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -619,14 +619,19 @@ kbc_at_poll_ps2(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_KBC_AMI_OUT: - if (dev->status & STAT_OFULL) - break; + case STATE_IRQC_WAIT: + kbc_at_log("ATkbc: IRQ clear wait...\n"); + phase = (phase + 1) & 1; + if (phase) + dev->state = STATE_IRQC_MAIN_IBF; + break; + case STATE_IRQC_MAIN_IBF: + kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (Main/IBF)...\n"); + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); fallthrough; case STATE_MAIN_IBF: default: - picint_common(1 << 1, 0, 0, NULL); - picint_common(1 << 12, 0, 0, NULL); ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); @@ -671,34 +676,41 @@ ps2_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); -#if 0 - dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; -#endif dev->pending = 0; dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + } else { + kbc_at_log("ATkbc: Noping IRQ 1 (keyboard)...\n"); + dev->state = STATE_MAIN_IBF; + } break; case STATE_AUX_IRQ: kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) + if (dev->mem[0x20] & 0x02) { picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + } else + dev->state = STATE_MAIN_IBF; break; case STATE_KBC_DELAY_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; + dev->state = STATE_IRQC_WAIT; + break; + } else { + dev->state = STATE_MAIN_IBF; + goto ps2_main_ibf; + } case STATE_KBC_OUT: + kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (KBC out)...\n"); + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ @@ -716,10 +728,11 @@ ps2_main_ibf: kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + else + dev->state = STATE_KBC_OUT; break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ From 4e67a4fdd32b9e6e6e1e8f554a9df7eefc487c26 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 13 May 2024 00:57:53 +0200 Subject: [PATCH 509/690] DMA speed fixes in place on the 53c400. See above, so that the CD-ROM speed is accurate enough on both ends (T13B and the MMIO variants) and, at the same time, not timing out abnormally. --- src/scsi/scsi_ncr53c400.c | 66 ++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 1ed8e520e..6576e79ab 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -103,6 +103,18 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif +static void +ncr53c400_timer_on_auto(void *ext_priv, double period) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + + ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, timer_is_enabled(&ncr400->timer)); + if (period <= 0.0) + timer_stop(&ncr400->timer); + else if ((period > 0.0) && !timer_is_enabled(&ncr400->timer)) + timer_on_auto(&ncr400->timer, period); +} + /* Memory-mapped I/O WRITE handler. */ static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) @@ -110,7 +122,6 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - int actual_block = 0; addr &= 0x3fff; @@ -135,6 +146,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr400->busy = 1; + if (!(ncr->mode & MODE_MONITOR_BUSY)) + timer_on_auto(&ncr400->timer, ncr->period / 280.0); } } break; @@ -165,19 +178,13 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr400->buffer_host_pos = 0; ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0) && !timer_is_on(&ncr400->timer)) { + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d.\n", scsi_device_get_callback(dev), dev->buffer_length); - actual_block = ncr400->block_count; - if (!actual_block) - actual_block = 256; - - /*Sometimes the actual block count doesn't match the SCSI buffer length / 128.*/ - if (actual_block != (dev->buffer_length / 128)) { - /*FIXME: To be improved further, this is just to workaround callback de-syncs when split transfers occur.*/ - timer_on_auto(&ncr400->timer, (ncr->period / ((double)(actual_block * 40.0)))); - } else + if (ncr->mode & MODE_MONITOR_BUSY) timer_on_auto(&ncr400->timer, ncr->period); + else + timer_on_auto(&ncr400->timer, 40.0); + ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); } break; @@ -232,6 +239,8 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); + if (!(ncr->mode & MODE_MONITOR_BUSY)) + timer_on_auto(&ncr400->timer, ncr->period / 280.0); } } break; @@ -258,8 +267,7 @@ ncr53c400_read(uint32_t addr, void *priv) break; case 0x3982: /* switch register read */ - ret = 0xf8; - ret |= (ncr->irq & 0x07); + ret = 0xff; ncr53c400_log("Switches read=%02x.\n", ret); break; @@ -392,24 +400,13 @@ ncr53c400_dma_mode_ext(void *priv, void *ext_priv) ncr_t *ncr = (ncr_t *) priv; /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr400->block_count_loaded && !(ncr->mode & MODE_DMA)) { + if (!(ncr->mode & MODE_DMA)) { ncr53c400_log("No DMA mode\n"); ncr->tcr &= ~TCR_LAST_BYTE_SENT; ncr->isr &= ~STATUS_END_OF_DMA; ncr->dma_mode = DMA_IDLE; - } -} - -static void -ncr53c400_timer_on_auto(void *ext_priv, double period) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - - ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, !!timer_is_on(&ncr400->timer)); - if (period == 0.0) - timer_stop(&ncr400->timer); - else - timer_on_auto(&ncr400->timer, period); + } else + ncr53c400_log("Continuing DMA, mode bit=%02x, block loaded=%d, waitcomplete=%d.\n", ncr->mode, ncr400->block_count_loaded, ncr->wait_complete); } static void @@ -428,16 +425,10 @@ ncr53c400_callback(void *priv) if (ncr->data_wait & 1) { ncr->clear_req = 3; ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) { - timer_stop(&ncr400->timer); - return; - } } - if (ncr->dma_mode == DMA_IDLE) { - timer_stop(&ncr400->timer); + if (ncr->dma_mode == DMA_IDLE) return; - } switch (ncr->dma_mode) { case DMA_SEND: @@ -462,7 +453,6 @@ ncr53c400_callback(void *priv) if (ncr->cur_bus & BUS_REQ) break; } - /* Data ready. */ temp = ncr400->buffer[ncr400->buffer_pos]; @@ -487,7 +477,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr400->timer); if (ncr->mode & MODE_ENA_EOP_INT) { ncr53c400_log("NCR 53c400 write irq\n"); ncr5380_irq(ncr, 1); @@ -518,7 +507,6 @@ ncr53c400_callback(void *priv) if (ncr->cur_bus & BUS_REQ) break; } - /* Data ready. */ ncr5380_bus_read(ncr); temp = BUS_GETDATA(ncr->cur_bus); @@ -541,7 +529,6 @@ ncr53c400_callback(void *priv) ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr400->timer); if (ncr->mode & MODE_ENA_EOP_INT) { ncr53c400_log("NCR read irq\n"); ncr5380_irq(ncr, 1); @@ -562,6 +549,7 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; + ncr400->block_count_loaded = 0; } } From 1856696cd250314b1415bc4591adb246d6d1cabb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 13 May 2024 01:02:27 +0200 Subject: [PATCH 510/690] Warning fix --- src/scsi/scsi_ncr53c400.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 6576e79ab..ca4d28ffb 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -394,9 +394,8 @@ t130b_in(uint16_t port, void *priv) } static void -ncr53c400_dma_mode_ext(void *priv, void *ext_priv) +ncr53c400_dma_mode_ext(void *priv, UNUSED(void *ext_priv)) { - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; ncr_t *ncr = (ncr_t *) priv; /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -405,8 +404,7 @@ ncr53c400_dma_mode_ext(void *priv, void *ext_priv) ncr->tcr &= ~TCR_LAST_BYTE_SENT; ncr->isr &= ~STATUS_END_OF_DMA; ncr->dma_mode = DMA_IDLE; - } else - ncr53c400_log("Continuing DMA, mode bit=%02x, block loaded=%d, waitcomplete=%d.\n", ncr->mode, ncr400->block_count_loaded, ncr->wait_complete); + } } static void From 3c3e53e8b0e2c25711b3bccdb313ebefe2598b3b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 02:03:49 +0200 Subject: [PATCH 511/690] PS/2 KBC: Different approach to fix the Soyo 4SAW2 - it's only ever seen with ASIC KBC's (Holtek, MB-300E, and VIA VT82C42N), so I have added a Holtek controller that's basically an AMI with an ASIC flag. --- src/device/kbc_at.c | 115 +++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 74c5d83d1..179cca5ec 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -91,6 +91,8 @@ #define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c +#define KBC_IS_ASIC 0x80000000 + #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 #define FLAG_PS2 0x04 @@ -99,7 +101,7 @@ enum { STATE_RESET = 0, /* KBC reset state, only accepts command AA. */ STATE_KBC_DELAY_OUT, /* KBC is sending one single byte. */ - STATE_IRQC_MAIN_IBF, /* KBC checking if the input buffer is full, clear IRQ's first. */ + STATE_KBC_AMI_OUT, /* KBC waiting for OBF - needed for AMIKey commands that require clearing of the output byte. */ STATE_MAIN_IBF, /* KBC checking if the input buffer is full. */ STATE_MAIN_KBD, /* KBC checking if the keyboard has anything to send. */ STATE_MAIN_AUX, /* KBC checking if the auxiliary has anything to send. */ @@ -110,11 +112,10 @@ enum { STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ - STATE_IRQ, /* KBC is raising the IRQ. */ + STATE_IRQ = 0x10, /* KBC is raising the IRQ. */ STATE_KBC_IRQ, STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ, - STATE_IRQC_WAIT, + STATE_KBC_DELAY_IRQ }; typedef struct atkbc_t { @@ -379,23 +380,23 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x02) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x02) picint_common(1 << 12, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } - // picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 1, 0, 0, NULL); } else if (dev->mem[0x20] & 0x02) dev->state = STATE_AUX_IRQ; } else if (channel == 1) { - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x01) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } - // picint_common(1 << 12, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); } else if (dev->mem[0x20] & 0x01) dev->state = STATE_IRQ; + } else if ((channel == 0) && (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -504,6 +505,10 @@ kbc_at_poll_at(atkbc_t *dev) kbc_at_process_cmd(dev); } break; + case STATE_KBC_AMI_OUT: + if (dev->status & STAT_OFULL) + break; + fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -531,6 +536,9 @@ at_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto at_main_ibf; @@ -609,8 +617,6 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { - static uint8_t phase = 0; - switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -619,16 +625,9 @@ kbc_at_poll_ps2(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_IRQC_WAIT: - kbc_at_log("ATkbc: IRQ clear wait...\n"); - phase = (phase + 1) & 1; - if (phase) - dev->state = STATE_IRQC_MAIN_IBF; - break; - case STATE_IRQC_MAIN_IBF: - kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (Main/IBF)...\n"); - picint_common(1 << 1, 0, 0, NULL); - picint_common(1 << 12, 0, 0, NULL); + case STATE_KBC_AMI_OUT: + if (dev->status & STAT_OFULL) + break; fallthrough; case STATE_MAIN_IBF: default: @@ -676,41 +675,37 @@ ps2_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->pending = 0; - dev->state = STATE_KBC_DELAY_IRQ; + if (dev->flags & KBC_IS_ASIC) + dev->state = STATE_MAIN_IBF; + else + dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: - if (dev->mem[0x20] & 0x01) { - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } else { - kbc_at_log("ATkbc: Noping IRQ 1 (keyboard)...\n"); - dev->state = STATE_MAIN_IBF; - } + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; break; case STATE_AUX_IRQ: kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) { + if (dev->mem[0x20] & 0x02) picint_common(1 << 12, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } else - dev->state = STATE_MAIN_IBF; + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; break; case STATE_KBC_DELAY_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) { + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - break; - } else { - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; - } - case STATE_KBC_OUT: - kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (KBC out)...\n"); - picint_common(1 << 1, 0, 0, NULL); picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + goto ps2_main_ibf; + case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ @@ -721,16 +716,22 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->state = STATE_KBC_IRQ; + if (dev->flags & KBC_IS_ASIC) { + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_KBC_IRQ; } break; case STATE_KBC_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_IRQC_WAIT; + dev->state = STATE_MAIN_IBF; else dev->state = STATE_KBC_OUT; break; @@ -2572,6 +2573,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_holtek_device = { + .name = "PS/2 Keyboard (Holtek)", + .internal_name = "keyboard_ps2_holtek", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_IS_ASIC, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_phoenix_device = { .name = "PS/2 Keyboard (Phoenix)", .internal_name = "keyboard_ps2_phoenix", From 55e1ca7dc14a650d7997b727ed04807acfeb945f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 02:22:05 +0200 Subject: [PATCH 512/690] PS/2 ASIC KBC: A minor fix. --- src/device/kbc_at.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 179cca5ec..20f94f942 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -679,9 +679,10 @@ ps2_main_ibf: dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif dev->pending = 0; - if (dev->flags & KBC_IS_ASIC) + if (dev->flags & KBC_IS_ASIC) { dev->state = STATE_MAIN_IBF; - else + goto ps2_main_ibf; + } else dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: From 1a255693e9fcb777cfd1cfa73e54ea24ae3d61fa Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 May 2024 21:25:25 +0200 Subject: [PATCH 513/690] PS/2 KBC: Changed the way the IRQ delay is done, fixes #4451. --- src/device/kbc_at.c | 151 ++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 88 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 20f94f942..74ade4cd3 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -91,7 +91,7 @@ #define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c -#define KBC_IS_ASIC 0x80000000 +#define KBC_FLAG_IS_ASIC 0x80000000 #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 @@ -111,11 +111,7 @@ enum { STATE_SEND_KBD, /* KBC is sending command to the keyboard. */ STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ - STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ - STATE_IRQ = 0x10, /* KBC is raising the IRQ. */ - STATE_KBC_IRQ, - STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ + STATE_SCAN_AUX /* KBC is waiting for the auxiliary command response. */ }; typedef struct atkbc_t { @@ -140,9 +136,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; + uint8_t do_irq; + uint8_t is_asic; uint8_t pad; - uint8_t pad0; - uint8_t pad1; uint8_t mem[0x100]; @@ -353,16 +349,38 @@ kbc_translate(atkbc_t *dev, uint8_t val) return ret; } +static void +kbc_set_do_irq(atkbc_t *dev, uint8_t channel) +{ + dev->channel = channel; + dev->do_irq = 1; +} + +static void +kbc_do_irq(atkbc_t *dev) +{ + if (dev->do_irq) { + /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly + written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); + if (dev->channel >= 2) + picint_common(1 << 12, 0, 1, NULL); + else + picint_common(1 << 1, 0, 1, NULL); + + dev->do_irq = 0; + } +} + static void kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; int temp = (channel == 1) ? kbc_translate(dev, val) : ((int) val); - if (temp == -1) { - dev->state = STATE_MAIN_IBF; + if (temp == -1) return; - } if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TRIGEM_AMI) || (dev->misc_flags & FLAG_PS2)) @@ -373,34 +391,24 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) kbc_at_log("ATkbc: Sending %02X to the output buffer on channel %i...\n", temp, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; - dev->state = STATE_MAIN_IBF; + dev->do_irq = 0; /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - } else if (dev->mem[0x20] & 0x02) - dev->state = STATE_AUX_IRQ; - } else if (channel == 1) { - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } else if (dev->mem[0x20] & 0x01) - dev->state = STATE_IRQ; - } else if ((channel == 0) && (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } + + if (dev->mem[0x20] & 0x02) + kbc_set_do_irq(dev, channel); + } else if (dev->mem[0x20] & 0x01) + kbc_set_do_irq(dev, channel); } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + if (dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) + kbc_do_irq(dev); + dev->ob = temp; } @@ -595,6 +603,7 @@ kbc_scan_kbd_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 1\n", dev->ports[0]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[0]->out_new, 1, 0x00); dev->ports[0]->out_new = -1; + dev->state = STATE_MAIN_IBF; return 1; } @@ -608,6 +617,7 @@ kbc_scan_aux_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 2\n", dev->ports[1]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[1]->out_new, 2, 0x00); dev->ports[1]->out_new = -1; + dev->state = STATE_MAIN_IBF; return 1; } @@ -617,6 +627,8 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { + kbc_do_irq(dev); + switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -631,7 +643,6 @@ kbc_at_poll_ps2(atkbc_t *dev) fallthrough; case STATE_MAIN_IBF: default: -ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else if (!(dev->status & STAT_OFULL)) { @@ -655,20 +666,22 @@ ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - if (!kbc_scan_kbd_ps2(dev)) - dev->state = STATE_MAIN_IBF; + (void) kbc_scan_kbd_ps2(dev); + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_AUX: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - if (!kbc_scan_aux_ps2(dev)) - dev->state = STATE_MAIN_IBF; + (void) kbc_scan_aux_ps2(dev); + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_BOTH: - if (!kbc_scan_kbd_ps2(dev)) + if (kbc_scan_kbd_ps2(dev)) + dev->state = STATE_MAIN_IBF; + else dev->state = STATE_MAIN_AUX; break; case STATE_KBC_DELAY_OUT: @@ -678,34 +691,10 @@ ps2_main_ibf: #if 0 dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif + dev->state = STATE_MAIN_IBF; dev->pending = 0; - if (dev->flags & KBC_IS_ASIC) { - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; - } else - dev->state = STATE_KBC_DELAY_IRQ; + // goto ps2_main_ibf; break; - case STATE_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - break; - case STATE_AUX_IRQ: - kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - break; - case STATE_KBC_DELAY_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { @@ -717,25 +706,11 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - if (dev->flags & KBC_IS_ASIC) { - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; - } else - dev->state = STATE_KBC_IRQ; + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; } break; - case STATE_KBC_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; - else - dev->state = STATE_KBC_OUT; - break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { @@ -2108,7 +2083,7 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) /* Fast A20 - ignore all other bits. */ write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); - dev->wantdata = 0; + dev->wantdata = 0; dev->state = STATE_MAIN_IBF; return; } @@ -2155,9 +2130,7 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); - /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ - if ((strstr(machine_get_internal_name(), "pb41") != NULL) && - (cpu_override_dynarec == 1)) + if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -2276,6 +2249,8 @@ kbc_at_init(const device_t *info) dev->flags = info->local; + dev->is_asic = !!(info->local & KBC_FLAG_IS_ASIC); + video_reset(gfxcard[0]); kbc_at_reset(dev); @@ -2306,9 +2281,9 @@ kbc_at_init(const device_t *info) case KBC_VEN_ACER: case KBC_VEN_GENERIC: - case KBC_VEN_IBM: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: + case KBC_VEN_IBM: case KBC_VEN_COMPAQ: dev->write64_ven = write64_generic; break; @@ -2578,7 +2553,7 @@ const device_t keyboard_ps2_holtek_device = { .name = "PS/2 Keyboard (Holtek)", .internal_name = "keyboard_ps2_holtek", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_IS_ASIC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_FLAG_IS_ASIC, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2617,8 +2592,8 @@ const device_t keyboard_ps2_tg_ami_device = { }; const device_t keyboard_ps2_mca_1_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2", + .name = "PS/2 Keyboard (IBM PS/2 MCA Type 1)", + .internal_name = "keyboard_ps2_mca_1", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM, .init = kbc_at_init, @@ -2631,7 +2606,7 @@ const device_t keyboard_ps2_mca_1_device = { }; const device_t keyboard_ps2_mca_2_device = { - .name = "PS/2 Keyboard", + .name = "PS/2 Keyboard (IBM PS/2 MCA Type 2)", .internal_name = "keyboard_ps2_mca_2", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM, From 5af50e22edcf981b23e2d3b697f920fdd5fe0525 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 May 2024 21:25:54 +0200 Subject: [PATCH 514/690] And the forgotten keyboard.h. --- src/include/86box/keyboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 5058c821e..846123627 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -242,6 +242,7 @@ extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_ami_device; +extern const device_t keyboard_ps2_holtek_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; From a3d5f8e8676954de7a87b369dc7cdb07576301dd Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 15 May 2024 21:18:40 +0200 Subject: [PATCH 515/690] XGA 1-2: Pattern and cursor/sprite fixes. 1. Text is no longer glitchy under win95 using XGA. 2. Now there's a better way to handle the cursor/sprite X/Y offsets, should fix remaining Win3.x cursor blackness and other stuff using said cursor. --- src/video/vid_xga.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index a908c3418..9dcdd84b6 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1396,8 +1396,11 @@ xga_line_draw_write(svga_t *svga) } } - if (!y) + if (!y) { + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; break; + } if (xga->accel.octant & 0x01) { if (xga->accel.octant & 0x02) @@ -1511,6 +1514,7 @@ xga_bitblt(svga_t *svga) xga->accel.dst_map, xga->accel.py, xga->accel.sy, dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3]); + xga_log("PAT8: Pattern Enabled?=%d, xdir=%d, ydir=%d.\n", xga->accel.pattern, xdir, ydir); while (xga->accel.y >= 0) { if (xga->accel.command & 0xc0) { @@ -1569,9 +1573,12 @@ xga_bitblt(svga_t *svga) } } } else if (xga->accel.pat_src >= 1) { - if (patheight == 7) - xga->accel.pattern = 1; - else { + if (patheight == 7) { + if (xga->accel.src_map != 1) + xga->accel.pattern = 1; + else if ((xga->accel.src_map == 1) && (patwidth == 7)) + xga->accel.pattern = 1; + } else { if (dstwidth == (xga->h_disp - 1)) { if (srcwidth == (xga->h_disp - 1)) { if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { @@ -1607,6 +1614,7 @@ xga_bitblt(svga_t *svga) xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol); + xga_log("Pattern Enabled?=%d, patwidth=%d, patheight=%d, P(%d,%d).\n", xga->accel.pattern, patwidth, patheight, xga->accel.px, xga->accel.py); if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) { while (xga->accel.y >= 0) { @@ -2297,12 +2305,6 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { - case 0x0c: - temp = xga->regs[0x0c]; - break; - case 0x0d: - temp = xga->regs[0x0d]; - break; case 0x11: temp = xga->accel.control; if (xga->accel.control & 0x08) @@ -2932,12 +2934,12 @@ xga_poll(void *priv, svga_t *svga) if (!xga->linepos) { if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize; + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); xga->hwcursor_oddeven = 0; } if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - 1; + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); xga->hwcursor_oddeven = 1; } From fb6b0458a657c85a360406df2a9c1c271701d0de Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 16 May 2024 22:33:50 +0200 Subject: [PATCH 516/690] ATI Mach32/64 changes for the better: 1. On both Mach'es: direct linear video memory access is now the default for LFB mapping: fixes Mach64 drivers on NeXTSTEP/OPENSTEP and keeps everything else intact. 2. Mach8/32: minor cleanup to mode change code. --- src/include/86box/vid_8514a.h | 9 ++ src/video/vid_ati_mach64.c | 204 +++++++++++++++++++++++++++------- src/video/vid_ati_mach8.c | 135 ++++++++++++++++------ 3 files changed, 272 insertions(+), 76 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index fab504bbe..ac4085089 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -32,6 +32,13 @@ typedef struct hwcursor8514_t { uint32_t pitch; } hwcursor8514_t; +typedef union { + uint64_t q; + uint32_t d[2]; + uint16_t w[4]; + uint8_t b[8]; +} latch8514_t; + typedef struct ibm8514_t { rom_t bios_rom; rom_t bios_rom2; @@ -217,6 +224,8 @@ typedef struct ibm8514_t { int ext_pitch; int ext_crt_pitch; int extensions; + + latch8514_t latch; } ibm8514_t; #endif /*VIDEO_8514A_H*/ diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 9aa396383..8403e718d 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -621,11 +621,11 @@ mach64_updatemapping(mach64_t *mach64) break; } - mach64_log("Mach64 linear aperture = %08x.\n", mach64->linear_base); if (mach64->linear_base) { if (mach64->type == MACH64_GX) { if ((mach64->config_cntl & 3) == 2) { /*8 MB aperture*/ + mach64_log("Mach64 linear aperture=%08x, cfgcntl=%x, mapping=%x, VGAAP=%x.\n", mach64->linear_base + ((8 << 20) - 0x4000), mach64->config_cntl & 3, svga->gdcreg[6] & 0xc, mach64->config_cntl & 4); mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); } else { @@ -2344,7 +2344,7 @@ mach64_ext_readb(uint32_t addr, void *priv) ret = 0xff; break; } - } else + } else { switch (addr & 0x3ff) { case 0x00: case 0x01: @@ -2872,6 +2872,7 @@ mach64_ext_readb(uint32_t addr, void *priv) ret = 0; break; } + } if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); return ret; @@ -3050,7 +3051,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); } else if (addr & 0x300) { mach64_accel_write_fifo(mach64, addr & 0x3ff, val); - } else + } else { switch (addr & 0x3ff) { case 0x00: case 0x01: @@ -3232,17 +3233,20 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga); else - ati68860_ramdac_out(addr & 3, val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out(addr & 3, val, svga->ramdac, svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: WRITE8(addr, mach64->dac_cntl, val); - svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + mach64_log("Ext RAMDAC TYPE write=%x, bit set=%03x.\n", addr & 0x3ff, mach64->dac_cntl & 0x100); + if ((addr & 3) >= 1) { + svga_set_ramdac_type(svga, !!(mach64->dac_cntl & 0x100)); + ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100)); + } i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000)); break; @@ -3275,7 +3279,9 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) default: break; } + } } + void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) { @@ -3555,6 +3561,7 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *priv) { mach64_t *mach64 = (mach64_t *) priv; + svga_t *svga = &mach64->svga; mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); switch (port) { @@ -3695,9 +3702,9 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv) case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga); else - ati68860_ramdac_out(port & 3, val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out(port & 3, val, svga->ramdac, svga); break; case 0x62ec: @@ -3818,8 +3825,7 @@ mach64_writew(uint32_t addr, uint16_t val, void *priv) { mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; svga_writew_linear(addr, val, svga); } void @@ -3827,8 +3833,7 @@ mach64_writel(uint32_t addr, uint32_t val, void *priv) { mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; svga_writel_linear(addr, val, svga); } @@ -3847,18 +3852,20 @@ mach64_readw(uint32_t addr, void *priv) { mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; - + uint16_t ret; addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); + ret = svga_readw_linear(addr, svga); + return ret; } uint32_t mach64_readl(uint32_t addr, void *priv) { mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; - + uint32_t ret; addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); + ret = svga_readl_linear(addr, svga); + return ret; } #define CLAMP(x) \ @@ -4202,16 +4209,34 @@ mach64_io_remove(mach64_t *mach64) static void mach64_io_set(mach64_t *mach64) { + uint16_t io_base = 0x02ec; + mach64_io_remove(mach64); + switch (mach64->io_base) { + default: + case 0: + io_base = 0x02ec; + break; + case 1: + io_base = 0x01cc; + break; + case 2: + io_base = 0x01c8; + break; + case 3: + fatal("Attempting to use the reserved value for I/O Base\n"); + return; + } + io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); if (!mach64->use_block_decoded_io) { for (uint8_t c = 0; c < 8; c++) { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x0000 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x0400 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x0800 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x0c00 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); } } @@ -4221,6 +4246,107 @@ mach64_io_set(mach64_t *mach64) io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } +static uint8_t +mach64_read_linear(uint32_t addr, void *priv) +{ + const svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_read_b; + + if (!svga->fast) { + if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } + } + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + return svga->vram[addr & svga->vram_mask]; +} + +static uint16_t +mach64_readw_linear(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_read_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; + + return *(uint16_t *) &svga->vram[addr & svga->vram_mask]; +} + +static uint32_t +mach64_readl_linear(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_read_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; + + return *(uint32_t *) &svga->vram[addr & svga->vram_mask]; +} + +static void +mach64_write_linear(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_write_b; + + if (!svga->fast) { + if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } + } + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->vram[addr] = val; +} + +static void +mach64_writew_linear(uint32_t addr, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_write_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + *(uint16_t *) &svga->vram[addr] = val; +} + +static void +mach64_writel_linear(uint32_t addr, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_write_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + *(uint32_t *) &svga->vram[addr] = val; +} + uint8_t mach64_pci_read(UNUSED(int func), int addr, void *priv) { @@ -4364,9 +4490,9 @@ mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x33: mach64->pci_regs[addr] = val; if (mach64->pci_regs[0x30] & 0x01) { - uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - mach64_log("Mach64 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); + uint32_t biosaddr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); + mach64_log("Mach64 bios_rom enabled at %08x\n", biosaddr); + mem_mapping_set_addr(&mach64->bios_rom.mapping, biosaddr, 0x8000); } else { mach64_log("Mach64 bios_rom disabled\n"); mem_mapping_disable(&mach64->bios_rom.mapping); @@ -4411,7 +4537,7 @@ mach64_common_init(const device_t *info) mach64_overlay_draw); svga->dac_hwcursor.cur_ysize = 64; - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_add(&mach64->linear_mapping, 0, 0, mach64_read_linear, mach64_readw_linear, mach64_readl_linear, mach64_write_linear, mach64_writew_linear, mach64_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); @@ -4458,24 +4584,20 @@ mach64gx_init(const device_t *info) mach64->config_chip_id = 0x000000d7; mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ - if (info->flags & DEVICE_PCI) - mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ - else if (info->flags & DEVICE_VLB) - mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - else if (info->flags & DEVICE_ISA) - mach64->config_stat0 |= 7; /*ISA 16-bit, 256k16 DRAM*/ - - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - - if (info->flags & DEVICE_PCI) + if (info->flags & DEVICE_PCI) { + mach64->config_stat0 |= 7; /*PCI, 256Kx16 DRAM*/ + ati_eeprom_load(&mach64->eeprom, "mach64_pci.nvr", 1); rom_init(&mach64->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_VLB) - rom_init(&mach64->bios_rom, BIOS_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_ISA) - rom_init(&mach64->bios_rom, BIOS_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - if (info->flags & DEVICE_PCI) mem_mapping_disable(&mach64->bios_rom.mapping); + } else if (info->flags & DEVICE_VLB) { + mach64->config_stat0 |= 6; /*VLB, 256Kx16 DRAM*/ + ati_eeprom_load(&mach64->eeprom, "mach64_vlb.nvr", 1); + rom_init(&mach64->bios_rom, BIOS_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } else if (info->flags & DEVICE_ISA) { + mach64->config_stat0 |= 0; /*ISA 16-bit, 256k16 DRAM*/ + ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + rom_init(&mach64->bios_rom, BIOS_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } return mach64; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 29a687f24..be2c5d547 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -332,8 +332,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { - if (cpu_input && (cmd_type == 2)) + if ((cmd_type == 2) && cpu_input) { mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + } } switch (cmd_type) { @@ -816,7 +817,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; - if (mach->accel.dp_config == 0x5211) { + if ((mach->accel.dp_config == 0x5211) || (mach->accel.dp_config == 0x3251)) { if (mach->accel.dest_x_end == 1024) { goto skip_dx; } @@ -2602,7 +2603,7 @@ mach_recalctimings(svga_t *svga) dev->rowcount = !!(dev->disp_cntl & 0x08); mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04); - if ((dev->hdisp == 640) || (dev->hdisp == 800) || (dev->hdisp == 1280) || dev->bpp) { + if ((dev->hdisp != 1024) || dev->bpp) { /*For VESA/ATI modes in 8514/A mode.*/ dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; @@ -4865,14 +4866,22 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int writemask2 = svga->writemask; int reset_wm = 0; - latch_t vall; + latch8514_t vall; uint8_t wm = svga->writemask; uint8_t count; uint8_t i; cycles -= svga->monitor->mon_video_timing_write_b; - if (!linear) { + if (linear) { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return; + addr &= dev->vram_mask; + dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + dev->vram[addr] = val; + return; + } else { addr = mach32_decode_addr(svga, addr, 1); if (addr == 0xffffffff) return; @@ -4881,15 +4890,12 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - mach_log("WriteCommon chain4 = %x.\n", svga->chain4); if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } else if (svga->chain4 && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); - if (!linear) - addr &= ~3; - + addr &= ~3; addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -4934,7 +4940,7 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) case 1: for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = svga->latch.b[i]; + dev->vram[addr | i] = dev->latch.b[i]; } return; case 2: @@ -4944,7 +4950,7 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (dev->latch.b[i] & ~svga->gdcreg[8]); } return; } @@ -4967,25 +4973,25 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) case 0x00: /* Set */ for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (dev->latch.b[i] & ~svga->gdcreg[8]); } break; case 0x08: /* AND */ for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + dev->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & dev->latch.b[i]; } break; case 0x10: /* OR */ for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | dev->latch.b[i]; } break; case 0x18: /* XOR */ for (i = 0; i < count; i++) { if (writemask2 & (1 << i)) - dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ dev->latch.b[i]; } break; @@ -5022,11 +5028,43 @@ mach32_writel(uint32_t addr, uint32_t val, void *priv) mach32_write_common(addr + 3, val >> 24, 0, mach); } +static __inline void +mach32_writew_linear(uint32_t addr, uint16_t val, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + cycles -= svga->monitor->mon_video_timing_write_w; + + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return; + addr &= dev->vram_mask; + dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + *(uint16_t *) &dev->vram[addr] = val; +} + +static __inline void +mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + cycles -= svga->monitor->mon_video_timing_write_l; + + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return; + addr &= dev->vram_mask; + dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + *(uint32_t *) &dev->vram[addr] = val; +} + static __inline uint8_t mach32_read_common(uint32_t addr, int linear, mach_t *mach) { svga_t *svga = &mach->svga; - const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint32_t latch_addr = 0; int readplane = svga->readplane; uint8_t count; @@ -5035,7 +5073,13 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) cycles -= svga->monitor->mon_video_timing_read_b; - if (!linear) { + if (linear) { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xff; + + return dev->vram[addr & dev->vram_mask]; + } else { addr = mach32_decode_addr(svga, addr, 0); if (addr == 0xffffffff) return 0xff; @@ -5046,14 +5090,13 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) latch_addr = (addr << count) & svga->decode_mask; count = (1 << count); - mach_log("ReadCommon chain4 = %x.\n", svga->chain4); if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= dev->vram_size) return 0xff; latch_addr = (addr & dev->vram_mask) & ~3; for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = dev->vram[latch_addr | i]; + dev->latch.b[i] = dev->vram[latch_addr | i]; return dev->vram[addr & dev->vram_mask]; } else if (svga->chain4 && !svga->force_old_addr) { readplane = addr & 3; @@ -5068,7 +5111,7 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) return 0xff; latch_addr = (addr & dev->vram_mask) & ~3; for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = dev->vram[latch_addr | i]; + dev->latch.b[i] = dev->vram[latch_addr | i]; return dev->vram[addr & dev->vram_mask]; } @@ -5077,12 +5120,12 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) /* standard VGA latched access */ if (latch_addr >= dev->vram_size) { for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = 0xff; + dev->latch.b[i] = 0xff; } else { latch_addr &= dev->vram_mask; for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = dev->vram[latch_addr | i]; + dev->latch.b[i] = dev->vram[latch_addr | i]; } if (addr >= dev->vram_size) @@ -5097,7 +5140,7 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) for (uint8_t plane = 0; plane < count; plane++) { if (svga->colournocare & (1 << plane)) { /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ - if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) + if (((dev->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) temp &= ~(1 << pixel); } } @@ -5144,6 +5187,36 @@ mach32_readl(uint32_t addr, void *priv) return ret; } +static __inline uint16_t +mach32_readw_linear(uint32_t addr, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + cycles -= svga->monitor->mon_video_timing_read_w; + + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xffff; + + return *(uint16_t *) &dev->vram[addr & dev->vram_mask]; +} + +static __inline uint32_t +mach32_readl_linear(uint32_t addr, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + cycles -= svga->monitor->mon_video_timing_read_l; + + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xffffffff; + + return *(uint32_t *) &dev->vram[addr & dev->vram_mask]; +} + static void mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) { @@ -5190,8 +5263,7 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) } else { mach_log("Linear WORDW Write=%08x, val=%04x.\n", addr, val); if (dev->on[0] || dev->on[1]) { - mach32_write_common(addr, val & 0xff, 1, mach); - mach32_write_common(addr + 1, val >> 8, 1, mach); + mach32_writew_linear(addr, val, mach); } else svga_writew_linear(addr, val, svga); } @@ -5219,10 +5291,7 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) } else { mach_log("Linear WORDL Write=%08x, val=%08x.\n", addr, val); if (dev->on[0] || dev->on[1]) { - mach32_write_common(addr, val & 0xff, 1, mach); - mach32_write_common(addr + 1, val >> 8, 1, mach); - mach32_write_common(addr + 2, val >> 16, 1, mach); - mach32_write_common(addr + 3, val >> 24, 1, mach); + mach32_writel_linear(addr, val, mach); } else svga_writel_linear(addr, val, svga); } @@ -5272,8 +5341,7 @@ mach32_ap_readw(uint32_t addr, void *priv) temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); } else { if (dev->on[0] || dev->on[1]) { - temp = mach32_read_common(addr, 1, mach); - temp |= (mach32_read_common(addr + 1, 1, mach) << 8); + temp = mach32_readw_linear(addr, mach); } else temp = svga_readw_linear(addr, svga); @@ -5303,10 +5371,7 @@ mach32_ap_readl(uint32_t addr, void *priv) } } else { if (dev->on[0] || dev->on[1]) { - temp = mach32_read_common(addr, 1, mach); - temp |= (mach32_read_common(addr + 1, 1, mach) << 8); - temp |= (mach32_read_common(addr + 2, 1, mach) << 16); - temp |= (mach32_read_common(addr + 3, 1, mach) << 24); + temp = mach32_readl_linear(addr, mach); } else temp = svga_readl_linear(addr, svga); From 0561f65592df6239853eb66c6dbce9626465ddbd Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 May 2024 01:28:16 +0200 Subject: [PATCH 517/690] Sound Blaster: automatic DRQ clearing. --- src/dma.c | 55 +++++++------ src/sound/snd_sb_dsp.c | 172 ++++++++++++++++++++++++----------------- 2 files changed, 130 insertions(+), 97 deletions(-) diff --git a/src/dma.c b/src/dma.c index 318c6cda2..0593d0395 100644 --- a/src/dma.c +++ b/src/dma.c @@ -458,8 +458,8 @@ static uint8_t dma_read(uint16_t addr, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; - uint8_t temp; - int count; + int count; + uint8_t ret = (dmaregs[0][addr & 0xf]); switch (addr & 0xf) { case 0: @@ -468,8 +468,10 @@ dma_read(uint16_t addr, UNUSED(void *priv)) case 6: /*Address registers*/ dma_wp[0] ^= 1; if (dma_wp[0]) - return (dma[channel].ac & 0xff); - return ((dma[channel].ac >> 8) & 0xff); + ret = (dma[channel].ac & 0xff); + else + ret = ((dma[channel].ac >> 8) & 0xff); + break; case 1: case 3: @@ -477,29 +479,30 @@ dma_read(uint16_t addr, UNUSED(void *priv)) case 7: /*Count registers*/ dma_wp[0] ^= 1; count = dma[channel].cc/* + 1*/; - // if (count > dma[channel].cb) - // count = 0x0000; if (dma_wp[0]) - temp = count & 0xff; + ret = count & 0xff; else - temp = count >> 8; - return temp; + ret = count >> 8; + break; case 8: /*Status register*/ - temp = dma_stat_rq_pc & 0xf; - temp <<= 4; - temp |= dma_stat & 0xf; + ret = dma_stat_rq_pc & 0xf; + ret <<= 4; + ret |= dma_stat & 0xf; dma_stat &= ~0xf; - return temp; + break; case 0xd: /*Temporary register*/ - return 0; + ret = 0x00; + break; default: break; } - return (dmaregs[0][addr & 0xf]); + dma_log("DMA: [R] %04X = %02X\n", addr, ret); + + return ret; } static void @@ -507,6 +510,8 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; + dma_log("DMA: [W] %04X = %02X\n", addr, val); + dmaregs[0][addr & 0xf] = val; switch (addr & 0xf) { case 0: @@ -537,7 +542,7 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) dma_command[0] = val; #ifdef ENABLE_DMA_LOG if (val & 0x01) - pclog("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc); + dma_log("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc); #endif return; @@ -546,9 +551,7 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) if (val & 4) { dma_stat_rq_pc |= (1 << channel); if ((channel == 0) && (dma_command[0] & 0x01)) { -#ifdef ENABLE_DMA_LOG - pclog("Memory to memory transfer start\n"); -#endif + dma_log("Memory to memory transfer start\n"); dma_mem_to_mem_transfer(); } else dma_block_transfer(channel); @@ -828,9 +831,7 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) break; } -#ifdef ENABLE_DMA_LOG - pclog("dma16_read(%08X) = %02X\n", port, ret); -#endif + dma_log("dma16_read(%08X) = %02X\n", port, ret); return ret; } @@ -839,9 +840,9 @@ static void dma16_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; -#ifdef ENABLE_DMA_LOG - pclog("dma16_write(%08X, %02X)\n", addr, val); -#endif + + dma_log("dma16_write(%08X, %02X)\n", addr, val); + addr >>= 1; dmaregs[1][addr & 0xf] = val; @@ -944,6 +945,8 @@ dma_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { uint8_t convert[8] = CHANNELS; + dma_log("DMA: [W] %04X = %02X\n", addr, val); + #ifdef USE_DYNAREC if ((addr == 0x84) && cpu_use_dynarec) update_tsc(); @@ -1020,6 +1023,8 @@ dma_page_read(uint16_t addr, UNUSED(void *priv)) ret = dma[addr].page_l; } + dma_log("DMA: [R] %04X = %02X\n", addr, ret); + return ret; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index e5c2359a0..88f690762 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -543,9 +543,41 @@ sb_ess_get_dma_len(const sb_dsp_t *dsp) return 0x10000U - sb_ess_get_dma_counter(dsp); } +static void +sb_resume_dma(const sb_dsp_t *dsp, const int is_8) +{ + if IS_ESS(dsp) + { + dma_set_drq(dsp->sb_8_dmanum, 1); + dma_set_drq(dsp->sb_16_8_dmanum, 1); + } else if (is_8) + dma_set_drq(dsp->sb_8_dmanum, 1); + else { + if (dsp->sb_16_dmanum != 0xff) + dma_set_drq(dsp->sb_16_dmanum, 1); + + if (dsp->sb_16_8_dmanum != 0xff) + dma_set_drq(dsp->sb_16_8_dmanum, 1); + } +} + +static void +sb_stop_dma(const sb_dsp_t *dsp) +{ + dma_set_drq(dsp->sb_8_dmanum, 0); + + if (dsp->sb_16_dmanum != 0xff) + dma_set_drq(dsp->sb_16_dmanum, 0); + + if (dsp->sb_16_8_dmanum != 0xff) + dma_set_drq(dsp->sb_16_8_dmanum, 0); +} + void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { + sb_stop_dma(dsp); + dsp->sb_pausetime = -1; if (dma8) { @@ -590,6 +622,8 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { + sb_stop_dma(dsp); + if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -1549,35 +1583,43 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xD0: /* Pause 8-bit DMA */ dsp->sb_8_pause = 1; + sb_stop_dma(dsp); break; case 0xD1: /* Speaker on */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) + if (dsp->sb_type < SB15) { dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) + sb_stop_dma(dsp); + } else if (dsp->sb_type < SB16) dsp->muted = 0; } dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) + if (dsp->sb_type < SB15) { dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) + sb_stop_dma(dsp); + } else if (dsp->sb_type < SB16) dsp->muted = 1; } dsp->sb_speaker = 0; break; case 0xD4: /* Continue 8-bit DMA */ dsp->sb_8_pause = 0; + sb_resume_dma(dsp, 1); break; case 0xD5: /* Pause 16-bit DMA */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { dsp->sb_16_pause = 1; + sb_stop_dma(dsp); + } break; case 0xD6: /* Continue 16-bit DMA */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { dsp->sb_16_pause = 0; + sb_resume_dma(dsp, 1); + } break; case 0xD8: /* Get speaker status */ sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); @@ -2002,7 +2044,12 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Default values. Use sb_dsp_setxxx() methods to change. */ dsp->sb_irqnum = 7; dsp->sb_8_dmanum = 1; - dsp->sb_16_dmanum = 5; + if (type >= SB16) + dsp->sb_16_dmanum = 5; + else + dsp->sb_16_dmanum = 0xff; + if ((type >= SB16) || IS_ESS(dsp)) + dsp->sb_16_8_dmanum = 0x1; dsp->mpu = NULL; dsp->sbleftright_default = 0; @@ -2111,13 +2158,14 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, dsp->dma_priv = priv; } -void -sb_ess_finish_dma(sb_dsp_t *dsp) +static void +sb_finish_dma(sb_dsp_t *dsp) { - if (!dsp->ess_playback_mode) - return; - ESSreg(0xB8) &= ~0x01; - dma_set_drq(dsp->sb_8_dmanum, 0); + if (dsp->ess_playback_mode) { + ESSreg(0xB8) &= ~0x01; + dma_set_drq(dsp->sb_8_dmanum, 0); + } else + sb_stop_dma(dsp); } void @@ -2347,34 +2395,29 @@ pollsb(void *priv) break; case ESPCM_4: - if (dsp->espcm_sample_idx >= 19) { + if (dsp->espcm_sample_idx >= 19) dsp->espcm_sample_idx = 0; - } if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + if (fifo_get_empty(dsp->espcm_fifo)) break; - } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; tempi = dsp->espcm_byte_buffer[0] >> 4; } else if (dsp->espcm_sample_idx & 1) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + if (fifo_get_empty(dsp->espcm_fifo)) break; - } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; tempi = dsp->espcm_byte_buffer[0] & 0x0F; - } else { + } else tempi = dsp->espcm_byte_buffer[0] >> 4; - } - if (dsp->espcm_sample_idx == 18) { + if (dsp->espcm_sample_idx == 18) dsp->sb_8_length--; - } dsp->espcm_sample_idx++; @@ -2389,20 +2432,17 @@ pollsb(void *priv) else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } else { + } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - } break; case ESPCM_3: - if (dsp->espcm_sample_idx >= 19) { + if (dsp->espcm_sample_idx >= 19) dsp->espcm_sample_idx = 0; - } if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + if (fifo_get_empty(dsp->espcm_fifo)) break; - } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2411,15 +2451,13 @@ pollsb(void *priv) } else if (dsp->espcm_sample_idx == 1) { for (tempi = 0; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + if (fifo_get_empty(dsp->espcm_fifo)) break; - } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) { + if (tempi < 4) break; - } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; @@ -2440,15 +2478,13 @@ pollsb(void *priv) } else if (dsp->espcm_sample_idx == 11) { for (tempi = 1; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + if (fifo_get_empty(dsp->espcm_fifo)) break; - } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) { + if (tempi < 4) break; - } dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; @@ -2485,20 +2521,19 @@ pollsb(void *priv) else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } else { + } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - } break; case ESPCM_1: - if (dsp->espcm_sample_idx >= 19) { + if (dsp->espcm_sample_idx >= 19) dsp->espcm_sample_idx = 0; - } if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) { + + if (fifo_get_empty(dsp->espcm_fifo)) break; - } + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2520,13 +2555,12 @@ pollsb(void *priv) dsp->espcm_byte_buffer[0] >>= 1; } - if (dsp->espcm_sample_idx == 18) { + if (dsp->espcm_sample_idx == 18) dsp->sb_8_length--; - } dsp->espcm_sample_idx++; - tempi |= (dsp->espcm_range << 4); + tempi |= (dsp->espcm_range << 4); data[0] = (int) espcm_range_map[tempi]; dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { @@ -2537,9 +2571,8 @@ pollsb(void *priv) else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } else { + } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - } break; default: @@ -2552,7 +2585,7 @@ pollsb(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } sb_irq(dsp, 1); dsp->ess_irq_generic = true; @@ -2562,16 +2595,16 @@ pollsb(void *priv) if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; - dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); - dsp->ess_dma_counter += temp; + const uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; } } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { @@ -2626,7 +2659,7 @@ pollsb(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } sb_irq(dsp, 0); dsp->ess_irq_generic = true; @@ -2636,16 +2669,16 @@ pollsb(void *priv) if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; - dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); - dsp->ess_dma_counter += temp; + const uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; } } if (dsp->sb_pausetime > -1) { @@ -2715,12 +2748,10 @@ sb_poll_i(void *priv) for (i = 0; i < 19; i++) { s = dsp->espcm_sample_buffer[i]; - if (s < min_sample) { + if (s < min_sample) min_sample = s; - } - if (s > max_sample) { + if (s > max_sample) max_sample = s; - } } if (min_sample < 0) { if (min_sample == -128) @@ -2738,9 +2769,8 @@ sb_poll_i(void *priv) max_sample = min_sample; for (table_addr = 15; table_addr < 256; table_addr += 16) { - if (max_sample <= espcm_range_map[table_addr]) { + if (max_sample <= espcm_range_map[table_addr]) break; - } } dsp->espcm_range = table_addr >> 4; @@ -2750,12 +2780,10 @@ sb_poll_i(void *priv) s = dsp->espcm_sample_buffer[i]; for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) { int sigma = espcm_range_map[table_addr] - s; - if (sigma < 0) { + if (sigma < 0) sigma = -sigma; - } - if (sigma > last_sigma) { + if (sigma > last_sigma) break; - } last_sigma = sigma; } table_addr--; @@ -2787,7 +2815,7 @@ sb_poll_i(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } sb_irq(dsp, 1); dsp->ess_irq_generic = true; @@ -2797,7 +2825,7 @@ sb_poll_i(void *priv) if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); @@ -2857,7 +2885,7 @@ sb_poll_i(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } sb_irq(dsp, 0); dsp->ess_irq_generic = true; @@ -2867,7 +2895,7 @@ sb_poll_i(void *priv) if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); - sb_ess_finish_dma(dsp); + sb_finish_dma(dsp); } if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); From aaf3ab575ee7a5b3904f101ec6c424dce007d21f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 17 May 2024 15:09:04 -0400 Subject: [PATCH 518/690] Add new platform functions for global directories --- src/include/86box/plat.h | 4 +++- src/qt/qt_platform.cpp | 36 ++++++++++++++++++++++++++++-------- src/unix/unix.c | 31 ++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 5b36bab7e..975133f6c 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -138,7 +138,9 @@ extern int plat_getcwd(char *bufp, int max); extern int plat_chdir(char *path); extern void plat_tempfile(char *bufp, char *prefix, char *suffix); extern void plat_get_exe_name(char *s, int size); -extern void plat_get_global_config_dir(char* strptr); +extern void plat_get_global_config_dir(char *outbuf, uint8_t len); +extern void plat_get_global_data_dir(char *outbuf, uint8_t len); +extern void plat_get_temp_dir(char *outbuf, uint8_t len); extern void plat_init_rom_paths(void); extern int plat_dir_check(char *path); extern int plat_dir_create(char *path); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index e0b11ad7b..ef1942b3d 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -634,15 +634,34 @@ plat_chdir(char *path) } void -plat_get_global_config_dir(char* strptr) +plat_get_global_config_dir(char *outbuf, const uint8_t len) { -#ifdef __APPLE__ - auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)[0] + "/net.86Box.86Box/"); -#else - auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)[0] + "/86Box/"); -#endif - if (!dir.exists()) dir.mkpath("."); - strncpy(strptr, dir.canonicalPath().toUtf8().constData(), 1024); + const auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation)[0]); + if (!dir.exists()) { + if (!dir.mkpath(".")) { + qWarning("Failed to create global configuration directory %s", dir.absolutePath().toUtf8().constData()); + } + } + strncpy(outbuf, dir.canonicalPath().toUtf8().constData(), len); +} + +void +plat_get_global_data_dir(char *outbuf, const uint8_t len) +{ + const auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0]); + if (!dir.exists()) { + if (!dir.mkpath(".")) { + qWarning("Failed to create global data directory %s", dir.absolutePath().toUtf8().constData()); + } + } + strncpy(outbuf, dir.canonicalPath().toUtf8().constData(), len); +} + +void +plat_get_temp_dir(char *outbuf, const uint8_t len) +{ + const auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0]); + strncpy(outbuf, dir.canonicalPath().toUtf8().constData(), len); } void @@ -662,6 +681,7 @@ plat_init_rom_paths(void) for (auto &path : paths) { #ifdef __APPLE__ rom_add_path(QDir(path).filePath("net.86Box.86Box/roms").toUtf8().constData()); + rom_add_path(QDir(path).filePath("86Box/roms").toUtf8().constData()); #else rom_add_path(QDir(path).filePath("86Box/roms").toUtf8().constData()); #endif diff --git a/src/unix/unix.c b/src/unix/unix.c index 3eddc2bbb..58cb1448f 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -826,15 +826,32 @@ plat_init_rom_paths(void) } void -plat_get_global_config_dir(char *strptr) +plat_get_global_config_dir(char *outbuf, const uint8_t len) { -#ifdef __APPLE__ - char *prefPath = SDL_GetPrefPath(NULL, "net.86Box.86Box"); -#else char *prefPath = SDL_GetPrefPath(NULL, "86Box"); -#endif - strncpy(strptr, prefPath, 1024); - path_slash(strptr); + strncpy(outbuf, prefPath, len); + path_slash(outbuf); + SDL_free(prefPath); +} + +void +plat_get_global_data_dir(char *outbuf, const uint8_t len) +{ + char *prefPath = SDL_GetPrefPath(NULL, "86Box"); + strncpy(outbuf, prefPath, len); + path_slash(outbuf); + SDL_free(prefPath); +} + +void +plat_get_temp_dir(char *outbuf, uint8_t len) +{ + const char *tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL) { + tmpdir = "/tmp"; + } + strncpy(outbuf, tmpdir, len); + path_slash(outbuf); } bool From 2de3073da14bbaf379370b69fd9acf6b63ae49f8 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 17 May 2024 15:13:36 -0400 Subject: [PATCH 519/690] GHA: Disable 32-bit windows builds --- .github/workflows/cmake_windows_msys2.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index d3f679a78..36442684a 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -67,9 +67,9 @@ jobs: environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake +# - msystem: MINGW32 +# prefix: mingw-w64-i686 +# toolchain: ./cmake/flags-gcc-i686.cmake - msystem: MINGW64 prefix: mingw-w64-x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake From 7cad5b3f40e3c284262fe5d8eeda921c29efac0a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 18 May 2024 17:42:54 +0200 Subject: [PATCH 520/690] NEC Mate NX MA30D: The actual board has no AGP slot, closes #4459. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index dd3d58625..18bcc5a82 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13865,7 +13865,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, From 4fdb339407233905f12907147f2be024b8bc2128 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 18 May 2024 19:42:00 +0200 Subject: [PATCH 521/690] Attempt #2 to implement CD-ROM passthrough. Still Windows only on the QT side. --- src/cdrom/CMakeLists.txt | 2 +- src/cdrom/cdrom.c | 28 +-- src/cdrom/cdrom_ioctl.c | 83 +++++---- src/config.c | 4 +- src/include/86box/cdrom.h | 4 +- src/include/86box/cdrom_ioctl.h | 32 ++++ src/include/86box/plat_cdrom.h | 66 +++++++ src/machine_status.c | 8 +- src/qt/qt_machinestatus.cpp | 2 +- src/qt/qt_mediamenu.cpp | 72 ++++++-- src/qt/qt_mediamenu.hpp | 2 + src/qt/win_cdrom_ioctl.c | 300 +++++++++++++------------------- 12 files changed, 356 insertions(+), 247 deletions(-) create mode 100644 src/include/86box/cdrom_ioctl.h create mode 100644 src/include/86box/plat_cdrom.h diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 201cee7f6..d3b38095e 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -13,4 +13,4 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c) +add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_ioctl.c cdrom_mitsumi.c) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index e4e76ea66..06494e4a9 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1972,7 +1972,8 @@ cdrom_hard_reset(void) #endif cdrom_image_open(dev, dev->image_path); - } + } else if (dev->host_drive == 201) + cdrom_ioctl_open(dev, dev->image_path, dev->letter); } } @@ -2028,7 +2029,7 @@ cdrom_eject(uint8_t id) if (dev->host_drive == 200) strcpy(dev->prev_image_path, dev->image_path); - dev->prev_host_drive = dev->host_drive; + dev->prev_host_drive = dev->host_drive + (dev->host ? 1 : 0); dev->host_drive = 0; dev->ops->exit(dev); @@ -2058,26 +2059,33 @@ cdrom_reload(uint8_t id) dev->ops = NULL; memset(dev->image_path, 0, sizeof(dev->image_path)); - if (dev->prev_host_drive == 200) { + if (dev->prev_host_drive >= 200) { /* Reload a previous image. */ strcpy(dev->image_path, dev->prev_image_path); #ifdef _WIN32 - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) - dev->image_path[strlen(dev->image_path) - 1] = '\\'; + if (dev->prev_host_drive == 200) { + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; + } #else - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) - dev->image_path[strlen(dev->image_path) - 1] = '/'; + if (dev->prev_host_drive == 200) { + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; + } #endif - cdrom_image_open(dev, dev->image_path); + if (dev->prev_host_drive > 200) + cdrom_ioctl_open(dev, dev->image_path, dev->letter); + else + cdrom_image_open(dev, dev->image_path); cdrom_insert(id); - if (strlen(dev->image_path) == 0) + if ((strlen(dev->image_path) == 0) && !dev->letter) dev->host_drive = 0; else - dev->host_drive = 200; + dev->host_drive = 200 + (dev->host ? 1 : 0); } plat_cdrom_ui_update(id, 1); diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index 382465637..861c46eac 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -58,7 +58,7 @@ cdrom_ioctl_log(const char *fmt, ...) static void cdrom_ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) { - TMSF tmsf; + TMSF tmsf; plat_cdrom_get_audio_tracks(first, last, &tmsf); } @@ -94,14 +94,29 @@ cdrom_ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *sub } static int -cdrom_ioctl_is_track_audio(uint32_t pos, int ismsf) +cdrom_ioctl_get_capacity(UNUSED(cdrom_t *dev)) +{ + int ret; + + ret = plat_cdrom_get_last_block(); + pclog("GetCapacity=%x.\n", ret); + return ret; +} + +static int +cdrom_ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { uint8_t attr; + TMSF tmsf; int m; int s; int f; + int number; int track; + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + if (ismsf) { m = (pos >> 16) & 0xff; s = (pos >> 8) & 0xff; @@ -110,13 +125,20 @@ cdrom_ioctl_is_track_audio(uint32_t pos, int ismsf) } /* GetTrack requires LBA. */ - return plat_cdrom_get_audio_track(pos); + return plat_cdrom_is_track_audio(pos); } static int -cdrom_ioctl_sector_size(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) +cdrom_ioctl_is_track_pre(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) { - return plat_get_sector_size(); + return 0; +} + +static int +cdrom_ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba) +{ + pclog("LBA=%x.\n", lba); + return plat_cdrom_get_sector_size(lba); } static int @@ -128,21 +150,18 @@ cdrom_ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba case CD_READ_AUDIO: return plat_cdrom_read_sector(b, 1, lba); case CD_READ_RAW: - if (plat_get_sector_size() == 2352) - return plat_cdrom_read_sector(b, 1, lba); - else - return plat_cdrom_read_sector(b, 0, lba); - break; + return plat_cdrom_read_sector(b, 1, lba); default: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); - return 0; + break; } + return 0; } static int -cdrom_ioctl_track_type(UNUSED(cdrom_t *dev), uint32_t lba) +cdrom_ioctl_track_type(cdrom_t *dev, uint32_t lba) { - if (cdrom_ioctl_is_track_audio(lba, 0)) + if (cdrom_ioctl_is_track_audio(dev, lba, 0)) return CD_TRACK_AUDIO; return 0; @@ -151,9 +170,10 @@ cdrom_ioctl_track_type(UNUSED(cdrom_t *dev), uint32_t lba) static void cdrom_ioctl_exit(cdrom_t *dev) { + cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path); dev->cd_status = CD_STATUS_EMPTY; - plat_cdrom_exit(); + plat_cdrom_close(); dev->ops = NULL; } @@ -162,7 +182,7 @@ static const cdrom_ops_t cdrom_ioctl_ops = { cdrom_ioctl_get_tracks, cdrom_ioctl_get_track_info, cdrom_ioctl_get_subchannel, - NULL, + cdrom_ioctl_is_track_pre, cdrom_ioctl_sector_size, cdrom_ioctl_read_sector, cdrom_ioctl_track_type, @@ -170,48 +190,38 @@ static const cdrom_ops_t cdrom_ioctl_ops = { }; void -cdrom_ioctl_eject(void) +cdrom_ioctl_close(cdrom_t *dev) { - plat_cdrom_eject(); -} + cdrom_ioctl_log("CDROM: ioctl_close(%s)\n", dev->image_path); -void -cdrom_ioctl_load(void) -{ - plat_cdrom_load(); + if (dev && dev->ops && dev->ops->exit) + dev->ops->exit(dev); } static int cdrom_ioctl_open_abort(cdrom_t *dev) { - if (dev && dev->ops && dev->ops->exit) - dev->ops->exit(dev); - + cdrom_ioctl_close(dev); dev->ops = NULL; dev->host_drive = 0; - dev->ioctl_path[0] = 0; + dev->image_path[0] = 0; return 1; } int -cdrom_ioctl_open(cdrom_t *dev, const char *path) +cdrom_ioctl_open(cdrom_t *dev, char *path, int letter) { - /* Open the drive. */ - if (plat_cdrom_open()) + /* Open the image. */ + int i = plat_cdrom_open(path, letter); + if (!i) return cdrom_ioctl_open_abort(dev); - /* Make sure to not STRCPY if the two are pointing - at the same place. */ - if (path != dev->ioctl_path) - strcpy(dev->ioctl_path, path); - /* All good, reset state. */ dev->cd_status = CD_STATUS_STOPPED; dev->is_dir = 0; dev->seek_pos = 0; dev->cd_buflen = 0; - plat_cdrom_reset(); - dev->cdrom_capacity = plat_cdrom_get_capacity(); + dev->cdrom_capacity = cdrom_ioctl_get_capacity(dev); pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); /* Attach this handler to the drive. */ @@ -219,3 +229,4 @@ cdrom_ioctl_open(cdrom_t *dev, const char *path) return 0; } + diff --git a/src/config.c b/src/config.c index 02c1d276a..fdecb6cd5 100644 --- a/src/config.c +++ b/src/config.c @@ -1263,7 +1263,7 @@ load_floppy_and_cdrom_drives(void) path_normalize(cdrom[c].image_path); } - if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) + if (cdrom[c].host_drive && (cdrom[c].host_drive != 200) && (cdrom[c].host_drive != 201)) cdrom[c].host_drive = 0; if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) @@ -2575,7 +2575,7 @@ save_floppy_and_cdrom_drives(void) for (c = 0; c < CDROM_NUM; c++) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); - if ((cdrom[c].bus_type == 0) || (cdrom[c].host_drive != 200)) + if ((cdrom[c].bus_type == 0) || ((cdrom[c].host_drive != 200) && (cdrom[c].host_drive != 201))) ini_section_delete_var(cat, temp); else ini_section_set_int(cat, temp, cdrom[c].host_drive); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 15127b06e..de72974d1 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -246,6 +246,8 @@ typedef struct cdrom { int audio_op; int audio_muted_soft; int sony_msf; + int host; + int letter; const cdrom_ops_t *ops; @@ -309,7 +311,7 @@ extern void cdrom_image_reset(cdrom_t *dev); extern void cdrom_ioctl_eject(void); extern void cdrom_ioctl_load(void); -extern int cdrom_ioctl_open(cdrom_t *dev, const char d); +extern int cdrom_ioctl_open(cdrom_t *dev, char *path, int letter); extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); diff --git a/src/include/86box/cdrom_ioctl.h b/src/include/86box/cdrom_ioctl.h new file mode 100644 index 000000000..5fc157615 --- /dev/null +++ b/src/include/86box/cdrom_ioctl.h @@ -0,0 +1,32 @@ +/* + * 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. + * + * CD-ROM image file handling module header, translated to C + * from cdrom_dosbox.h. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2016-2022 RichardG. + * Copyright 2016-2022 Miran Grca. + */ +#ifndef CDROM_IOCTL_H +#define CDROM_IOCTL_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*CDROM_IOCTL_H*/ diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h new file mode 100644 index 000000000..38246bd07 --- /dev/null +++ b/src/include/86box/plat_cdrom.h @@ -0,0 +1,66 @@ +/* + * 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. + * + * Definitions for platform specific serial to host passthrough. + * + * + * Authors: Andreas J. Reichel , + * Jasmine Iwanek + * + * Copyright 2021 Andreas J. Reichel. + * Copyright 2021-2022 Jasmine Iwanek. + */ + +#ifndef PLAT_CDROM_H +#define PLAT_CDROM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M, S, F) \ + { \ + uint64_t value = f; \ + *(F) = (value % CD_FPS) & 0xff; \ + value /= CD_FPS; \ + *(S) = (value % 60) & 0xff; \ + value /= 60; \ + *(M) = value & 0xff; \ + } +#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F)) + +typedef struct SMSF { + uint16_t min; + uint8_t sec; + uint8_t fr; +} TMSF; + +extern int plat_cdrom_is_track_audio(uint32_t sector); +extern int plat_cdrom_get_last_block(void); +extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); +extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); +extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); +extern int plat_cdrom_get_sector_size(uint32_t sector); +extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); +extern void plat_cdrom_close(void); +extern int plat_cdrom_open(char *path, int letter); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/machine_status.c b/src/machine_status.c index 65f4704b4..03c0ac092 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -33,7 +33,11 @@ machine_status_init(void) machine_status.fdd[i].active = false; } for (size_t i = 0; i < CDROM_NUM; ++i) { - machine_status.cdrom[i].empty = cdrom[i].host_drive != 200 || (strlen(cdrom[i].image_path) == 0); + if (cdrom[i].host) + machine_status.cdrom[i].empty = cdrom[i].host_drive != 201; + else + machine_status.cdrom[i].empty = cdrom[i].host_drive != 200 || (strlen(cdrom[i].image_path) == 0); + machine_status.cdrom[i].active = false; } for (size_t i = 0; i < ZIP_NUM; i++) { @@ -55,4 +59,4 @@ machine_status_init(void) machine_status.net[i].active = false; machine_status.net[i].empty = !network_is_connected(i); } -} \ No newline at end of file +} diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 53e875e33..a36efd2cd 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -533,7 +533,7 @@ MachineStatus::refresh(QStatusBar *sbar) iterateCDROM([this, sbar](int i) { d->cdrom[i].label = std::make_unique(); - d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty()); + d->cdrom[i].setEmpty(((cdrom[i].host_drive != 200) && (cdrom[i].host_drive != 201)) || QString(cdrom[i].image_path).isEmpty()); d->cdrom[i].setActive(false); d->cdrom[i].refresh(); connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index c4fd50567..e6d52a823 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -29,6 +29,21 @@ #include extern "C" { +#ifdef Q_OS_WINDOWS +#define BITMAP WINDOWS_BITMAP +#undef UNICODE +#include +#include +#undef BITMAP +#endif +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/config.h> #include <86box/device.h> @@ -131,14 +146,25 @@ MediaMenu::refresh(QMenu *parentMenu) cdromMutePos = menu->children().count(); menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); - menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdromMount(i, 0); })->setCheckable(false); - menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdromMount(i, 1); })->setCheckable(false); + menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdrom[i].host = 0; cdrom[i].letter = 0; cdromMount(i, 0); })->setCheckable(false); + menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdrom[i].host = 0; cdrom[i].letter = 0; cdromMount(i, 1); })->setCheckable(false); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cdromImageHistoryPos[slot] = menu->children().count(); menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { cdromReload(i, slot); })->setCheckable(false); } menu->addSeparator(); +#ifdef Q_OS_WINDOWS + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (auto &letter : driveLetters) { + auto drive = QString::asprintf("%c:\\", letter).toUtf8().constData(); + if (GetDriveType(drive) == DRIVE_CDROM) { + menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdrom[i].host = 1; cdrom[i].letter = letter; cdromMount(i, 0); })->setCheckable(false); + } + } + menu->addSeparator(); +#endif // _WIN32 cdromImagePos = menu->children().count(); cdromDirPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { cdromEject(i); })->setCheckable(false); @@ -467,17 +493,24 @@ MediaMenu::cdromMount(int i, const QString &filename) if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) fn.data()[strlen(fn.data()) - 1] = '/'; #endif - cdrom_image_open(&(cdrom[i]), fn.data()); + if (cdrom[i].host) + cdrom_ioctl_open(&(cdrom[i]), fn.data(), cdrom[i].letter); + else + cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ if (cdrom[i].insert) cdrom[i].insert(cdrom[i].priv); - cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0) ? 0 : 200; - if (cdrom[i].host_drive == 200) { + cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0 && !cdrom[i].letter) ? 0 : (200 + (cdrom[i].host ? 1 : 0)); + + pclog("HostDrive=%d, letter=%d.\n", cdrom[i].host_drive, cdrom[i].letter); + if (cdrom[i].host_drive >= 200) { ui_sb_update_icon_state(SB_CDROM | i, 0); } else { ui_sb_update_icon_state(SB_CDROM | i, 1); } - mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].prev_image_path, cdrom[i].image_path); + if (!cdrom[i].host) + mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].prev_image_path, cdrom[i].image_path); + cdromUpdateMenu(i); ui_sb_update_tip(SB_CDROM | i); config_save(); @@ -489,19 +522,24 @@ MediaMenu::cdromMount(int i, int dir) QString filename; QFileInfo fi(cdrom[i].image_path); - if (dir) { - filename = QFileDialog::getExistingDirectory( - parentWidget); + pclog("IsHost?=%d.\n", cdrom[i].host); + if (cdrom[i].host) { + filename = QString(cdrom[i].letter); } else { - filename = QFileDialog::getOpenFileName( - parentWidget, - QString(), - QString(), - tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - } + if (dir) { + filename = QFileDialog::getExistingDirectory( + parentWidget); + } else { + filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + } - if (filename.isEmpty()) { - return; + if (filename.isEmpty()) { + return; + } } cdromMount(i, filename); diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 7835077b3..2e448086f 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -87,6 +87,8 @@ private: QString getMediaOpenDirectory(); ui::MediaHistoryManager mhm; + const QByteArray driveLetters = QByteArrayLiteral("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + int cassetteRecordPos; int cassettePlayPos; int cassetteRewindPos; diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 9eee9c789..1ba381692 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -32,107 +32,89 @@ #include <86box/plat_unused.h> #include <86box/plat_cdrom.h> -static const char ioctl_path[8]; -static HANDLE hIOCTL; -static CDROM_TOC toc; - /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int -plat_cdrom_get_track(uint32_t sector) -{ - int track = 0; - uint32_t track_addr; - - for (int i = toc.FirstTrack; i < toc.LastTrack; i++) { - /* There must be at least two tracks - data and lead out. */ - track_addr = MSFtoLBA(toc.TrackData[i].Address[1], toc.TrackData[i].Address[2], toc.TrackData[i].Address[3]); - if (track_addr <= sector) { - track = i; - } - } - - pclog("GetTrack = %d.\n", track); - return track; -} +static HANDLE handle; +static char ioctl_path[8]; int -plat_cdrom_get_audio_track(uint32_t sector) +plat_cdrom_is_track_audio(uint32_t sector) { + CDROM_TOC toc; + long size = 0; + int ret; int control = 0; - uint32_t track_addr; + uint32_t track_addr = 0; - for (int i = 0; toc.TrackData[i].TrackNumber != 0xaa; i++) { - /* There must be at least two tracks - data and lead out. */ - track_addr = MSFtoLBA(toc.TrackData[i].Address[1], toc.TrackData[i].Address[2], toc.TrackData[i].Address[3]); - if ((toc.TrackData[i].TrackNumber >= toc.FirstTrack) && (toc.TrackData[i].TrackNumber <= toc.LastTrack) && - (track_addr >= sector)) { - control = toc.TrackData[i].Control; + DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); + plat_cdrom_close(); + + for (int c = 0; toc.TrackData[c].TrackNumber != 0xaa; c++) { + track_addr = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + if ((toc.TrackData[c].TrackNumber >= toc.FirstTrack) && (toc.TrackData[c].TrackNumber <= toc.LastTrack) && + (track_addr >= sector)) + control = toc.TrackData[c].Control; break; - } } - - return (control & 4) ? DATA_TRACK : AUDIO_TRACK; + ret = (control & 0x04) ? 0 : 1; + return ret; } int -plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +plat_cdrom_get_last_block(void) { - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - DWORD size; - int pos = 0; - int cur_track = plat_cdrom_get_track(sector); + CDROM_TOC toc; + int lb = 0; + long size = 0; + uint32_t address = 0; - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - if (plat_cdrom_open()) - return 0; - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &size, NULL); - plat_cdrom_exit(); + DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); + plat_cdrom_close(); - *attr = sub.CurrentPosition.Control; - *track = (uint8_t)(cur_track + 1); - *index = sub.CurrentPosition.IndexNumber; - - FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); - - /* Absolute position should be adjusted by 150, not the relative ones. */ - FRAMES_TO_MSF(sector - toc.FirstTrack, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); - - return 1; + for (int c = 0; c <= toc.LastTrack; c++) { + address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + if (address > lb) + lb = address; + } + pclog("LBCapacity=%x.\n", lb); + return lb; } -int +void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) { - CDROM_TOC toc; - DWORD byteCount; + CDROM_TOC toc; + long size = 0; - *st_track = toc.FirstTrack; - *end = toc.LastTrack; - FRAMES_TO_MSF(toc.TrackData[*end].TrackNumber + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); + DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); + plat_cdrom_close(); - return 1; + *st_track = 1; + *end = toc.LastTrack; + lead_out->min = toc.TrackData[toc.LastTrack].Address[1]; + lead_out->sec = toc.TrackData[toc.LastTrack].Address[2]; + lead_out->fr = toc.TrackData[toc.LastTrack].Address[3]; } /* This replaces both Info and EndInfo, they are specified by a variable. */ int -plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr) +plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - int pos; - DWORD byteCount; + CDROM_TOC toc; + long size = 0; - pclog("plat_cdrom_get_audio_track_info(): start track = %d, last track = %d.\n", track, end); + DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); + plat_cdrom_close(); - if ((track < 1) || (track > end)) + if ((track < 1) || (track == 0xaa) || (track > (toc.LastTrack))) return 0; - pos = toc.FirstTrack + 150; - - FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); + start->min = toc.TrackData[track - 1].Address[1]; + start->sec = toc.TrackData[track - 1].Address[2]; + start->fr = toc.TrackData[track - 1].Address[3]; *track_num = toc.TrackData[track - 1].TrackNumber; *attr = toc.TrackData[track - 1].Control; @@ -140,136 +122,100 @@ plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, return 1; } -uint32_t -plat_get_sector_size(void) +/* TODO: See if track start is adjusted by 150 or not. */ +int +plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - DISK_GEOMETRY dgCDROM; - DWORD size; + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + long size = 0; - if (plat_cdrom_open()) - return 0; - DeviceIoControl(hIOCTL, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(DISK_GEOMETRY), &size, NULL); - plat_cdrom_exit(); + insub.Format = IOCTL_CDROM_CURRENT_POSITION; - if (dgCDROM.MediaType != 11) // Removable Media Check + DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); + plat_cdrom_close(); + + if (sub.CurrentPosition.TrackNumber < 1) return 0; - return dgCDROM.BytesPerSector; + *track = sub.CurrentPosition.TrackNumber; + *attr = sub.CurrentPosition.Control; + *index = sub.CurrentPosition.IndexNumber; + + rel_pos->min = sub.CurrentPosition.TrackRelativeAddress[1]; + rel_pos->sec = sub.CurrentPosition.TrackRelativeAddress[2]; + rel_pos->fr = sub.CurrentPosition.TrackRelativeAddress[3]; + abs_pos->min = sub.CurrentPosition.AbsoluteAddress[1]; + abs_pos->sec = sub.CurrentPosition.AbsoluteAddress[2]; + abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3]; + + return 1; +} + +int +plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +{ + return COOKED_SECTOR_SIZE; } int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) { - int ret; LARGE_INTEGER pos; - RAW_READ_INFO in; - DWORD byteCount; - pclog("plat_cdrom_read_sector(): raw? = %d, sector = %02x.\n", raw, sector); + BOOL status; + long size = 0; - if (raw) { - in.TrackMode = CDDA; - in.SectorCount = 1; - in.DiskOffset.QuadPart = sector * RAW_SECTOR_SIZE; - if (plat_cdrom_open()) - return 0; - ret = DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(RAW_READ_INFO), buffer, RAW_SECTOR_SIZE, &byteCount, NULL); - plat_cdrom_exit(); - return ret; - } else { - pos.QuadPart = sector * COOKED_SECTOR_SIZE; - if (plat_cdrom_open()) - return 0; - SetFilePointer(hIOCTL, pos.LowPart, &pos.HighPart, FILE_BEGIN); - ret = ReadFile(hIOCTL, buffer, COOKED_SECTOR_SIZE, &byteCount, NULL); - plat_cdrom_exit(); - pclog("plat_cdrom_read_sector(): ret = %x.\n", !ret); - return !ret; - } - return 0; -} + int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; -uint32_t -plat_cdrom_get_capacity(void) -{ - DWORD size; - int c; - DISK_GEOMETRY dgCDROM; - uint32_t totals; + if (!raw) { + pclog("Cooked.\n"); + // Cooked + int success = 0; + DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + if (newPos != 0xFFFFFFFF) + success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); + status = (success != 0); + } else { + pclog("Raw.\n"); + // Raw + RAW_READ_INFO in; + in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), + buffer, buflen, (LPDWORD)&size, NULL); + } - if (plat_cdrom_open()) - return 0; - DeviceIoControl(hIOCTL, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(DISK_GEOMETRY), &size, NULL); - plat_cdrom_exit(); - - totals = dgCDROM.SectorsPerTrack * dgCDROM.TracksPerCylinder * dgCDROM.Cylinders.QuadPart; - - pclog("Total = %08x.\n", totals); - return totals; -} - -int -plat_cdrom_load(void) -{ - int ret; - DWORD size; - - if (plat_cdrom_open()) - return 0; - DeviceIoControl(hIOCTL, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &size, NULL); - plat_cdrom_exit(); - return 1; -} - -int -plat_cdrom_eject(void) -{ - int ret; - DWORD size; - - if (plat_cdrom_open()) - return 0; - ret = DeviceIoControl(hIOCTL, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &size, NULL); - plat_cdrom_exit(); - return ret; -} - -void -plat_cdrom_exit(void) -{ - if (hIOCTL) { - CloseHandle(hIOCTL); - hIOCTL = NULL; - } + plat_cdrom_close(); + pclog("ReadSector status=%d, sector=%d, size=%d.\n", status, sector, size); + return (size == buflen) && (status > 0); } void plat_cdrom_close(void) { - plat_cdrom_exit(); + if (handle != NULL) { + CloseHandle(handle); + handle = NULL; + } +} + +static int +plat_cdrom_load(char *path, int letter) +{ + plat_cdrom_close(); + strcpy(ioctl_path, "\\\\.\\"); + strcat(ioctl_path, path); + + /* Data track (shouldn't there be a lead in track?). */ + handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + pclog("handle=%p, error=%x, drive=%s.\n", handle, GetLastError(), ioctl_path); + return (handle != INVALID_HANDLE_VALUE); } int -plat_cdrom_reset(void) +plat_cdrom_open(char *path, int letter) { - CDROM_TOC ltoc; - DWORD size; - - if (plat_cdrom_open()) - return 0; - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - plat_cdrom_exit(); - - toc = ltoc; - return 1; -} - -int -plat_cdrom_open(void) -{ - plat_cdrom_exit(); - hIOCTL = CreateFile((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hIOCTL == NULL) - return 1; - - return 0; + return plat_cdrom_load(path, letter); } From 9af55412db2e013f91117c15c9ecff371c76a4d7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 18 May 2024 22:37:49 +0200 Subject: [PATCH 522/690] Make the CD/DVD-ROM passthrough actually work (WIP) Still WIP, eject/reload in the qt side is a bit broken. --- src/cdrom/cdrom.c | 13 ++++--- src/cdrom/cdrom_ioctl.c | 10 ++++-- src/include/86box/cdrom.h | 4 +-- src/include/86box/plat_cdrom.h | 2 +- src/qt/qt_mediamenu.cpp | 23 ++++++------ src/qt/win_cdrom_ioctl.c | 66 +++++++++++++++++++++++++--------- 6 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 06494e4a9..94d47ed06 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1973,7 +1973,7 @@ cdrom_hard_reset(void) cdrom_image_open(dev, dev->image_path); } else if (dev->host_drive == 201) - cdrom_ioctl_open(dev, dev->image_path, dev->letter); + cdrom_ioctl_open(dev, dev->drive); } } @@ -2028,6 +2028,8 @@ cdrom_eject(uint8_t id) if (dev->host_drive == 200) strcpy(dev->prev_image_path, dev->image_path); + else if (dev->host_drive == 201) + cdrom_ioctl_eject(); dev->prev_host_drive = dev->host_drive + (dev->host ? 1 : 0); dev->host_drive = 0; @@ -2049,7 +2051,7 @@ cdrom_reload(uint8_t id) { cdrom_t *dev = &cdrom[id]; - if ((dev->host_drive == dev->prev_host_drive) || (dev->prev_host_drive == 0) || (dev->host_drive != 0)) { + if (!dev->host && ((dev->host_drive == dev->prev_host_drive) || (dev->prev_host_drive == 0) || (dev->host_drive != 0))) { /* Switch from empty to empty. Do nothing. */ return; } @@ -2061,7 +2063,8 @@ cdrom_reload(uint8_t id) if (dev->prev_host_drive >= 200) { /* Reload a previous image. */ - strcpy(dev->image_path, dev->prev_image_path); + if (dev->prev_host_drive == 200) + strcpy(dev->image_path, dev->prev_image_path); #ifdef _WIN32 if (dev->prev_host_drive == 200) { @@ -2076,13 +2079,13 @@ cdrom_reload(uint8_t id) #endif if (dev->prev_host_drive > 200) - cdrom_ioctl_open(dev, dev->image_path, dev->letter); + cdrom_ioctl_open(dev, dev->drive); else cdrom_image_open(dev, dev->image_path); cdrom_insert(id); - if ((strlen(dev->image_path) == 0) && !dev->letter) + if ((strlen(dev->image_path) == 0) && !dev->drive) dev->host_drive = 0; else dev->host_drive = 200 + (dev->host ? 1 : 0); diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index 861c46eac..8f5c5f099 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -208,11 +208,17 @@ cdrom_ioctl_open_abort(cdrom_t *dev) return 1; } +void +cdrom_ioctl_eject(void) +{ + plat_cdrom_eject(); +} + int -cdrom_ioctl_open(cdrom_t *dev, char *path, int letter) +cdrom_ioctl_open(cdrom_t *dev, int drive) { /* Open the image. */ - int i = plat_cdrom_open(path, letter); + int i = plat_cdrom_set_drive(drive); if (!i) return cdrom_ioctl_open_abort(dev); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index de72974d1..ff0c77930 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -247,7 +247,7 @@ typedef struct cdrom { int audio_muted_soft; int sony_msf; int host; - int letter; + int drive; const cdrom_ops_t *ops; @@ -311,7 +311,7 @@ extern void cdrom_image_reset(cdrom_t *dev); extern void cdrom_ioctl_eject(void); extern void cdrom_ioctl_load(void); -extern int cdrom_ioctl_open(cdrom_t *dev, char *path, int letter); +extern int cdrom_ioctl_open(cdrom_t *dev, int drive); extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index 38246bd07..93f9befe5 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -57,7 +57,7 @@ extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *tra extern int plat_cdrom_get_sector_size(uint32_t sector); extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); extern void plat_cdrom_close(void); -extern int plat_cdrom_open(char *path, int letter); +extern int plat_cdrom_set_drive(int drive); #ifdef __cplusplus } diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index e6d52a823..8405156fb 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -146,8 +146,8 @@ MediaMenu::refresh(QMenu *parentMenu) cdromMutePos = menu->children().count(); menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); - menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdrom[i].host = 0; cdrom[i].letter = 0; cdromMount(i, 0); })->setCheckable(false); - menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdrom[i].host = 0; cdrom[i].letter = 0; cdromMount(i, 1); })->setCheckable(false); + menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdrom[i].host = 0; cdrom[i].drive = 0; cdromMount(i, 0); })->setCheckable(false); + menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdrom[i].host = 0; cdrom[i].drive = 0; cdromMount(i, 1); })->setCheckable(false); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cdromImageHistoryPos[slot] = menu->children().count(); @@ -160,7 +160,7 @@ MediaMenu::refresh(QMenu *parentMenu) for (auto &letter : driveLetters) { auto drive = QString::asprintf("%c:\\", letter).toUtf8().constData(); if (GetDriveType(drive) == DRIVE_CDROM) { - menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdrom[i].host = 1; cdrom[i].letter = letter; cdromMount(i, 0); })->setCheckable(false); + menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdrom[i].host = 1; cdrom[i].drive = letter; cdromMount(i, 0); })->setCheckable(false); } } menu->addSeparator(); @@ -487,22 +487,22 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); #ifdef _WIN32 - if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) + if (!cdrom[i].host && (fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) fn.data()[strlen(fn.data()) - 1] = '\\'; #else if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) fn.data()[strlen(fn.data()) - 1] = '/'; #endif if (cdrom[i].host) - cdrom_ioctl_open(&(cdrom[i]), fn.data(), cdrom[i].letter); + cdrom_ioctl_open(&(cdrom[i]), cdrom[i].drive); else cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ if (cdrom[i].insert) cdrom[i].insert(cdrom[i].priv); - cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0 && !cdrom[i].letter) ? 0 : (200 + (cdrom[i].host ? 1 : 0)); + cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0 && !cdrom[i].drive) ? 0 : (200 + (cdrom[i].host ? 1 : 0)); - pclog("HostDrive=%d, letter=%d.\n", cdrom[i].host_drive, cdrom[i].letter); + pclog("HostDrive=%d, drive=%d.\n", cdrom[i].host_drive, cdrom[i].drive); if (cdrom[i].host_drive >= 200) { ui_sb_update_icon_state(SB_CDROM | i, 0); } else { @@ -524,7 +524,7 @@ MediaMenu::cdromMount(int i, int dir) pclog("IsHost?=%d.\n", cdrom[i].host); if (cdrom[i].host) { - filename = QString(cdrom[i].letter); + filename = QString(cdrom[i].drive); } else { if (dir) { filename = QFileDialog::getExistingDirectory( @@ -536,10 +536,11 @@ MediaMenu::cdromMount(int i, int dir) QString(), tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } + } - if (filename.isEmpty()) { - return; - } + if (filename.isEmpty()) { + pclog("File is empty.\n"); + return; } cdromMount(i, filename); diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 1ba381692..9f02e8d27 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -38,7 +38,22 @@ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) static HANDLE handle; -static char ioctl_path[8]; +static WCHAR ioctl_path[256]; + +static int +plat_cdrom_open(void) +{ + plat_cdrom_close(); + + handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + pclog("handle=%p, error=%x.\n", handle, GetLastError()); + if (handle != INVALID_HANDLE_VALUE) { + long size; + DeviceIoControl(handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + return 1; + } + return 0; +} int plat_cdrom_is_track_audio(uint32_t sector) @@ -49,6 +64,7 @@ plat_cdrom_is_track_audio(uint32_t sector) int control = 0; uint32_t track_addr = 0; + plat_cdrom_open(); DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); plat_cdrom_close(); @@ -71,6 +87,7 @@ plat_cdrom_get_last_block(void) long size = 0; uint32_t address = 0; + plat_cdrom_open(); DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); plat_cdrom_close(); @@ -79,7 +96,7 @@ plat_cdrom_get_last_block(void) if (address > lb) lb = address; } - pclog("LBCapacity=%x.\n", lb); + pclog("LBCapacity=%d.\n", lb); return lb; } @@ -89,6 +106,7 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) CDROM_TOC toc; long size = 0; + plat_cdrom_open(); DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); plat_cdrom_close(); @@ -106,6 +124,7 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF CDROM_TOC toc; long size = 0; + plat_cdrom_open(); DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); plat_cdrom_close(); @@ -132,6 +151,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, insub.Format = IOCTL_CDROM_CURRENT_POSITION; + plat_cdrom_open(); DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); plat_cdrom_close(); @@ -155,7 +175,15 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, int plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) { - return COOKED_SECTOR_SIZE; + long size; + DISK_GEOMETRY dgCDROM; + + plat_cdrom_open(); + DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); + plat_cdrom_close(); + + pclog("BytesPerSector=%d.\n", dgCDROM.BytesPerSector); + return dgCDROM.BytesPerSector; } int @@ -167,6 +195,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + plat_cdrom_open(); if (!raw) { pclog("Cooked.\n"); // Cooked @@ -186,12 +215,22 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), buffer, buflen, (LPDWORD)&size, NULL); } - plat_cdrom_close(); pclog("ReadSector status=%d, sector=%d, size=%d.\n", status, sector, size); return (size == buflen) && (status > 0); } +void +plat_cdrom_eject(void) +{ + long size; + int ret; + + plat_cdrom_open(); + DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + plat_cdrom_close(); +} + void plat_cdrom_close(void) { @@ -201,21 +240,14 @@ plat_cdrom_close(void) } } -static int -plat_cdrom_load(char *path, int letter) +int +plat_cdrom_set_drive(int drive) { plat_cdrom_close(); - strcpy(ioctl_path, "\\\\.\\"); - strcat(ioctl_path, path); - /* Data track (shouldn't there be a lead in track?). */ - handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - pclog("handle=%p, error=%x, drive=%s.\n", handle, GetLastError(), ioctl_path); - return (handle != INVALID_HANDLE_VALUE); -} + wsprintf(ioctl_path, L"\\\\.\\%c:", drive); + pclog("Path is %s\n", ioctl_path); -int -plat_cdrom_open(char *path, int letter) -{ - return plat_cdrom_load(path, letter); + plat_cdrom_open(); + return 1; } From 641da43f1527b90b1cc08dee57d245d2f5af5ffc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 May 2024 21:17:57 +0200 Subject: [PATCH 523/690] IOCTL and CD-ROM changes. --- src/cdrom/cdrom.c | 20 +- src/cdrom/cdrom_image.c | 7 + src/cdrom/cdrom_ioctl.c | 135 ++++++++----- src/include/86box/cdrom.h | 16 +- src/include/86box/plat_cdrom.h | 21 +- src/qt/CMakeLists.txt | 4 + src/qt/qt_machinestatus.cpp | 2 +- src/qt/qt_mediahistorymanager.cpp | 2 +- src/qt/qt_mediamenu.cpp | 116 ++++++----- src/qt/qt_mediamenu.hpp | 2 +- src/qt/qt_platform.cpp | 13 +- src/qt/win_cdrom_ioctl.c | 309 ++++++++++++++++++++---------- src/scsi/scsi_cdrom.c | 8 +- 13 files changed, 424 insertions(+), 231 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 94d47ed06..0da199b52 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1971,9 +1971,11 @@ cdrom_hard_reset(void) dev->image_path[strlen(dev->image_path) - 1] = '/'; #endif - cdrom_image_open(dev, dev->image_path); - } else if (dev->host_drive == 201) - cdrom_ioctl_open(dev, dev->drive); + if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) + cdrom_ioctl_open(dev, dev->image_path); + else + cdrom_image_open(dev, dev->image_path); + } } } @@ -2026,10 +2028,8 @@ cdrom_eject(uint8_t id) return; } - if (dev->host_drive == 200) + if (dev->host_drive >= 200) strcpy(dev->prev_image_path, dev->image_path); - else if (dev->host_drive == 201) - cdrom_ioctl_eject(); dev->prev_host_drive = dev->host_drive + (dev->host ? 1 : 0); dev->host_drive = 0; @@ -2078,17 +2078,17 @@ cdrom_reload(uint8_t id) } #endif - if (dev->prev_host_drive > 200) - cdrom_ioctl_open(dev, dev->drive); + if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) + cdrom_ioctl_open(dev, dev->image_path); else cdrom_image_open(dev, dev->image_path); cdrom_insert(id); - if ((strlen(dev->image_path) == 0) && !dev->drive) + if (strlen(dev->image_path) == 0) dev->host_drive = 0; else - dev->host_drive = 200 + (dev->host ? 1 : 0); + dev->host_drive = 200; } plat_cdrom_ui_update(id, 1); diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 0c7ee03a0..dff3a9105 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -217,6 +217,12 @@ image_track_type(cdrom_t *dev, uint32_t lba) return 0; } +static int +image_ext_medium_changed(cdrom_t *dev) +{ + return 0; +} + static void image_exit(cdrom_t *dev) { @@ -241,6 +247,7 @@ static const cdrom_ops_t cdrom_image_ops = { image_sector_size, image_read_sector, image_track_type, + image_ext_medium_changed, image_exit }; diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index 8f5c5f099..dae9abaad 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -56,7 +56,7 @@ cdrom_ioctl_log(const char *fmt, ...) #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) static void -cdrom_ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) +ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) { TMSF tmsf; @@ -64,7 +64,7 @@ cdrom_ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) } static void -cdrom_ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti) +ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti) { TMSF tmsf; @@ -76,13 +76,30 @@ cdrom_ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_ } static void -cdrom_ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) +ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) { TMSF rel_pos; TMSF abs_pos; - plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index, - &rel_pos, &abs_pos); + if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) { + uint32_t dat = lba + 150; + abs_pos.fr = dat % 75; + dat /= 75; + abs_pos.sec = dat % 60; + dat /= 60; + abs_pos.min = dat; + + dat = lba - plat_cdrom_get_track_start(lba, &subc->attr, &subc->track); + rel_pos.fr = dat % 75; + dat /= 75; + rel_pos.sec = dat % 60; + dat /= 60; + rel_pos.min = dat; + + subc->index = 1; + } else + plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index, + &rel_pos, &abs_pos); subc->abs_m = abs_pos.min; subc->abs_s = abs_pos.sec; @@ -91,6 +108,9 @@ cdrom_ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *sub subc->rel_m = rel_pos.min; subc->rel_s = rel_pos.sec; subc->rel_f = rel_pos.fr; + + cdrom_ioctl_log("ioctl_get_subchannel(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); } static int @@ -99,20 +119,16 @@ cdrom_ioctl_get_capacity(UNUSED(cdrom_t *dev)) int ret; ret = plat_cdrom_get_last_block(); - pclog("GetCapacity=%x.\n", ret); + cdrom_ioctl_log("GetCapacity=%x.\n", ret); return ret; } static int -cdrom_ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) +ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { - uint8_t attr; - TMSF tmsf; int m; int s; int f; - int number; - int track; if (dev->cd_status == CD_STATUS_DATA_ONLY) return 0; @@ -129,27 +145,30 @@ cdrom_ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) } static int -cdrom_ioctl_is_track_pre(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) +ioctl_is_track_pre(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) { return 0; } static int -cdrom_ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba) +ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba) { - pclog("LBA=%x.\n", lba); + cdrom_ioctl_log("LBA=%x.\n", lba); return plat_cdrom_get_sector_size(lba); } static int -cdrom_ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba) +ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba) { switch (type) { case CD_READ_DATA: + cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n"); return plat_cdrom_read_sector(b, 0, lba); case CD_READ_AUDIO: + cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n"); return plat_cdrom_read_sector(b, 1, lba); case CD_READ_RAW: + cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); return plat_cdrom_read_sector(b, 1, lba); default: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); @@ -159,16 +178,34 @@ cdrom_ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba } static int -cdrom_ioctl_track_type(cdrom_t *dev, uint32_t lba) +ioctl_track_type(cdrom_t *dev, uint32_t lba) { - if (cdrom_ioctl_is_track_audio(dev, lba, 0)) - return CD_TRACK_AUDIO; + int ret = 0; - return 0; + if (ioctl_is_track_audio(dev, lba, 0)) + ret = CD_TRACK_AUDIO; + + cdrom_ioctl_log("cdrom_ioctl_track_type(): %i\n", ret); + + return ret; +} + +static int +ioctl_ext_medium_changed(cdrom_t *dev) +{ + const int ret = plat_cdrom_ext_medium_changed(); + + if (ret == 1) { + dev->cd_status = CD_STATUS_STOPPED; + dev->cdrom_capacity = cdrom_ioctl_get_capacity(dev); + } else if (ret == -1) + dev->cd_status = CD_STATUS_EMPTY; + + return ret; } static void -cdrom_ioctl_exit(cdrom_t *dev) +ioctl_exit(cdrom_t *dev) { cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path); dev->cd_status = CD_STATUS_EMPTY; @@ -179,25 +216,17 @@ cdrom_ioctl_exit(cdrom_t *dev) } static const cdrom_ops_t cdrom_ioctl_ops = { - cdrom_ioctl_get_tracks, - cdrom_ioctl_get_track_info, - cdrom_ioctl_get_subchannel, - cdrom_ioctl_is_track_pre, - cdrom_ioctl_sector_size, - cdrom_ioctl_read_sector, - cdrom_ioctl_track_type, - cdrom_ioctl_exit + ioctl_get_tracks, + ioctl_get_track_info, + ioctl_get_subchannel, + ioctl_is_track_pre, + ioctl_sector_size, + ioctl_read_sector, + ioctl_track_type, + ioctl_ext_medium_changed, + ioctl_exit }; -void -cdrom_ioctl_close(cdrom_t *dev) -{ - cdrom_ioctl_log("CDROM: ioctl_close(%s)\n", dev->image_path); - - if (dev && dev->ops && dev->ops->exit) - dev->ops->exit(dev); -} - static int cdrom_ioctl_open_abort(cdrom_t *dev) { @@ -208,17 +237,21 @@ cdrom_ioctl_open_abort(cdrom_t *dev) return 1; } -void -cdrom_ioctl_eject(void) -{ - plat_cdrom_eject(); -} - int -cdrom_ioctl_open(cdrom_t *dev, int drive) +cdrom_ioctl_open(cdrom_t *dev, const char *drv) { + const char *actual_drv = &(drv[8]); + + /* Make sure to not STRCPY if the two are pointing + at the same place. */ + if (drv != dev->image_path) + strcpy(dev->image_path, drv); + /* Open the image. */ - int i = plat_cdrom_set_drive(drive); + if (strstr(drv, "ioctl://") != drv) + return cdrom_ioctl_open_abort(dev); + cdrom_ioctl_log("actual_drv = %s\n", actual_drv); + int i = plat_cdrom_set_drive(actual_drv); if (!i) return cdrom_ioctl_open_abort(dev); @@ -228,7 +261,8 @@ cdrom_ioctl_open(cdrom_t *dev, int drive) dev->seek_pos = 0; dev->cd_buflen = 0; dev->cdrom_capacity = cdrom_ioctl_get_capacity(dev); - pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); + cdrom_ioctl_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", + dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); /* Attach this handler to the drive. */ dev->ops = &cdrom_ioctl_ops; @@ -236,3 +270,12 @@ cdrom_ioctl_open(cdrom_t *dev, int drive) return 0; } +void +cdrom_ioctl_close(cdrom_t *dev) +{ + cdrom_ioctl_log("CDROM: ioctl_close(%s)\n", dev->image_path); + + if (dev && dev->ops && dev->ops->exit) + dev->ops->exit(dev); +} + diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index ff0c77930..33f900806 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -199,10 +199,11 @@ typedef struct cdrom_ops_t { void (*get_tracks)(struct cdrom *dev, int *first, int *last); void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); - int (*is_track_pre)(struct cdrom *dev, uint32_t lba); - int (*sector_size)(struct cdrom *dev, uint32_t lba); - int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba); - int (*track_type)(struct cdrom *dev, uint32_t lba); + int (*is_track_pre)(struct cdrom *dev, uint32_t lba); + int (*sector_size)(struct cdrom *dev, uint32_t lba); + int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba); + int (*track_type)(struct cdrom *dev, uint32_t lba); + int (*ext_medium_changed)(struct cdrom *dev); void (*exit)(struct cdrom *dev); } cdrom_ops_t; @@ -247,7 +248,6 @@ typedef struct cdrom { int audio_muted_soft; int sony_msf; int host; - int drive; const cdrom_ops_t *ops; @@ -307,11 +307,9 @@ extern void cdrom_reload(uint8_t id); extern int cdrom_image_open(cdrom_t *dev, const char *fn); extern void cdrom_image_close(cdrom_t *dev); -extern void cdrom_image_reset(cdrom_t *dev); -extern void cdrom_ioctl_eject(void); -extern void cdrom_ioctl_load(void); -extern int cdrom_ioctl_open(cdrom_t *dev, int drive); +extern int cdrom_ioctl_open(cdrom_t *dev, const char *drv); +extern void cdrom_ioctl_close(cdrom_t *dev); extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index 93f9befe5..a21dd357f 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -49,15 +49,18 @@ typedef struct SMSF { uint8_t fr; } TMSF; -extern int plat_cdrom_is_track_audio(uint32_t sector); -extern int plat_cdrom_get_last_block(void); -extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); -extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); -extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); -extern int plat_cdrom_get_sector_size(uint32_t sector); -extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); -extern void plat_cdrom_close(void); -extern int plat_cdrom_set_drive(int drive); +extern int plat_cdrom_is_track_audio(uint32_t sector); +extern uint32_t plat_cdrom_get_last_block(void); +extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); +extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); +extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); +extern int plat_cdrom_get_sector_size(uint32_t sector); +extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); +extern void plat_cdrom_eject(void); +extern void plat_cdrom_close(void); +extern int plat_cdrom_set_drive(const char *drv); +extern int plat_cdrom_ext_medium_changed(void); +extern uint32_t plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track); #ifdef __cplusplus } diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 422989a44..ebaa84be1 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -225,6 +225,10 @@ else() target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) endif() +if(WIN32) + target_sources(plat PRIVATE win_cdrom_ioctl.c) +endif() + if (APPLE) target_sources(ui PRIVATE macos_event_filter.mm) if(MOLTENVK) diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index a36efd2cd..88375354b 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -533,7 +533,7 @@ MachineStatus::refresh(QStatusBar *sbar) iterateCDROM([this, sbar](int i) { d->cdrom[i].label = std::make_unique(); - d->cdrom[i].setEmpty(((cdrom[i].host_drive != 200) && (cdrom[i].host_drive != 201)) || QString(cdrom[i].image_path).isEmpty()); + d->cdrom[i].setEmpty((cdrom[i].host_drive != 200) || QString(cdrom[i].image_path).isEmpty()); d->cdrom[i].setActive(false); d->cdrom[i].refresh(); connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 9d003f464..672ccfa8d 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -306,7 +306,7 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) } // For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info; - if (!absolute_path.exists()) { + if ((file_info.filePath().left(8) != "ioctl://") && !absolute_path.exists()) { qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath())); checked_path = ""; } diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 8405156fb..1a2b0e831 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -146,8 +146,8 @@ MediaMenu::refresh(QMenu *parentMenu) cdromMutePos = menu->children().count(); menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); - menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdrom[i].host = 0; cdrom[i].drive = 0; cdromMount(i, 0); })->setCheckable(false); - menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdrom[i].host = 0; cdrom[i].drive = 0; cdromMount(i, 1); })->setCheckable(false); + menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false); + menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cdromImageHistoryPos[slot] = menu->children().count(); @@ -159,12 +159,11 @@ MediaMenu::refresh(QMenu *parentMenu) it's a CDROM */ for (auto &letter : driveLetters) { auto drive = QString::asprintf("%c:\\", letter).toUtf8().constData(); - if (GetDriveType(drive) == DRIVE_CDROM) { - menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdrom[i].host = 1; cdrom[i].drive = letter; cdromMount(i, 0); })->setCheckable(false); - } + if (GetDriveType(drive) == DRIVE_CDROM) + menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DriveCDIcon), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdromMount(i, 2, QString::asprintf(R"(\\.\%c:)", letter).toUtf8().constData()); })->setCheckable(false); } menu->addSeparator(); -#endif // _WIN32 +#endif // Q_OS_WINDOWS cdromImagePos = menu->children().count(); cdromDirPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { cdromEject(i); })->setCheckable(false); @@ -486,30 +485,27 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); -#ifdef _WIN32 - if (!cdrom[i].host && (fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) +#ifdef Q_OS_WINDOWS + if (!cdrom[i].host && (fn.data() != nullptr) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) fn.data()[strlen(fn.data()) - 1] = '\\'; #else if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) fn.data()[strlen(fn.data()) - 1] = '/'; #endif - if (cdrom[i].host) - cdrom_ioctl_open(&(cdrom[i]), cdrom[i].drive); + if ((fn.data() != nullptr) && fn.contains("ioctl://")) + cdrom_ioctl_open(&(cdrom[i]), fn.data()); else cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ if (cdrom[i].insert) cdrom[i].insert(cdrom[i].priv); - cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0 && !cdrom[i].drive) ? 0 : (200 + (cdrom[i].host ? 1 : 0)); + cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0) ? 0 : 200; - pclog("HostDrive=%d, drive=%d.\n", cdrom[i].host_drive, cdrom[i].drive); - if (cdrom[i].host_drive >= 200) { + if (cdrom[i].host_drive >= 200) ui_sb_update_icon_state(SB_CDROM | i, 0); - } else { + else ui_sb_update_icon_state(SB_CDROM | i, 1); - } - if (!cdrom[i].host) - mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].prev_image_path, cdrom[i].image_path); + mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].prev_image_path, cdrom[i].image_path); cdromUpdateMenu(i); ui_sb_update_tip(SB_CDROM | i); @@ -517,31 +513,23 @@ MediaMenu::cdromMount(int i, const QString &filename) } void -MediaMenu::cdromMount(int i, int dir) +MediaMenu::cdromMount(int i, int dir, const QString &arg) { QString filename; QFileInfo fi(cdrom[i].image_path); - pclog("IsHost?=%d.\n", cdrom[i].host); - if (cdrom[i].host) { - filename = QString(cdrom[i].drive); - } else { - if (dir) { - filename = QFileDialog::getExistingDirectory( - parentWidget); - } else { - filename = QFileDialog::getOpenFileName( - parentWidget, - QString(), - QString(), - tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - } + if (dir > 1) + filename = QString::asprintf(R"(ioctl://%s)", arg.toStdString().c_str()); + else if (dir == 1) + filename = QFileDialog::getExistingDirectory(parentWidget); + else { + filename = QFileDialog::getOpenFileName(parentWidget, QString(), + QString(), + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } - if (filename.isEmpty()) { - pclog("File is empty.\n"); + if (filename.isEmpty()) return; - } cdromMount(i, filename); } @@ -589,6 +577,9 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) QObjectList children; QFileInfo fi; QIcon menu_icon; + const auto fn = mhm.getImageForSlot(index, slot, type); + + QString menu_item_name; switch (type) { case ui::MediaType::Optical: @@ -597,8 +588,18 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = cdromMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[cdromImageHistoryPos[slot]]); - fi.setFile(mhm.getImageForSlot(index, slot, type)); - menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + if (fn.left(8) == "ioctl://") { + menu_icon = QApplication::style()->standardIcon(QStyle::SP_DriveCDIcon); +#ifdef Q_OS_WINDOWS + menu_item_name = tr("Host CD/DVD Drive (%1)").arg(fn.right(2)).toUtf8().constData(); +#else + menu_item_name = tr("Host CD/DVD Drive (%1)").arg(fn.right(name.length() - 8)); +#endif + } else { + fi.setFile(fn); + menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + menu_item_name = fn.isEmpty() ? tr("previous image").toUtf8().constData() : fn.toUtf8().constData(); + } imageHistoryUpdatePos->setIcon(menu_icon); break; case ui::MediaType::Floppy: @@ -607,17 +608,20 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = floppyMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); - fi.setFile(mhm.getImageForSlot(index, slot, type)); + fi.setFile(fn); + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); break; default: - pclog("History not yet implemented for media type %s\n", qPrintable(mhm.mediaTypeToString(type))); + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); return; } - const QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData())); - imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty()); - imageHistoryUpdatePos->setVisible(fi.exists()); + + if (fn.left(8) == "ioctl://") + imageHistoryUpdatePos->setVisible(true); + else + imageHistoryUpdatePos->setVisible(!fn.isEmpty() && fi.exists()); } void @@ -630,8 +634,9 @@ MediaMenu::clearImageHistory() void MediaMenu::cdromUpdateMenu(int i) { - QString name = cdrom[i].image_path; - QFileInfo fi(cdrom[i].image_path); + QString name = cdrom[i].image_path; + QString name2; + QIcon menu_icon; if (!cdromMenus.contains(i)) return; @@ -644,14 +649,27 @@ MediaMenu::cdromUpdateMenu(int i) auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); - const QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); - const auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + QString menu_item_name; + if (name.left(8) == "ioctl://") { +#ifdef Q_OS_WINDOWS + menu_item_name = tr("Host CD/DVD Drive (%1)").arg(name.right(2)).toUtf8().constData(); +#else + menu_item_name = tr("Host CD/DVD Drive (%1)").arg(name.right(name.length() - 8)); +#endif + name2 = menu_item_name; + menu_icon = QApplication::style()->standardIcon(QStyle::SP_DriveCDIcon); + } else { + QFileInfo fi(cdrom[i].image_path); + + menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : name.toUtf8().constData(); + name2 = name; + menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + } imageMenu->setIcon(menu_icon); imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData())); - for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) updateImageHistory(i, slot, ui::MediaType::Optical); - } QString busName = tr("Unknown Bus"); switch (cdrom[i].bus_type) { @@ -669,7 +687,7 @@ MediaMenu::cdromUpdateMenu(int i) } // menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); - menu->setTitle(QString::asprintf(tr("CD-ROM %i (%s): %s").toUtf8().constData(), i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toUtf8().data() : name.toUtf8().data())); + menu->setTitle(QString::asprintf(tr("CD-ROM %i (%s): %s").toUtf8().constData(), i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toUtf8().data() : name2.toUtf8().data())); } void diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 2e448086f..725ce92b3 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -41,7 +41,7 @@ public: void floppyUpdateMenu(int i); void cdromMute(int i); - void cdromMount(int i, int dir); + void cdromMount(int i, int dir, const QString &arg); void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index e0b11ad7b..91826ed83 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -278,7 +278,7 @@ int path_abs(char *path) { #ifdef Q_OS_WINDOWS - if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/')) + if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/') || (strstr(path, "ioctl://") == path)) return 1; return 0; @@ -291,10 +291,13 @@ void path_normalize(char *path) { #ifdef Q_OS_WINDOWS - while (*path++ != 0) { - if (*path == '\\') - *path = '/'; - } + if (strstr(path, "ioctl://") != path) { + while (*path++ != 0) { + if (*path == '\\') + *path = '/'; + } + } else + path[8] = path[9] = path[11] = '\\'; #endif } diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 9f02e8d27..36838820a 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -21,11 +21,17 @@ #include #include #undef BITMAP +#include #include #include "ntddcdrm.h" #include "ntddscsi.h" -#include +#include #include +#include +#include +#include +#include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> @@ -37,8 +43,29 @@ of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static HANDLE handle; -static WCHAR ioctl_path[256]; +static int toc_valid = 0; +static CDROM_TOC cur_toc = { 0 }; +static HANDLE handle = NULL; +static WCHAR ioctl_path[256] = { 0 }; +static WCHAR old_ioctl_path[256] = { 0 }; + +#ifdef ENABLE_WIN_CDROM_IOCTL_LOG +int win_cdrom_ioctl_do_log = ENABLE_WIN_CDROM_IOCTL_LOG; + +void +win_cdrom_ioctl_log(const char *fmt, ...) +{ + va_list ap; + + if (win_cdrom_ioctl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define win_cdrom_ioctl_log(fmt, ...) +#endif static int plat_cdrom_open(void) @@ -46,7 +73,7 @@ plat_cdrom_open(void) plat_cdrom_close(); handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - pclog("handle=%p, error=%x.\n", handle, GetLastError()); + win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); if (handle != INVALID_HANDLE_VALUE) { long size; DeviceIoControl(handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); @@ -55,88 +82,166 @@ plat_cdrom_open(void) return 0; } -int -plat_cdrom_is_track_audio(uint32_t sector) +static void +plat_cdrom_read_toc(void) { - CDROM_TOC toc; - long size = 0; - int ret; - int control = 0; - uint32_t track_addr = 0; + long size = 0; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); - - for (int c = 0; toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); - if ((toc.TrackData[c].TrackNumber >= toc.FirstTrack) && (toc.TrackData[c].TrackNumber <= toc.LastTrack) && - (track_addr >= sector)) - control = toc.TrackData[c].Control; - break; + if (!toc_valid) { + toc_valid = 1; + plat_cdrom_open(); + DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cur_toc, sizeof(cur_toc), (LPDWORD)&size, NULL); + plat_cdrom_close(); } - ret = (control & 0x04) ? 0 : 1; - return ret; } int +plat_cdrom_is_track_audio(uint32_t sector) +{ + int control = 0; + uint32_t track_addr = 0; + uint32_t next_track_addr = 0; + + plat_cdrom_read_toc(); + + for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { + track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; + next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; + win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", + cur_toc.FirstTrack, cur_toc.LastTrack, + cur_toc.TrackData[c].TrackNumber, c, + cur_toc.TrackData[c].Control, track_addr, sector); + if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && + (sector >= track_addr) && (sector <= next_track_addr)) { + control = cur_toc.TrackData[c].Control; + break; + } + } + + const int ret = !(control & 0x04); + + win_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + +uint32_t +plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +{ + uint32_t track_addr = 0; + uint32_t next_track_addr = 0; + + plat_cdrom_read_toc(); + + for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { + track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; + next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; + win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", + cur_toc.FirstTrack, cur_toc.LastTrack, + cur_toc.TrackData[c].TrackNumber, c, + cur_toc.TrackData[c].Control, track_addr, sector); + if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && + (sector >= track_addr) && (sector <= next_track_addr)) { + *track = cur_toc.TrackData[c].TrackNumber; + *attr = cur_toc.TrackData[c].Control; + break; + } + } + + win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, track_addr); + + return track_addr; +} + +uint32_t plat_cdrom_get_last_block(void) { - CDROM_TOC toc; - int lb = 0; - long size = 0; - uint32_t address = 0; + uint32_t lb = 0; + uint32_t address = 0; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); + plat_cdrom_read_toc(); - for (int c = 0; c <= toc.LastTrack; c++) { - address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + for (int c = 0; c <= cur_toc.LastTrack; c++) { + address = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; if (address > lb) lb = address; } - pclog("LBCapacity=%d.\n", lb); + win_cdrom_ioctl_log("LBCapacity=%d\n", lb); return lb; } +int +plat_cdrom_ext_medium_changed(void) +{ + long size; + CDROM_TOC toc; + int ret = 0; + + plat_cdrom_open(); + int temp = DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, + NULL, 0, &toc, sizeof(toc), + (LPDWORD)&size, NULL); + plat_cdrom_close(); + + if (!temp) + /* There has been some kind of error - not a medium change, but a not ready + condition. */ + ret = -1; + else if (!toc_valid || (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0)) { + /* Changed to a different host drive - we already detect such medium changes. */ + toc_valid = 1; + cur_toc = toc; + if (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0) + memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); + } else if ((toc.TrackData[toc.LastTrack].Address[1] != + cur_toc.TrackData[cur_toc.LastTrack].Address[1]) || + (toc.TrackData[toc.LastTrack].Address[2] != + cur_toc.TrackData[cur_toc.LastTrack].Address[2]) || + (toc.TrackData[toc.LastTrack].Address[3] != + cur_toc.TrackData[cur_toc.LastTrack].Address[3])) + /* The TOC has changed. */ + ret = 1; + + win_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); + + return ret; +} + void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) { - CDROM_TOC toc; - long size = 0; - - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); + plat_cdrom_read_toc(); *st_track = 1; - *end = toc.LastTrack; - lead_out->min = toc.TrackData[toc.LastTrack].Address[1]; - lead_out->sec = toc.TrackData[toc.LastTrack].Address[2]; - lead_out->fr = toc.TrackData[toc.LastTrack].Address[3]; + *end = cur_toc.LastTrack; + lead_out->min = cur_toc.TrackData[cur_toc.LastTrack].Address[1]; + lead_out->sec = cur_toc.TrackData[cur_toc.LastTrack].Address[2]; + lead_out->fr = cur_toc.TrackData[cur_toc.LastTrack].Address[3]; + + win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", + *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); } /* This replaces both Info and EndInfo, they are specified by a variable. */ int plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - CDROM_TOC toc; - long size = 0; + plat_cdrom_read_toc(); - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); - - if ((track < 1) || (track == 0xaa) || (track > (toc.LastTrack))) + if ((track < 1) || (track == 0xaa) || (track > (cur_toc.LastTrack + 1))) { + win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); return 0; + } - start->min = toc.TrackData[track - 1].Address[1]; - start->sec = toc.TrackData[track - 1].Address[2]; - start->fr = toc.TrackData[track - 1].Address[3]; + start->min = cur_toc.TrackData[track - 1].Address[1]; + start->sec = cur_toc.TrackData[track - 1].Address[2]; + start->fr = cur_toc.TrackData[track - 1].Address[3]; - *track_num = toc.TrackData[track - 1].TrackNumber; - *attr = toc.TrackData[track - 1].Control; + *track_num = cur_toc.TrackData[track - 1].TrackNumber; + *attr = cur_toc.TrackData[track - 1].Control; + + win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", + track, start->min, start->sec, start->fr, *track_num, *attr); return 1; } @@ -145,14 +250,14 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF int plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - long size = 0; + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + long size = 0; insub.Format = IOCTL_CDROM_CURRENT_POSITION; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); + plat_cdrom_open(); + DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); plat_cdrom_close(); if (sub.CurrentPosition.TrackNumber < 1) @@ -162,12 +267,15 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, *attr = sub.CurrentPosition.Control; *index = sub.CurrentPosition.IndexNumber; - rel_pos->min = sub.CurrentPosition.TrackRelativeAddress[1]; - rel_pos->sec = sub.CurrentPosition.TrackRelativeAddress[2]; - rel_pos->fr = sub.CurrentPosition.TrackRelativeAddress[3]; - abs_pos->min = sub.CurrentPosition.AbsoluteAddress[1]; - abs_pos->sec = sub.CurrentPosition.AbsoluteAddress[2]; - abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3]; + rel_pos->min = sub.CurrentPosition.TrackRelativeAddress[1]; + rel_pos->sec = sub.CurrentPosition.TrackRelativeAddress[2]; + rel_pos->fr = sub.CurrentPosition.TrackRelativeAddress[3]; + abs_pos->min = sub.CurrentPosition.AbsoluteAddress[1]; + abs_pos->sec = sub.CurrentPosition.AbsoluteAddress[2]; + abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3]; + + win_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); return 1; } @@ -179,55 +287,55 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) DISK_GEOMETRY dgCDROM; plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); - plat_cdrom_close(); + DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); + plat_cdrom_close(); - pclog("BytesPerSector=%d.\n", dgCDROM.BytesPerSector); + win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector); return dgCDROM.BytesPerSector; } int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) { - LARGE_INTEGER pos; BOOL status; - long size = 0; + long size = 0; + int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + plat_cdrom_open(); - plat_cdrom_open(); - if (!raw) { - pclog("Cooked.\n"); - // Cooked - int success = 0; - DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); - if (newPos != 0xFFFFFFFF) + if (!raw) { + win_cdrom_ioctl_log("Cooked\n"); + /* Cooked */ + int success = 0; + DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + if (newPos != 0xFFFFFFFF) success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); - status = (success != 0); - } else { - pclog("Raw.\n"); - // Raw - RAW_READ_INFO in; - in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), - buffer, buflen, (LPDWORD)&size, NULL); - } + status = (success != 0); + } else { + win_cdrom_ioctl_log("Raw\n"); + /* Raw */ + RAW_READ_INFO in; + in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), + buffer, buflen, (LPDWORD)&size, NULL); + } plat_cdrom_close(); - pclog("ReadSector status=%d, sector=%d, size=%d.\n", status, sector, size); - return (size == buflen) && (status > 0); + win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%d.\n", status, sector, size); + + return (size == buflen) && (status > 0); } void plat_cdrom_eject(void) { - long size; - int ret; + long size; plat_cdrom_open(); DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + plat_cdrom_close(); } @@ -241,12 +349,17 @@ plat_cdrom_close(void) } int -plat_cdrom_set_drive(int drive) +plat_cdrom_set_drive(const char *drv) { plat_cdrom_close(); - wsprintf(ioctl_path, L"\\\\.\\%c:", drive); - pclog("Path is %s\n", ioctl_path); + memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); + memset(ioctl_path, 0x00, sizeof(ioctl_path)); + + wsprintf(ioctl_path, L"%S", drv); + win_cdrom_ioctl_log("Path is %S\n", ioctl_path); + + toc_valid = 0; plat_cdrom_open(); return 1; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 47ba0535e..12840f624 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1557,6 +1557,10 @@ static int scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) { int ready = 0; + int ext_medium_changed = 0; + + if (dev->drv && dev->drv->ops && dev->drv->ops->ext_medium_changed) + ext_medium_changed = dev->drv->ops->ext_medium_changed(dev->drv); if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", @@ -1590,10 +1594,10 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) goto skip_ready_check; } - if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) + if ((dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) || (ext_medium_changed == 1)) scsi_cdrom_insert((void *) dev); - ready = (dev->drv->cd_status != CD_STATUS_EMPTY); + ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1); skip_ready_check: /* If the drive is not ready, there is no reason to keep the From 0c9887b0ec9f4c0be68a0a1cffe9f64e3eae131e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 May 2024 21:24:04 +0200 Subject: [PATCH 524/690] AT KBC: Revert to old behavior always. --- src/device/kbc_at.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 74ade4cd3..dd18649de 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -406,7 +406,9 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ - if (dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) +#ifdef WRONG_CONDITION + if ((dev->channel > 0) || dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) +#endif kbc_do_irq(dev); dev->ob = temp; From 9dc92bc1d46129296ec5ec33bb719c0c428f2568 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 01:57:15 +0200 Subject: [PATCH 525/690] More IOCTL fixes - audio now works correctly. --- src/cdrom/cdrom_image.c | 3 ++ src/cdrom/cdrom_ioctl.c | 36 ++++++++-------- src/include/86box/plat_cdrom.h | 1 + src/qt/win_cdrom_ioctl.c | 75 +++++++++++++++++++++++++++------- 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index dff3a9105..be6779f9b 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -97,6 +97,9 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) subc->rel_m = rel_pos.min; subc->rel_s = rel_pos.sec; subc->rel_f = rel_pos.fr; + + cdrom_image_log("image_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); } static int diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index dae9abaad..c1bc6569e 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -82,19 +82,12 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) TMSF abs_pos; if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) { - uint32_t dat = lba + 150; - abs_pos.fr = dat % 75; - dat /= 75; - abs_pos.sec = dat % 60; - dat /= 60; - abs_pos.min = dat; + const uint32_t trk = plat_cdrom_get_track_start(lba, &subc->attr, &subc->track); - dat = lba - plat_cdrom_get_track_start(lba, &subc->attr, &subc->track); - rel_pos.fr = dat % 75; - dat /= 75; - rel_pos.sec = dat % 60; - dat /= 60; - rel_pos.min = dat; + FRAMES_TO_MSF(lba + 150, &abs_pos.min, &abs_pos.sec, &abs_pos.fr); + + /* Absolute position should be adjusted by 150, not the relative ones. */ + FRAMES_TO_MSF(lba - trk, &rel_pos.min, &rel_pos.sec, &rel_pos.fr); subc->index = 1; } else @@ -109,12 +102,12 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) subc->rel_s = rel_pos.sec; subc->rel_f = rel_pos.fr; - cdrom_ioctl_log("ioctl_get_subchannel(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + cdrom_ioctl_log("ioctl_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); } static int -cdrom_ioctl_get_capacity(UNUSED(cdrom_t *dev)) +ioctl_get_capacity(UNUSED(cdrom_t *dev)) { int ret; @@ -145,9 +138,9 @@ ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) } static int -ioctl_is_track_pre(UNUSED(cdrom_t *dev), UNUSED(uint32_t lba)) +ioctl_is_track_pre(UNUSED(cdrom_t *dev), uint32_t lba) { - return 0; + return plat_cdrom_is_track_pre(lba); } static int @@ -193,11 +186,16 @@ ioctl_track_type(cdrom_t *dev, uint32_t lba) static int ioctl_ext_medium_changed(cdrom_t *dev) { - const int ret = plat_cdrom_ext_medium_changed(); + int ret; + + if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) + ret = 0; + else + ret = plat_cdrom_ext_medium_changed(); if (ret == 1) { dev->cd_status = CD_STATUS_STOPPED; - dev->cdrom_capacity = cdrom_ioctl_get_capacity(dev); + dev->cdrom_capacity = ioctl_get_capacity(dev); } else if (ret == -1) dev->cd_status = CD_STATUS_EMPTY; @@ -260,7 +258,7 @@ cdrom_ioctl_open(cdrom_t *dev, const char *drv) dev->is_dir = 0; dev->seek_pos = 0; dev->cd_buflen = 0; - dev->cdrom_capacity = cdrom_ioctl_get_capacity(dev); + dev->cdrom_capacity = ioctl_get_capacity(dev); cdrom_ioctl_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index a21dd357f..8e81f9459 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -50,6 +50,7 @@ typedef struct SMSF { } TMSF; extern int plat_cdrom_is_track_audio(uint32_t sector); +extern int plat_cdrom_is_track_pre(uint32_t sector); extern uint32_t plat_cdrom_get_last_block(void); extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 36838820a..ff422bcd2 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -72,6 +72,17 @@ plat_cdrom_open(void) { plat_cdrom_close(); + handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); + + return (handle != INVALID_HANDLE_VALUE); +} + +static int +plat_cdrom_load(void) +{ + plat_cdrom_close(); + handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); if (handle != INVALID_HANDLE_VALUE) { @@ -112,7 +123,7 @@ plat_cdrom_is_track_audio(uint32_t sector) cur_toc.TrackData[c].TrackNumber, c, cur_toc.TrackData[c].Control, track_addr, sector); if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector <= next_track_addr)) { + (sector >= track_addr) && (sector < next_track_addr)) { control = cur_toc.TrackData[c].Control; break; } @@ -125,6 +136,36 @@ plat_cdrom_is_track_audio(uint32_t sector) return ret; } +int +plat_cdrom_is_track_pre(uint32_t sector) +{ + int control = 0; + uint32_t track_addr = 0; + uint32_t next_track_addr = 0; + + plat_cdrom_read_toc(); + + for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { + track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; + next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; + win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", + cur_toc.FirstTrack, cur_toc.LastTrack, + cur_toc.TrackData[c].TrackNumber, c, + cur_toc.TrackData[c].Control, track_addr, sector); + if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && + (sector >= track_addr) && (sector < next_track_addr)) { + control = cur_toc.TrackData[c].Control; + break; + } + } + + const int ret = (control & 0x01); + + win_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + uint32_t plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) { @@ -136,14 +177,16 @@ plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; - win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", + win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, a: %02X, A: %08X, S: %08X\n", cur_toc.FirstTrack, cur_toc.LastTrack, cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, track_addr, sector); + cur_toc.TrackData[c].Control, cur_toc.TrackData[c].Adr, + track_addr, sector); if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector <= next_track_addr)) { + (sector >= track_addr) && (sector < next_track_addr)) { *track = cur_toc.TrackData[c].TrackNumber; *attr = cur_toc.TrackData[c].Control; + *attr |= ((cur_toc.TrackData[c].Adr << 4) & 0xf0); break; } } @@ -239,6 +282,7 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *track_num = cur_toc.TrackData[track - 1].TrackNumber; *attr = cur_toc.TrackData[track - 1].Control; + *attr |= ((cur_toc.TrackData[track - 1].Adr << 4) & 0xf0); win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", track, start->min, start->sec, start->fr, *track_num, *attr); @@ -265,6 +309,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, *track = sub.CurrentPosition.TrackNumber; *attr = sub.CurrentPosition.Control; + *attr |= ((sub.CurrentPosition.ADR << 4) & 0xf0); *index = sub.CurrentPosition.IndexNumber; rel_pos->min = sub.CurrentPosition.TrackRelativeAddress[1]; @@ -303,15 +348,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) plat_cdrom_open(); - if (!raw) { - win_cdrom_ioctl_log("Cooked\n"); - /* Cooked */ - int success = 0; - DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); - if (newPos != 0xFFFFFFFF) - success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); - status = (success != 0); - } else { + if (raw) { win_cdrom_ioctl_log("Raw\n"); /* Raw */ RAW_READ_INFO in; @@ -321,9 +358,17 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) in.TrackMode = CDDA; status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), buffer, buflen, (LPDWORD)&size, NULL); + } else { + win_cdrom_ioctl_log("Cooked\n"); + /* Cooked */ + int success = 0; + DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + if (newPos != 0xFFFFFFFF) + success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); + status = (success != 0); } plat_cdrom_close(); - win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%d.\n", status, sector, size); + win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); return (size == buflen) && (status > 0); } @@ -361,6 +406,6 @@ plat_cdrom_set_drive(const char *drv) toc_valid = 0; - plat_cdrom_open(); + plat_cdrom_load(); return 1; } From 7c74a977fa965faa94429cde86d9c25733930500 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 02:15:17 +0200 Subject: [PATCH 526/690] There goes the legacy host_drive. --- src/cdrom/cdrom.c | 25 ++++++++----------------- src/cdrom/cdrom_image.c | 1 - src/cdrom/cdrom_ioctl.c | 1 - src/cdrom/cdrom_mitsumi.c | 20 ++++++++++++-------- src/config.c | 23 ++--------------------- src/include/86box/cdrom.h | 2 -- src/machine_status.c | 6 +----- src/qt/qt_machinestatus.cpp | 2 +- src/qt/qt_mediamenu.cpp | 6 ++---- src/scsi/scsi_cdrom.c | 18 +++++++++--------- src/unix/unix_cdrom.c | 9 +++------ 11 files changed, 38 insertions(+), 75 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 0da199b52..88811c016 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1961,7 +1961,7 @@ cdrom_hard_reset(void) dev->cd_status = CD_STATUS_EMPTY; - if (dev->host_drive == 200) { + if (strlen(dev->image_path) > 0) { #ifdef _WIN32 if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) dev->image_path[strlen(dev->image_path) - 1] = '\\'; @@ -2023,16 +2023,12 @@ cdrom_eject(uint8_t id) cdrom_t *dev = &cdrom[id]; /* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */ - if (dev->host_drive == 0) { + if (strlen(dev->image_path) == 0) { /* Switch from empty to empty. Do nothing. */ return; } - if (dev->host_drive >= 200) - strcpy(dev->prev_image_path, dev->image_path); - - dev->prev_host_drive = dev->host_drive + (dev->host ? 1 : 0); - dev->host_drive = 0; + strcpy(dev->prev_image_path, dev->image_path); dev->ops->exit(dev); dev->ops = NULL; @@ -2051,7 +2047,7 @@ cdrom_reload(uint8_t id) { cdrom_t *dev = &cdrom[id]; - if (!dev->host && ((dev->host_drive == dev->prev_host_drive) || (dev->prev_host_drive == 0) || (dev->host_drive != 0))) { + if ((strcmp(dev->image_path, dev->prev_image_path) == 0) || (strlen(dev->prev_image_path) == 0) || (strlen(dev->image_path) > 0)) { /* Switch from empty to empty. Do nothing. */ return; } @@ -2061,18 +2057,18 @@ cdrom_reload(uint8_t id) dev->ops = NULL; memset(dev->image_path, 0, sizeof(dev->image_path)); - if (dev->prev_host_drive >= 200) { + if (strlen(dev->image_path) > 0) { /* Reload a previous image. */ - if (dev->prev_host_drive == 200) + if (strlen(dev->prev_image_path) > 0) strcpy(dev->image_path, dev->prev_image_path); #ifdef _WIN32 - if (dev->prev_host_drive == 200) { + if (strlen(dev->prev_image_path) > 0) { if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) dev->image_path[strlen(dev->image_path) - 1] = '\\'; } #else - if (dev->prev_host_drive == 200) { + if (strlen(dev->prev_image_path) > 0) { if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) dev->image_path[strlen(dev->image_path) - 1] = '/'; } @@ -2084,11 +2080,6 @@ cdrom_reload(uint8_t id) cdrom_image_open(dev, dev->image_path); cdrom_insert(id); - - if (strlen(dev->image_path) == 0) - dev->host_drive = 0; - else - dev->host_drive = 200; } plat_cdrom_ui_update(id, 1); diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index be6779f9b..2203674cd 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -259,7 +259,6 @@ image_open_abort(cdrom_t *dev) { cdrom_image_close(dev); dev->ops = NULL; - dev->host_drive = 0; dev->image_path[0] = 0; return 1; } diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index c1bc6569e..a204fad0f 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -230,7 +230,6 @@ cdrom_ioctl_open_abort(cdrom_t *dev) { cdrom_ioctl_close(dev); dev->ops = NULL; - dev->host_drive = 0; dev->image_path[0] = 0; return 1; } diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index 7f4d2645b..01a9cf047 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -147,14 +147,18 @@ mitsumi_cdrom_log(const char *fmt, ...) # define mitsumi_cdrom_log(fmt, ...) #endif +static int +mitsumi_cdrom_is_ready(const cdrom_t *dev) +{ + return (dev->image_path[0] != 0x00); +} + static void mitsumi_cdrom_reset(mcd_t *dev) { cdrom_t cdrom; - cdrom.host_drive = 0; - - dev->stat = cdrom.host_drive ? (STAT_READY | STAT_CHANGE) : 0; + dev->stat = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | STAT_CHANGE) : 0; dev->cmdrd_count = 0; dev->cmdbuf_count = 0; dev->buf_count = 0; @@ -344,18 +348,18 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; } if (!dev->cmdrd_count) - dev->stat = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + dev->stat = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; return; } dev->cmd = val; dev->cmdbuf_idx = 0; dev->cmdrd_count = 0; dev->cmdbuf_count = 1; - dev->cmdbuf[0] = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + dev->cmdbuf[0] = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; dev->data = 0; switch (val) { case CMD_GET_INFO: - if (cdrom.host_drive) { + if (mitsumi_cdrom_is_ready(&cdrom)) { cdrom_get_track_buffer(&cdrom, &(dev->cmdbuf[1])); dev->cmdbuf_count = 10; dev->readcount = 0; @@ -365,7 +369,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) } break; case CMD_GET_Q: - if (cdrom.host_drive) { + if (mitsumi_cdrom_is_ready(&cdrom)) { cdrom_get_q(&cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC); dev->cmdbuf_count = 11; dev->readcount = 0; @@ -391,7 +395,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case CMD_READ1X: case CMD_READ2X: - if (cdrom.host_drive) { + if (mitsumi_cdrom_is_ready(&cdrom)) { dev->readcount = 0; dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ; dev->cmdrd_count = 6; diff --git a/src/config.c b/src/config.c index fdecb6cd5..77ec89125 100644 --- a/src/config.c +++ b/src/config.c @@ -1175,8 +1175,7 @@ load_floppy_and_cdrom_drives(void) memset(temp, 0x00, sizeof(temp)); for (c = 0; c < CDROM_NUM; c++) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); - cdrom[c].host_drive = ini_section_get_int(cat, temp, 0); - cdrom[c].prev_host_drive = cdrom[c].host_drive; + ini_section_delete_var(cat, temp); sprintf(temp, "cdrom_%02i_parameters", c + 1); p = ini_section_get_string(cat, temp, NULL); @@ -1263,12 +1262,6 @@ load_floppy_and_cdrom_drives(void) path_normalize(cdrom[c].image_path); } - if (cdrom[c].host_drive && (cdrom[c].host_drive != 200) && (cdrom[c].host_drive != 201)) - cdrom[c].host_drive = 0; - - 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) << 1, sizeof(char)); sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); @@ -1289,9 +1282,6 @@ load_floppy_and_cdrom_drives(void) /* 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); - ini_section_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); @@ -1422,9 +1412,6 @@ load_other_removable_devices(void) /* 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); - sprintf(temp, "zip_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); @@ -1538,9 +1525,6 @@ load_other_removable_devices(void) /* 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); - sprintf(temp, "mo_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); @@ -2575,10 +2559,7 @@ save_floppy_and_cdrom_drives(void) for (c = 0; c < CDROM_NUM; c++) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); - if ((cdrom[c].bus_type == 0) || ((cdrom[c].host_drive != 200) && (cdrom[c].host_drive != 201))) - ini_section_delete_var(cat, temp); - else - ini_section_set_int(cat, temp, cdrom[c].host_drive); + ini_section_delete_var(cat, temp); sprintf(temp, "cdrom_%02i_speed", c + 1); if ((cdrom[c].bus_type == 0) || (cdrom[c].speed == 8)) diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 33f900806..1702382a3 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -241,8 +241,6 @@ typedef struct cdrom { uint32_t cd_end; uint32_t type; - int host_drive; - int prev_host_drive; int cd_buflen; int audio_op; int audio_muted_soft; diff --git a/src/machine_status.c b/src/machine_status.c index 03c0ac092..16976fa83 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -33,11 +33,7 @@ machine_status_init(void) machine_status.fdd[i].active = false; } for (size_t i = 0; i < CDROM_NUM; ++i) { - if (cdrom[i].host) - machine_status.cdrom[i].empty = cdrom[i].host_drive != 201; - else - machine_status.cdrom[i].empty = cdrom[i].host_drive != 200 || (strlen(cdrom[i].image_path) == 0); - + machine_status.cdrom[i].empty = (strlen(cdrom[i].image_path) == 0); machine_status.cdrom[i].active = false; } for (size_t i = 0; i < ZIP_NUM; i++) { diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 88375354b..a074f556e 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -533,7 +533,7 @@ MachineStatus::refresh(QStatusBar *sbar) iterateCDROM([this, sbar](int i) { d->cdrom[i].label = std::make_unique(); - d->cdrom[i].setEmpty((cdrom[i].host_drive != 200) || QString(cdrom[i].image_path).isEmpty()); + d->cdrom[i].setEmpty(QString(cdrom[i].image_path).isEmpty()); d->cdrom[i].setActive(false); d->cdrom[i].refresh(); connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 1a2b0e831..de4f5a05e 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -478,7 +478,6 @@ MediaMenu::cdromMount(int i, const QString &filename) { QByteArray fn = filename.toUtf8().data(); - cdrom[i].prev_host_drive = cdrom[i].host_drive; strcpy(cdrom[i].prev_image_path, cdrom[i].image_path); if (cdrom[i].ops && cdrom[i].ops->exit) cdrom[i].ops->exit(&(cdrom[i])); @@ -499,9 +498,8 @@ MediaMenu::cdromMount(int i, const QString &filename) /* Signal media change to the emulated machine. */ if (cdrom[i].insert) cdrom[i].insert(cdrom[i].priv); - cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0) ? 0 : 200; - if (cdrom[i].host_drive >= 200) + if (strlen(cdrom[i].image_path) > 0) ui_sb_update_icon_state(SB_CDROM | i, 0); else ui_sb_update_icon_state(SB_CDROM | i, 1); @@ -557,7 +555,7 @@ MediaMenu::cdromUpdateUi(int i) { cdrom_t *drv = &cdrom[i]; - if (drv->host_drive == 0) { + if (strlen(cdrom[i].image_path) == 0) { mhm.addImageToHistory(i, ui::MediaType::Optical, drv->prev_image_path, QString()); ui_sb_update_icon_state(SB_CDROM | i, 1); } else { diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 12840f624..262d9600c 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1887,7 +1887,7 @@ begin: case GPCMD_AUDIO_SCAN: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2563,7 +2563,7 @@ begin: case CDROM_TYPE_TOSHIBA_XM5701TA_3136: case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2591,7 +2591,7 @@ begin: case CDROM_TYPE_NEC_211_100: case CDROM_TYPE_NEC_464_105: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2670,7 +2670,7 @@ begin: case CDROM_TYPE_TOSHIBA_XM5701TA_3136: case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_PLAY_AUDIO_TOSHIBA*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2697,7 +2697,7 @@ begin: case CDROM_TYPE_NEC_211_100: case CDROM_TYPE_NEC_464_105: /*GPCMD_PLAY_AUDIO_NEC*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2765,7 +2765,7 @@ begin: break; } - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -2882,7 +2882,7 @@ begin: } pos = cdb[4]; - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -3596,7 +3596,7 @@ atapi_out: break; case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_AUDIO_TRACK_SEARCH_PIONEER*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } @@ -3646,7 +3646,7 @@ atapi_out: break; case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_PLAY_AUDIO_PIONEER*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { scsi_cdrom_illegal_mode(dev); break; } diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 61813a754..186c7649b 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -124,7 +124,7 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload) { cdrom_t *drv = &cdrom[id]; - if (drv->host_drive == 0) { + if (drv->image_path[0] == 0x00) { ui_sb_update_icon_state(SB_CDROM | id, 1); } else { ui_sb_update_icon_state(SB_CDROM | id, 0); @@ -139,7 +139,6 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload) void cdrom_mount(uint8_t id, char *fn) { - cdrom[id].prev_host_drive = cdrom[id].host_drive; strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); if (cdrom[id].ops && cdrom[id].ops->exit) cdrom[id].ops->exit(&(cdrom[id])); @@ -151,12 +150,10 @@ cdrom_mount(uint8_t id, char *fn) /* Signal media change to the emulated machine. */ if (cdrom[id].insert) cdrom[id].insert(cdrom[id].priv); - cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200; - if (cdrom[id].host_drive == 200) { + if (cdrom[id].image_path[0] == 0x00) ui_sb_update_icon_state(SB_CDROM | id, 0); - } else { + else ui_sb_update_icon_state(SB_CDROM | id, 1); - } #if 0 media_menu_update_cdrom(id); #endif From f8b93dc24e64a89fec60491d5d796db47af133c6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 02:17:36 +0200 Subject: [PATCH 527/690] And .host as well. --- src/include/86box/cdrom.h | 1 - src/qt/qt_mediamenu.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 1702382a3..b3f5a5ea5 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -245,7 +245,6 @@ typedef struct cdrom { int audio_op; int audio_muted_soft; int sony_msf; - int host; const cdrom_ops_t *ops; diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index de4f5a05e..d9d6b6c31 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -485,7 +485,7 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); #ifdef Q_OS_WINDOWS - if (!cdrom[i].host && (fn.data() != nullptr) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) + if ((fn.data() != nullptr) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) fn.data()[strlen(fn.data()) - 1] = '\\'; #else if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) From 1baae350dc855f2acc53a83bb059ebe9ef37ee50 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 20 May 2024 02:26:10 +0200 Subject: [PATCH 528/690] More S3 changes/fixes. S3 928: When the pitch is 1280, make sure the proper horizontal resolution is displayed right (in this case, 1280x1024). S3 Vision864: Exclude it from the horizontal blank bits due to more issues that are TBD (like the Trio32 and 64 and up), this works around the mode issues under Windows 9x and more as well as fix 32bpp horizontal rendering in said chip. --- src/video/vid_s3.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index a971c2f65..8fa86dfe0 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3370,9 +3370,9 @@ s3_recalctimings(svga_t *svga) if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { svga->vram_display_mask = s3->vram_mask; s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " - "attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], + "attr=%02x, hdisp=%d.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, - svga->attrregs[0x10] & 0x40); + svga->attrregs[0x10] & 0x40, svga->hdisp); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3381,9 +3381,19 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_METHEUS_86C928: switch (s3->width) { - case 1280: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } break; case 2048: /*Account for the 1280x1024 resolution*/ switch (svga->hdisp) { @@ -3979,6 +3989,11 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_VISION864: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + break; + case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -4116,7 +4131,7 @@ s3_recalctimings(svga_t *svga) } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64)) + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864)) svga->hoverride = 1; else svga->hoverride = 0; From 18736f9c94b04d8839088a6bf6ebc852c2bc21f3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 03:07:14 +0200 Subject: [PATCH 529/690] Fixed a compile-breaking bug on non-Windows. --- src/qt/qt_mediamenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index d9d6b6c31..a1d8a528c 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -591,7 +591,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) #ifdef Q_OS_WINDOWS menu_item_name = tr("Host CD/DVD Drive (%1)").arg(fn.right(2)).toUtf8().constData(); #else - menu_item_name = tr("Host CD/DVD Drive (%1)").arg(fn.right(name.length() - 8)); + menu_item_name = tr("Host CD/DVD Drive (%1)").arg(fn.right(fn.length() - 8)); #endif } else { fi.setFile(fn); From 1b68770bda5e6a028fdbe1f830e32f13c27c00db Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 03:52:53 +0200 Subject: [PATCH 530/690] Dummy CD-ROM IOCTL handler to fix compiling platforms other than Windows. --- src/qt/CMakeLists.txt | 3 + src/qt/dummy_cdrom_ioctl.c | 241 +++++++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 src/qt/dummy_cdrom_ioctl.c diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index ebaa84be1..1e9c76378 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -227,6 +227,9 @@ endif() if(WIN32) target_sources(plat PRIVATE win_cdrom_ioctl.c) +else() +# Replace with proper *nix and mac handler files once they are done. + target_sources(plat PRIVATE dummy_cdrom_ioctl.c) endif() if (APPLE) diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c new file mode 100644 index 000000000..f319f554b --- /dev/null +++ b/src/qt/dummy_cdrom_ioctl.c @@ -0,0 +1,241 @@ +/* + * 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. + * + * Win32 CD-ROM support via IOCTL. + * + * + * + * Authors: TheCollector1995, , + * Miran Grca, + * + * Copyright 2023 TheCollector1995. + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/scsi_device.h> +#include <86box/cdrom.h> +#include <86box/plat_unused.h> +#include <86box/plat_cdrom.h> + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) + +static int toc_valid = 0; + +#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG +int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; + +void +dummy_cdrom_ioctl_log(const char *fmt, ...) +{ + va_list ap; + + if (dummy_cdrom_ioctl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define dummy_cdrom_ioctl_log(fmt, ...) +#endif + +static int +plat_cdrom_open(void) +{ + return 0; +} + +static int +plat_cdrom_load(void) +{ + return 0; +} + +static void +plat_cdrom_read_toc(void) +{ + if (!toc_valid) + toc_valid = 1; +} + +int +plat_cdrom_is_track_audio(uint32_t sector) +{ + plat_cdrom_read_toc(); + + const int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + +int +plat_cdrom_is_track_pre(uint32_t sector) +{ + plat_cdrom_read_toc(); + + const int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + +uint32_t +plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +{ + plat_cdrom_read_toc(); + + return 0x00000000; +} + +uint32_t +plat_cdrom_get_last_block(void) +{ + plat_cdrom_read_toc(); + + return 0x00000000; +} + +int +plat_cdrom_ext_medium_changed(void) +{ + int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); + + return ret; +} + +void +plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +{ + plat_cdrom_read_toc(); + + *st_track = 1; + *end = 1; + lead_out->min = 0; + lead_out->sec = 0; + lead_out->fr = 2; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", + *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); +} + +/* This replaces both Info and EndInfo, they are specified by a variable. */ +int +plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +{ + plat_cdrom_read_toc(); + + if ((track < 1) || (track == 0xaa)) { + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); + return 0; + } + + start->min = 0; + start->sec = 0; + start->fr = 2; + + *track_num = 1; + *attr = 0x14; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", + track, start->min, start->sec, start->fr, *track_num, *attr); + + return 1; +} + +/* TODO: See if track start is adjusted by 150 or not. */ +int +plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +{ + long size = 0; + + *track = 1; + *attr = 0x14; + *index = 1; + + rel_pos->min = 0; + rel_pos->sec = 0; + rel_pos->fr = 0; + abs_pos->min = 0; + abs_pos->sec = 0; + abs_pos->fr = 2; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); + + return 1; +} + +int +plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +{ + dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); + + return 2048; +} + +int +plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +{ + int status; + long size = 0; + int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + + plat_cdrom_open(); + + if (raw) { + dummy_cdrom_ioctl_log("Raw\n"); + /* Raw */ + } else { + dummy_cdrom_ioctl_log("Cooked\n"); + /* Cooked */ + } + plat_cdrom_close(); + dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); + + return 0; +} + +void +plat_cdrom_eject(void) +{ + plat_cdrom_open(); + plat_cdrom_close(); +} + +void +plat_cdrom_close(void) +{ +} + +int +plat_cdrom_set_drive(const char *drv) +{ + plat_cdrom_close(); + + toc_valid = 0; + + plat_cdrom_load(); + return 1; +} From d07f018e6b23afe03cbf8d98b88f5adae74a3b97 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 04:04:13 +0200 Subject: [PATCH 531/690] Removed the io.c #include from the dummy IOCTL handler and added the handler to the Unix SDL UI as well. --- src/qt/dummy_cdrom_ioctl.c | 1 - src/unix/CMakeLists.txt | 2 +- src/unix/dummy_cdrom_ioctl.c | 240 +++++++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 src/unix/dummy_cdrom_ioctl.c diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index f319f554b..cb0824675 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -17,7 +17,6 @@ * Copyright 2023 Miran Grca. */ #include -#include #include #include #include diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index aa4cc84e2..4cbda5c83 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -27,7 +27,7 @@ set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) target_link_libraries(86Box Threads::Threads) -add_library(ui OBJECT unix_sdl.c unix_cdrom.c) +add_library(ui OBJECT unix_sdl.c unix_cdrom.c dummy_cdrom_ioctl.c) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui ${CMAKE_DL_LIBS}) diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c new file mode 100644 index 000000000..cb0824675 --- /dev/null +++ b/src/unix/dummy_cdrom_ioctl.c @@ -0,0 +1,240 @@ +/* + * 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. + * + * Win32 CD-ROM support via IOCTL. + * + * + * + * Authors: TheCollector1995, , + * Miran Grca, + * + * Copyright 2023 TheCollector1995. + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/scsi_device.h> +#include <86box/cdrom.h> +#include <86box/plat_unused.h> +#include <86box/plat_cdrom.h> + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) + +static int toc_valid = 0; + +#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG +int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; + +void +dummy_cdrom_ioctl_log(const char *fmt, ...) +{ + va_list ap; + + if (dummy_cdrom_ioctl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define dummy_cdrom_ioctl_log(fmt, ...) +#endif + +static int +plat_cdrom_open(void) +{ + return 0; +} + +static int +plat_cdrom_load(void) +{ + return 0; +} + +static void +plat_cdrom_read_toc(void) +{ + if (!toc_valid) + toc_valid = 1; +} + +int +plat_cdrom_is_track_audio(uint32_t sector) +{ + plat_cdrom_read_toc(); + + const int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + +int +plat_cdrom_is_track_pre(uint32_t sector) +{ + plat_cdrom_read_toc(); + + const int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + + return ret; +} + +uint32_t +plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +{ + plat_cdrom_read_toc(); + + return 0x00000000; +} + +uint32_t +plat_cdrom_get_last_block(void) +{ + plat_cdrom_read_toc(); + + return 0x00000000; +} + +int +plat_cdrom_ext_medium_changed(void) +{ + int ret = 0; + + dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); + + return ret; +} + +void +plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +{ + plat_cdrom_read_toc(); + + *st_track = 1; + *end = 1; + lead_out->min = 0; + lead_out->sec = 0; + lead_out->fr = 2; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", + *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); +} + +/* This replaces both Info and EndInfo, they are specified by a variable. */ +int +plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +{ + plat_cdrom_read_toc(); + + if ((track < 1) || (track == 0xaa)) { + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); + return 0; + } + + start->min = 0; + start->sec = 0; + start->fr = 2; + + *track_num = 1; + *attr = 0x14; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", + track, start->min, start->sec, start->fr, *track_num, *attr); + + return 1; +} + +/* TODO: See if track start is adjusted by 150 or not. */ +int +plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +{ + long size = 0; + + *track = 1; + *attr = 0x14; + *index = 1; + + rel_pos->min = 0; + rel_pos->sec = 0; + rel_pos->fr = 0; + abs_pos->min = 0; + abs_pos->sec = 0; + abs_pos->fr = 2; + + dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", + *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); + + return 1; +} + +int +plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +{ + dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); + + return 2048; +} + +int +plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +{ + int status; + long size = 0; + int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + + plat_cdrom_open(); + + if (raw) { + dummy_cdrom_ioctl_log("Raw\n"); + /* Raw */ + } else { + dummy_cdrom_ioctl_log("Cooked\n"); + /* Cooked */ + } + plat_cdrom_close(); + dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); + + return 0; +} + +void +plat_cdrom_eject(void) +{ + plat_cdrom_open(); + plat_cdrom_close(); +} + +void +plat_cdrom_close(void) +{ +} + +int +plat_cdrom_set_drive(const char *drv) +{ + plat_cdrom_close(); + + toc_valid = 0; + + plat_cdrom_load(); + return 1; +} From 117f604bf695d7b489091a51b308a88b4cf0938f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Mon, 20 May 2024 11:07:55 -0400 Subject: [PATCH 532/690] fdd: Add support for pcjs json floppy images --- src/CMakeLists.txt | 2 +- src/cJSON.c | 3129 ++++++++++++++++++++++++++++++++++ src/floppy/CMakeLists.txt | 2 +- src/floppy/fdd.c | 6 +- src/floppy/fdd_pcjs.c | 795 +++++++++ src/include/86box/fdd_pcjs.h | 255 +++ src/include/cJSON.h | 300 ++++ 7 files changed, 4484 insertions(+), 5 deletions(-) create mode 100644 src/cJSON.c create mode 100644 src/floppy/fdd_pcjs.c create mode 100644 src/include/86box/fdd_pcjs.h create mode 100644 src/include/cJSON.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7030e9f63..6cfaef89c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ 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 fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c - machine_status.c ini.c) + machine_status.c ini.c cJSON.c) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1) diff --git a/src/cJSON.c b/src/cJSON.c new file mode 100644 index 000000000..4e4979e99 --- /dev/null +++ b/src/cJSON.c @@ -0,0 +1,3129 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef NAN +#ifdef _WIN32 +#define NAN sqrt(-1.0) +#else +#define NAN 0.0/0.0 +#endif +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 17) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + /* return NULL if the object is corrupted */ + if (object->valuestring == NULL) + { + return NULL; + } + if (strlen(valuestring) <= strlen(object->valuestring)) + { + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + + memcpy(newbuffer, p->buffer, p->offset + 1); + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else if(d == (double)item->valueint) + { + length = sprintf((char*)number_buffer, "%d", item->valueint); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0 || newitem == NULL) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + if (after_inserted != array->child && after_inserted->prev == NULL) { + /* return false if after_inserted is a corrupted array item */ + return false; + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if (replacement->string == NULL) + { + return false; + } + + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + if (newitem && newitem->child) + { + newitem->child->prev = newchild; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt index 89fbbf76f..6d69d2d59 100644 --- a/src/floppy/CMakeLists.txt +++ b/src/floppy/CMakeLists.txt @@ -14,5 +14,5 @@ # add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_monster.c fdc_pii15xb.c - fdi2raw.c fdd_common.c fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_json.c + fdi2raw.c fdd_common.c fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_pcjs.c fdd_mfm.c fdd_td0.c) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 09e791c4e..72d6ac648 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -34,7 +34,7 @@ #include <86box/fdd_fdi.h> #include <86box/fdd_imd.h> #include <86box/fdd_img.h> -#include <86box/fdd_json.h> +#include <86box/fdd_pcjs.h> #include <86box/fdd_mfm.h> #include <86box/fdd_td0.h> #include <86box/fdc.h> @@ -131,7 +131,7 @@ static const struct { "IMA", img_load, img_close, -1}, { "IMD", imd_load, imd_close, -1}, { "IMG", img_load, img_close, -1}, - { "JSON", json_load, json_close, -1}, + { "JSON", pcjs_load, pcjs_close, -1}, { "MFM", mfm_load, mfm_close, -1}, { "TD0", td0_load, td0_close, -1}, { "VFD", img_load, img_close, -1}, @@ -674,7 +674,7 @@ fdd_init(void) d86f_init(); td0_init(); imd_init(); - json_init(); + pcjs_init(); for (i = 0; i < FDD_NUM; i++) { fdd_load(i, floppyfns[i]); diff --git a/src/floppy/fdd_pcjs.c b/src/floppy/fdd_pcjs.c new file mode 100644 index 000000000..474d8ee37 --- /dev/null +++ b/src/floppy/fdd_pcjs.c @@ -0,0 +1,795 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the pcjs v2 floppy image format (read-only) + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + + +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/fdd.h> +#include <86box/fdd_86f.h> +#include <86box/fdd_common.h> +#include <86box/fdd_pcjs.h> +#include + +static pcjs_t *images[FDD_NUM]; +static pcjs_error_t pcjs_error = E_SUCCESS; + +struct pcjs_error_description { + int code; + const char *message; +} pcjs_error_description[] = { + { E_SUCCESS, "No error" }, + { E_MISSING_KEY, "The requested key was missing" }, + { E_UNEXPECTED_VALUE, "The value was not of the expected type" }, + { E_INTEGRITY, "Integrity check failed" }, + { E_INVALID_OBJECT, "Object is missing or invalid" }, + { E_ALLOC, "Memory allocation failure" }, + { E_PARSE, "Parsing failure" }, + { -1, "Unknown error" }, +}; + +#ifdef ENABLE_PCJS_LOG +int pcjs_do_log = ENABLE_PCJS_LOG; +static void +pcjs_log(const char *fmt, ...) +{ + if (pcjs_do_log) { + va_list ap; + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define pcjs_log(fmt, ...) +#endif + +void +pcjs_init(void) +{ + memset(images, 0x00, sizeof(images)); +} + +const char* pcjs_errmsg(void) +{ + int i = 0; + while (pcjs_error_description[i].code >= 0) { + if (pcjs_error_description[i].code == pcjs_error) { + return pcjs_error_description[i].message; + } + i++; + } + return "Unknown error"; +} + +int parse_image_info(pcjs_t *dev, const cJSON *parsed_json) +{ + const cJSON *imageInfo = NULL; + + if(dev == NULL || parsed_json == NULL) { + pcjs_log("Null values passed\n"); + pcjs_error = E_INTEGRITY; + return 1; + } + + imageInfo = cJSON_GetObjectItemCaseSensitive(parsed_json, "imageInfo"); + + if (imageInfo == NULL || !cJSON_IsObject(imageInfo)) { + pcjs_log("imageInfo object does not exist or is invalid\n"); + pcjs_error = E_INVALID_OBJECT; + return 1; + } + + /* Macros are used here to avoid repetition */ + /* First get strings */ + IMAGE_INFO_GET_STRING(type) + IMAGE_INFO_GET_STRING(name) + IMAGE_INFO_GET_STRING(format) + IMAGE_INFO_GET_STRING(hash) + IMAGE_INFO_GET_STRING(version) + IMAGE_INFO_GET_STRING(repository) + /* Then the numbers */ + IMAGE_INFO_GET_NUMBER(cylinders) + IMAGE_INFO_GET_NUMBER(heads) + IMAGE_INFO_GET_NUMBER(trackDefault) + IMAGE_INFO_GET_NUMBER(sectorDefault) + IMAGE_INFO_GET_NUMBER(diskSize) + + /* Special cases */ + /* Convert bootSector to array if it exists */ + /* For some reason the array itself is stored as a string + * which needs to be converted into an array before parsing. */ + dev->image_info.boot_sector_array_size = 0; + const cJSON *array_string = cJSON_GetObjectItemCaseSensitive(imageInfo, "bootSector"); + cJSON *bootSector = NULL; + if(cJSON_IsString(array_string) && array_string != NULL) { + bootSector = cJSON_Parse(array_string->valuestring); + } + if(cJSON_IsArray(bootSector)) { + const int array_size = cJSON_GetArraySize(bootSector); + dev->image_info.boot_sector_array_size = array_size; + const cJSON *array_item = NULL; + int array_index = 0; + cJSON_ArrayForEach(array_item, bootSector) + { + /* Make sure each item is a number */ + if(!cJSON_IsNumber(array_item)) { + pcjs_log("Non-number item in bootSector array\n"); + dev->image_info.boot_sector_array_size = 0; + /* Prevent the loop from continuing */ + array_item = NULL; + break; + } + /* Make sure each number is in range */ + const int value = array_item->valueint; + if (value < 0 || value > 255) { + pcjs_log("bootSector value %i out of range (0-255)\n", value); + dev->image_info.boot_sector_array_size = 0; + /* Prevent the loop from continuing */ + array_item = NULL; + break; + } + /* Make sure we don't exceed the array length */ + if (array_index + 1 > PCJS_IMAGE_INFO_ARRAY_LEN) { + pcjs_log("bootSector array length exceeded (max %i)\n", PCJS_IMAGE_INFO_ARRAY_LEN); + dev->image_info.boot_sector_array_size = 0; + /* Prevent the loop from continuing */ + array_item = NULL; + break; + } + dev->image_info.boot_sector[array_index] = value; + array_index++; + } + } + + /* checksum: Can't use the number macro like the others because it uses valueInt + * which is 32-bit signed and we need unsigned. Use the double value (valuedouble) instead. */ + const cJSON *checksum_json = cJSON_GetObjectItemCaseSensitive(imageInfo, "checksum"); + if (cJSON_IsNumber(checksum_json)) { + dev->image_info.checksum = checksum_json->valuedouble; + } else { + pcjs_log("Required number value for \"%s\" missing from imageInfo\n", "checksum"); + pcjs_error = E_MISSING_KEY; + cJSON_Delete(bootSector); + return 1; + } + + /* Use the metadata as the official source */ + dev->total_tracks = dev->image_info.cylinders; + dev->total_sides = dev->image_info.heads; + dev->total_sectors = dev->image_info.trackDefault; + cJSON_Delete(bootSector); + return 0; +} + +int parse_file_table(pcjs_t *dev, const cJSON *parsed_json) +{ + const cJSON *fileTable = NULL; + + if(dev == NULL || parsed_json == NULL) { + pcjs_log("Null values passed\n"); + pcjs_error = E_INTEGRITY; + return 1; + } + + fileTable = cJSON_GetObjectItemCaseSensitive(parsed_json, "fileTable"); + + if (fileTable == NULL || !cJSON_IsArray(fileTable)) { + pcjs_log("fileTable object does not exist or is invalid\n"); + pcjs_error = E_INVALID_OBJECT; + return 1; + } + + const cJSON *each_file_table = NULL; + dev->file_table.num_entries = cJSON_GetArraySize(fileTable); + uint16_t processed_entries = 0; + uint16_t current_entry = 0; + + if (dev->file_table.num_entries == 0) { + pcjs_log("No fileTable entries to process\n"); + return 0; + } + + pcjs_log("Processing %i file table entries\n", dev->file_table.num_entries); + + /* Allocate the entries */ + dev->file_table.entries = (pcjs_file_table_entry_t *)calloc(dev->file_table.num_entries, sizeof(pcjs_file_table_entry_t)); + if (dev->file_table.entries == NULL ) { + pcjs_log("Failed to allocate file table entries\n"); + pcjs_error = E_ALLOC; + return 1; + } + + cJSON_ArrayForEach(each_file_table, fileTable) + { + /* The -1 length of the temporary buffer brought to you by gcc's -Wstringop-truncation */ + char hash[PCJS_FILE_TABLE_STRING_LEN-1] = {0}; + char path[PCJS_FILE_TABLE_STRING_LEN-1] = {0}; + char attr[PCJS_FILE_TABLE_STRING_LEN-1] = {0}; + char date[PCJS_FILE_TABLE_STRING_LEN-1] = {0}; + uint16_t f_size = 0; + + JSON_GET_OBJECT_STRING_OPTIONAL(hash, each_file_table, PCJS_OBJECT_KEY_FT_HASH) + JSON_GET_OBJECT_STRING_OPTIONAL(path, each_file_table, PCJS_OBJECT_KEY_FT_PATH) + JSON_GET_OBJECT_STRING_REQUIRED(attr, each_file_table, PCJS_OBJECT_KEY_FT_ATTR) + JSON_GET_OBJECT_STRING_REQUIRED(date, each_file_table, PCJS_OBJECT_KEY_FT_DATE) + JSON_GET_OBJECT_NUMBER_OPTIONAL(f_size, each_file_table, PCJS_OBJECT_KEY_FT_SIZE) + + strncpy(dev->file_table.entries[current_entry].hash, hash, sizeof(dev->file_table.entries[current_entry].hash) - 1); + strncpy(dev->file_table.entries[current_entry].path, path, sizeof(dev->file_table.entries[current_entry].path) - 1); + strncpy(dev->file_table.entries[current_entry].attr, attr, sizeof(dev->file_table.entries[current_entry].attr) - 1); + strncpy(dev->file_table.entries[current_entry].date, date, sizeof(dev->file_table.entries[current_entry].date) - 1); + dev->file_table.entries[current_entry].size = f_size; + + processed_entries++; + current_entry++; + + } + + if(processed_entries != dev->file_table.num_entries) { + pcjs_log("fileTable entries processed (%i) inconsistent with number of entries in the table (%i)\n", processed_entries, dev->file_table.num_entries); + pcjs_error = E_INTEGRITY; + goto fail; + } + + return 0; +fail: + /* Deallocate the array */ + free(dev->file_table.entries); + return 1; +} + +int json_parse(pcjs_t *dev) +{ + const cJSON *diskData = NULL; + + /* Determine the size of the file, reset back */ + fseek(dev->fp, 0L, SEEK_END); + const long numbytes = ftell(dev->fp); + fseek(dev->fp, 0L, SEEK_SET); + + /* Allocate memory for the contents */ + char *buffer = calloc(numbytes + 1, sizeof(char)); + if(buffer == NULL) { + pcjs_error = E_ALLOC; + return 1; + } + + /* Read and null terminate */ + fread(buffer, sizeof(char), numbytes, dev->fp); + buffer[numbytes] = '\0'; + + cJSON *parsed_json = cJSON_Parse(buffer); + + if (parsed_json == NULL) + { + const char *error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) { + fprintf(stderr, "Error parsing json before: %s\n", error_ptr); + } + pcjs_error = E_PARSE; + goto fail; + } + + if(parse_image_info(dev, parsed_json)) { + pcjs_log("Failed to parse imageInfo metadata\n"); + goto fail; + } + + /* File table metadata is optional */ + if(parse_file_table(dev, parsed_json)) { + pcjs_log("File table metadata is not present or invalid\n"); + } + + diskData = cJSON_GetObjectItemCaseSensitive(parsed_json, "diskData"); + + const cJSON *each_track = NULL; + int total_c = 0; + int full_count = 0; + + /* The diskData array is essentially [c][h][s] */ + /* Start with the tracks in [c] */ + cJSON_ArrayForEach(each_track, diskData) + { + int total_heads = 0; + const cJSON *each_head = NULL; + + /* For each track, loop on each head */ + /* Now in [c][h] */ + cJSON_ArrayForEach(each_head, each_track) + { + int total_sectors = 0; + const cJSON *each_sector = NULL; + + /* Now loop on the sectors in [c][h][s] */ + /* Each sector item will have the information needed to fill in a pcjs_sector_t */ + cJSON_ArrayForEach(each_sector, each_head) + { + const cJSON *data = NULL; + const cJSON *each_data = NULL; + int data_array_size = 0; + int total_d = 0; + int32_t current_track = 0; + int32_t current_head = 0; + int32_t current_sector = 0; + int32_t current_length = 0; + int32_t file_mapping = 0; + int32_t offset = 0; + pcjs_sector_t *sector = NULL; + + /* Macros to keep things tidy */ + JSON_GET_OBJECT_NUMBER_REQUIRED(current_track, each_sector, PCJS_OBJECT_KEY_TRACK) + JSON_GET_OBJECT_NUMBER_REQUIRED(current_head, each_sector, PCJS_OBJECT_KEY_HEAD) + JSON_GET_OBJECT_NUMBER_REQUIRED(current_sector, each_sector, PCJS_OBJECT_KEY_SECTOR) + JSON_GET_OBJECT_NUMBER_REQUIRED(current_length, each_sector, PCJS_OBJECT_KEY_LENGTH) + JSON_GET_OBJECT_NUMBER_OPTIONAL_DEFAULT(offset, each_sector, PCJS_OBJECT_KEY_OFFSET, -1) + JSON_GET_OBJECT_NUMBER_OPTIONAL_DEFAULT(file_mapping, each_sector, PCJS_OBJECT_KEY_FILE, -1) + + /* NOTE: The sectors array is zero indexed, but the metadata for each sector shows its conventional sector number */ + sector = &dev->sectors[current_track][current_head][current_sector-1]; + + if (sector->data == NULL ) { + /* We could verify the sector size against the metadata here */ + sector->data = (uint8 *)calloc(1, current_length); + if (sector->data == NULL ) { + pcjs_log("Failed to allocate\n"); + pcjs_error = E_ALLOC; + goto fail; + } + } + sector->track = current_track; + sector->side = current_head; + sector->sector = current_sector; + sector->size = current_length; + sector->encoded_size = fdd_sector_size_code(current_length); + sector->offset = offset; + sector->file = file_mapping; + sector->pattern_repeat = 0; + sector->last_entry = 0; + + data = cJSON_GetObjectItemCaseSensitive(each_sector, PCJS_OBJECT_KEY_DATA); + if(data != NULL && cJSON_IsArray(data)) { + data_array_size = cJSON_GetArraySize(data); + cJSON_ArrayForEach(each_data, data) + { + /* total_d is our current position in the data array */ + /* That number will be used to determine where to store the + * value in its destination (sector->data). + * Each value in the data array is a 32-bit integer, but the + * destination (sector->data) is a uint8_t array. Therefore + * we'll need to manually calculate offsets and place the bytes. + */ + const int dest_offset = total_d * 4; + if(total_d == data_array_size - 1) { + /* This is the last value in the data array. Check to see if we'll need it + * for the repeating pattern. + * We use current_length / 4 because each data element is 32 bits in size. + * For example, if current_length = 512 + * then 512 / 4 = 128 + * so anything less than that value will have padding */ + if (total_d + 1 < current_length / 4) { + sector->last_entry = each_data->valueint; + /* total_d + 1 because it is zero indexed at this point */ + sector->pattern_repeat = current_length / 4 - (total_d + 1); + } + } + const int value = each_data->valueint; + /* Take each value and shift in as necessary */ + for (int i = 0; i < 4; i++) { + sector->data[dest_offset + i] = (value >> i * 8) & 0xff; + } + total_d++; + } + } else { + pcjs_log("Data array missing from [%d][%d][%d]", current_track, current_head, current_sector); + pcjs_error = E_MISSING_KEY; + goto fail; + } + /* Fill in the repeating pattern if needed */ + /* total_d was already advanced at the end of the previous loop */ + for (int i = 0; i < sector->pattern_repeat; i++ ) { + const int position = total_d + i; + const int dest_offset = position * 4; + if(position >= (sector->size / 4)) { + /* Something is wrong */ + pcjs_log("Out of bounds write attempt to data array at %i", position); + pcjs_error = E_INTEGRITY; + goto fail; + } + for (int j = 0; j < 4; j++) { + sector->data[dest_offset + j] = (sector->last_entry >> j * 8) & 0xff; + } + } + + total_sectors++; + full_count++; + dev->calc_total_sectors = total_sectors; + /* End sectors */ + } + dev->spt[total_c][total_heads] = total_sectors; + total_heads++; + dev->calc_total_sides = total_heads; + /* End heads */ + } + total_c++; + dev->calc_total_tracks = total_c; + /* End tracks */ + } + + pcjs_log("calculated totals: c/h/s %i/%i/%i\n", dev->calc_total_tracks, dev->calc_total_sides, dev->calc_total_sectors); + pcjs_log("metadata totals: c/h/s %i/%i/%i\n", dev->image_info.cylinders, dev->image_info.heads, dev->image_info.trackDefault); + + free(buffer); + cJSON_Delete(parsed_json); + return 0; +fail: + free(buffer); + cJSON_Delete(parsed_json); + return pcjs_error; +} + +/* Handlers */ + +static uint16_t +disk_flags(int drive) +{ + const pcjs_t *dev = images[drive]; + + return dev->disk_flags; +} + +static uint16_t +track_flags(int drive) +{ + const pcjs_t *dev = images[drive]; + + return dev->track_flags; +} + +static void +set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +{ + pcjs_t *dev = images[drive]; + + dev->current_sector[side] = 0; + + /* Make sure we are on the desired track. */ + if (c != dev->current_track) + return; + + /* Set the desired side. */ + dev->current_side = side; + + /* Sectors are stored zero indexed, but sector zero should not be requested */ + if(r == 0) { + pcjs_log("set_sector: Sector 0 requested?\n"); + } else { + dev->current_sector[side] = r - 1; + } + /* The ifdef is necessary because if ENABLE_PCJS_LOG is not defined gcc throws an unused variable warning */ +#ifdef ENABLE_PCJS_LOG + const int file_index = dev->sectors[dev->current_track][side][dev->current_sector[side]].file; + pcjs_log("set sector: %i/%i/%i %s%s%s\n", c, h, r, + file_index == -1 ? "" : "(", + file_index == -1 ? "" : dev->file_table.entries[file_index].path, + file_index == -1 ? "" : ")"); +#endif +} + +static uint8_t +poll_read_data(int drive, int side, uint16_t pos) +{ + const pcjs_t *dev = images[drive]; + const uint8_t sec = dev->current_sector[side]; + return (dev->sectors[dev->current_track][side][sec].data[pos]); +} + +static void +pcjs_seek(int drive, int track) +{ + uint8_t id[4] = { 0, 0, 0, 0 }; + pcjs_t *dev = images[drive]; + int rate; + int gap2; + int gap3; + int pos; + int ssize; + int rsec; + int asec; + + if (dev->fp == NULL) { + pcjs_log("pcjs_seek: no file loaded\n"); + return; + } + + /* Allow for doublestepping tracks. */ + if (!dev->track_width && fdd_doublestep_40(drive)) + track /= 2; + + /* Set the new track. */ + dev->current_track = track; + d86f_set_cur_track(drive, track); + + /* Reset the 86F state machine. */ + d86f_reset_index_hole_pos(drive, 0); + d86f_destroy_linked_lists(drive, 0); + d86f_reset_index_hole_pos(drive, 1); + d86f_destroy_linked_lists(drive, 1); + + if (track > dev->total_tracks) { + d86f_zero_track(drive); + return; + } + + pcjs_log("seeking to track %i\n", track); + + for (uint8_t side = 0; side < dev->total_sides; side++) { + /* Get transfer rate for this side. */ + rate = dev->track_flags & 0x07; + if (!rate && (dev->track_flags & 0x20)) + rate = 4; + + /* Get correct GAP3 value for this side. */ + gap3 = fdd_get_gap3_size(rate, + // dev->sectors[track][side][0].size, + dev->sectors[track][side][0].encoded_size, + dev->spt[track][side]); + + /* Get correct GAP2 value for this side. */ + gap2 = ((dev->track_flags & 0x07) >= 3) ? 41 : 22; + + pos = d86f_prepare_pretrack(drive, side, 0); + + for (uint8_t sector = 0; sector < dev->spt[track][side]; sector++) { + rsec = dev->sectors[track][side][sector].sector; + asec = sector; + + id[0] = track; + id[1] = side; + id[2] = rsec; + if (dev->sectors[track][side][asec].encoded_size > 255) + perror("PCJS: pcjs_seek: sector size too big."); + id[3] = dev->sectors[track][side][asec].encoded_size & 0xff; + ssize = fdd_sector_code_size(dev->sectors[track][side][asec].encoded_size & 0xff); + + pos = d86f_prepare_sector( + drive, side, pos, id, + dev->sectors[track][side][asec].data, + ssize, gap2, gap3, + 0 + ); + + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } +} + +static int +pcjs_load_image(pcjs_t *dev) +{ + if (dev->fp == NULL) { + pcjs_log("No file loaded!\n"); + return 1; + } + + /* Initialize. */ + for (uint16_t i = 0; i < PCJS_MAX_TRACKS; i++) { + for (uint8_t j = 0; j < PCJS_MAX_SIDES; j++) + memset(dev->sectors[i][j], 0x00, sizeof(pcjs_sector_t)); + } + dev->current_track = 0; + dev->current_side = 0; + + return json_parse(dev); +} + +void +pcjs_load(int drive, char *fn) +{ + double bit_rate = 0; + int temp_rate; + const pcjs_sector_t *sector; + pcjs_t *dev; + + d86f_unregister(drive); + + /* Allocate a drive block */ + dev = (pcjs_t *) malloc(sizeof(pcjs_t)); + memset(dev, 0x00, sizeof(pcjs_t)); + + /* Open the image file, read-only */ + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { + free(dev); + memset(fn, 0x00, sizeof(char)); + return; + } + + pcjs_log("Opening filename: %s\n", fn); + + /* Always set the drive to write-protected mode */ + writeprot[drive] = 1; + + /* Place in the correct slot */ + images[drive] = dev; + + /* Parse and load the information from the json file */ + if (pcjs_load_image(dev)) { + pcjs_log("Failed to initialize: %s\n", pcjs_errmsg()); + (void) fclose(dev->fp); + free(dev); + images[drive] = NULL; + memset(fn, 0x00, sizeof(char)); + return; + } + + pcjs_log("Drive %d: %s (%i tracks, %i sides, %i sectors, sector size %i)\n", + drive, fn, dev->image_info.cylinders, dev->image_info.heads, dev->image_info.trackDefault, dev->image_info.sectorDefault); + + + /* + * If the image has more than 43 tracks, then + * the tracks are thin (96 tpi). + */ + dev->track_width = (dev->total_tracks > 43) ? 1 : 0; + + /* If the image has 2 sides, mark it as such. */ + dev->disk_flags = 0x00; + if (dev->total_sides == 2) + dev->disk_flags |= 0x08; + + /* PCJS files are always assumed to be MFM-encoded. */ + dev->track_flags = 0x08; + + dev->interleave = 0; + + temp_rate = 0xff; + sector = &dev->sectors[0][0][0]; + for (uint8_t i = 0; i < 6; i++) { + if (dev->spt[0][0] > fdd_max_sectors[sector->encoded_size][i]) + continue; + + bit_rate = fdd_bit_rates_300[i]; + temp_rate = fdd_rates[i]; + dev->disk_flags |= (fdd_holes[i] << 1); + + if ((bit_rate == 500.0) && (dev->spt[0][0] == 21) && (sector->encoded_size == 2) && (dev->total_tracks >= 80) && (dev->total_tracks <= 82) && (dev->total_sides == 2)) { + /* + * This is a DMF floppy, set the flag so + * we know to interleave the sectors. + */ + dev->dmf = 1; + } else { + if ((bit_rate == 500.0) && (dev->spt[0][0] == 22) && (sector->encoded_size == 2) && (dev->total_tracks >= 80) && (dev->total_tracks <= 82) && (dev->total_sides == 2)) { + /* + * This is marked specially because of the + * track flag (a RPM slow down is needed). + */ + dev->interleave = 2; + } + dev->dmf = 0; + } + break; + } + + if (temp_rate == 0xff) { + pcjs_log("Invalid image (temp_rate=0xff)\n"); + (void) fclose(dev->fp); + dev->fp = NULL; + free(dev); + images[drive] = NULL; + memset(fn, 0x00, sizeof(char)); + return; + } + + if (dev->interleave == 2) { + dev->interleave = 1; + dev->disk_flags |= 0x60; + } + + dev->gap2_len = (temp_rate == 3) ? 41 : 22; + if (dev->dmf) + dev->gap3_len = 8; + else + dev->gap3_len = fdd_get_gap3_size(temp_rate, sector->encoded_size, dev->spt[0][0]); + + if (!dev->gap3_len) { + pcjs_log("Image of unknown format was inserted into drive %c:\n", + 'C' + drive); + (void) fclose(dev->fp); + dev->fp = NULL; + free(dev); + images[drive] = NULL; + memset(fn, 0x00, sizeof(char)); + return; + } + + dev->track_flags |= (temp_rate & 0x03); /* data rate */ + if (temp_rate & 0x04) + dev->track_flags |= 0x20; /* RPM */ + + pcjs_log(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n", + dev->disk_flags, dev->track_flags, dev->gap3_len); + pcjs_log(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n", + bit_rate, temp_rate, (dev->disk_flags >> 1), dev->dmf); + pcjs_log(" encoded_size: %i spt: %i\n", sector->encoded_size, dev->spt[0][0]); + + /* Set up 86F handlers */ + + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = track_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = null_write_data; + d86f_handler[drive].format_conditions = null_format_conditions; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = null_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, 0x0063); + + d86f_common_handlers(drive); + + drives[drive].seek = pcjs_seek; + +} + +void +pcjs_close(int drive) +{ + pcjs_t *dev = images[drive]; + + if (dev == NULL) + return; + + /* Unlink image from the system. */ + d86f_unregister(drive); + + /* Release all the sector buffers. */ + for (int c = 0; c < PCJS_MAX_TRACKS; c++) { + for (int h = 0; h < PCJS_MAX_SIDES; h++) { + for (uint16_t s = 0; s < PCJS_MAX_SECTORS; s++) { + if (dev->sectors[c][h][s].data != NULL) + free(dev->sectors[c][h][s].data); + dev->sectors[c][h][s].data = NULL; + + } + } + } + /* Release file table entries */ + if(dev->file_table.entries != NULL) + free(dev->file_table.entries); + dev->file_table.entries = NULL; + dev->file_table.num_entries = 0; + + if (dev->fp != NULL) + (void) fclose(dev->fp); + + /* Release the memory. */ + free(dev); + images[drive] = NULL; +} diff --git a/src/include/86box/fdd_pcjs.h b/src/include/86box/fdd_pcjs.h new file mode 100644 index 000000000..30e8d28a3 --- /dev/null +++ b/src/include/86box/fdd_pcjs.h @@ -0,0 +1,255 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the pcjs v2 floppy image format (read-only) + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + * + * More info: https://www.pcjs.org/tools/diskimage/ + * pcjs disk module v2: https://github.com/jeffpar/pcjs/blob/master/machines/pcx86/modules/v2/disk.js + */ + +#ifndef EMU_FLOPPY_PCJS_H +#define EMU_FLOPPY_PCJS_H + +/* Currently targeting v2 of the spec */ +#define PCJS_DISK_SPEC_VERSION 2 + +#define PCJS_MAX_TRACKS 256 +#define PCJS_MAX_SIDES 2 +#define PCJS_MAX_SECTORS 256 + +/* The json keys as defined in each sector array item */ +#define PCJS_OBJECT_KEY_CYLINDER "c" +#define PCJS_OBJECT_KEY_TRACK PCJS_OBJECT_KEY_CYLINDER +#define PCJS_OBJECT_KEY_HEAD "h" +#define PCJS_OBJECT_KEY_SECTOR "s" +#define PCJS_OBJECT_KEY_LENGTH "l" +#define PCJS_OBJECT_KEY_DATA "d" +#define PCJS_OBJECT_KEY_FILE "f" +#define PCJS_OBJECT_KEY_OFFSET "d" + +/* The json keys as defined in the fileTable object */ +#define PCJS_OBJECT_KEY_FT_HASH "hash" +#define PCJS_OBJECT_KEY_FT_PATH "path" +#define PCJS_OBJECT_KEY_FT_ATTR "attr" +#define PCJS_OBJECT_KEY_FT_DATE "date" +#define PCJS_OBJECT_KEY_FT_SIZE "size" + +/* String length defaults */ +#define PCJS_IMAGE_INFO_STRING_LEN 128 +#define PCJS_IMAGE_INFO_ARRAY_LEN 128 +#define PCJS_FILE_TABLE_STRING_LEN 128 + +/* Defaults for optional json values */ +#define JSON_OPTIONAL_NUMBER_DEFAULT 0 +#define JSON_OPTIONAL_STRING_DEFAULT "" + +/* Structure for each sector */ +typedef struct pcjs_sector_t { + /* Track number */ + uint8_t track; + /* Side number */ + uint8_t side; + /* Sector number */ + uint8_t sector; + /* Size of the sector */ + uint16_t size; + /* Encoded size of the sector */ + uint16_t encoded_size; + /* Pointer the the allocated data for the sector */ + uint8_t *data; + /* Number of times to repeat the pattern until end of sector */ + uint16_t pattern_repeat; + /* Last pattern entry to repeat */ + int32_t last_entry; + /* Maps back to a file entry. -1 if not set */ + int32_t file; + /* The offset in the mapped file entry. -1 if not set */ + int32_t offset; +} pcjs_sector_t; + +/* Cases are mixed here (some camelCase) to match the pcjs values */ +typedef struct pcjs_image_info_t { + char type[PCJS_IMAGE_INFO_STRING_LEN]; + char name[PCJS_IMAGE_INFO_STRING_LEN]; + char format[PCJS_IMAGE_INFO_STRING_LEN]; + char hash[PCJS_IMAGE_INFO_STRING_LEN]; + uint32_t checksum; + uint8_t cylinders; + uint8_t heads; + uint8_t trackDefault; + uint16_t sectorDefault; + uint32_t diskSize; + uint8_t boot_sector[PCJS_IMAGE_INFO_ARRAY_LEN]; + uint8_t boot_sector_array_size; + char version[PCJS_IMAGE_INFO_STRING_LEN]; + char repository[PCJS_IMAGE_INFO_STRING_LEN]; +} pcjs_image_info_t; + +typedef struct pcjs_file_table_entry_t { + char hash[PCJS_FILE_TABLE_STRING_LEN]; + char path[PCJS_FILE_TABLE_STRING_LEN]; + char attr[PCJS_FILE_TABLE_STRING_LEN]; + char date[PCJS_FILE_TABLE_STRING_LEN]; + uint32_t size; +} pcjs_file_table_entry_t ; + +typedef struct pcjs_file_table_t { + pcjs_file_table_entry_t *entries; + uint16_t num_entries; +} pcjs_file_table_t; + +typedef struct pcjs_t { + /* FILE pointer for the json file */ + FILE *fp; + + /* These values are read in from the metadata */ + /* Total number of tracks */ + uint8_t total_tracks; + /* Total number of sides */ + uint8_t total_sides; + /* Total number of sectors per track */ + uint16_t total_sectors; + + /* These values are calculated for validation */ + /* Calculated number of tracks */ + uint8_t calc_total_tracks; + /* Calculated number of sides */ + uint8_t calc_total_sides; + /* Calculated number of sectors per track */ + uint16_t calc_total_sectors; + + /* Number of sectors per track */ + uint8_t spt[PCJS_MAX_TRACKS][PCJS_MAX_SIDES]; + + /* Current track */ + uint8_t current_track; + /* Current side */ + uint8_t current_side; + /* Current sector */ + uint8_t current_sector[PCJS_MAX_SIDES]; + + /* Disk is in dmf format? */ + uint8_t dmf; + uint8_t interleave; + uint8_t gap2_len; + uint8_t gap3_len; + int track_width; + + /* Flags for the entire disk */ + uint16_t disk_flags; + /* Flags for the current track */ + uint16_t track_flags; + + uint8_t interleave_ordered[PCJS_MAX_TRACKS][PCJS_MAX_SIDES]; + + /* The main mapping of all the sectors back to each individual pcjs_sector_t item. */ + pcjs_sector_t sectors[PCJS_MAX_TRACKS][PCJS_MAX_SIDES][PCJS_MAX_SECTORS]; + + /* Disk metadata information contained in each image */ + pcjs_image_info_t image_info; + /* Optional file table mapping for each sector */ + pcjs_file_table_t file_table; +} pcjs_t; + +/* Errors */ +enum pcjs_img_error { + E_SUCCESS = 0, + E_MISSING_KEY = 1, + E_UNEXPECTED_VALUE = 2, + E_INTEGRITY, + E_INVALID_OBJECT, + E_ALLOC, + E_PARSE, +}; + +typedef enum pcjs_img_error pcjs_error_t; + +/* Macros */ + +/* Macro for getting image info metadata: strings */ +#define IMAGE_INFO_GET_STRING(type) \ + const cJSON * type##_json = cJSON_GetObjectItemCaseSensitive(imageInfo, #type); \ + if (cJSON_IsString( type##_json) && type##_json->valuestring != NULL) { \ + strncpy(dev->image_info.type, type##_json->valuestring, sizeof(dev->image_info. type) - 1); \ + } else { \ + pcjs_log("Required string value for \"%s\" missing from imageInfo\n", #type); \ + pcjs_error = E_INVALID_OBJECT; \ + return 1; \ + } +/* Macro for getting image info metadata: ints */ +#define IMAGE_INFO_GET_NUMBER(type) \ + const cJSON * type##_json = cJSON_GetObjectItemCaseSensitive(imageInfo, #type); \ + if (cJSON_IsNumber( type##_json)) { \ + dev->image_info.type = type##_json->valueint; \ + } else { \ + pcjs_log("Required number value for \"%s\" missing from imageInfo\n", #type); \ + pcjs_error = E_INVALID_OBJECT; \ + return 1; \ + } + +/* Macro for getting required object value: number */ +#define JSON_GET_OBJECT_NUMBER_REQUIRED(var, json, key) \ +const cJSON *var##_json = cJSON_GetObjectItemCaseSensitive(json, key); \ +if (!cJSON_IsNumber(var##_json)) { \ + pcjs_log("Required number value for \"%s\" missing or invalid\n", key); \ + pcjs_error = E_INVALID_OBJECT; \ + goto fail; \ +} else { \ + var = var##_json->valueint; \ +} + +/* Macro for getting optional object value: number + * Default value will be used if the number does not exist */ +#define JSON_GET_OBJECT_NUMBER_OPTIONAL(var, json, key) \ +const cJSON *var##_json = cJSON_GetObjectItemCaseSensitive(json, key); \ +if (!cJSON_IsNumber(var##_json)) { \ +var = JSON_OPTIONAL_NUMBER_DEFAULT; \ +} else { \ +var = var##_json->valueint; \ +} + +/* Macro for getting optional object value: number + * Provided default value will be used if the number does not exist */ +#define JSON_GET_OBJECT_NUMBER_OPTIONAL_DEFAULT(var, json, key, default) \ +const cJSON *var##_json = cJSON_GetObjectItemCaseSensitive(json, key); \ +if (!cJSON_IsNumber(var##_json)) { \ +var = default; \ +} else { \ +var = var##_json->valueint; \ +} + +/* Macro for getting optional object value: string + * Default value will be used if the string does not exist */ +#define JSON_GET_OBJECT_STRING_OPTIONAL(var, json, key) \ + const cJSON * var##_json = cJSON_GetObjectItemCaseSensitive(json, key); \ + if (cJSON_IsString( var##_json) && var##_json->valuestring != NULL) { \ + strncpy(var, var##_json->valuestring, sizeof(var) - 1); \ + } else { \ + strncpy(var, JSON_OPTIONAL_STRING_DEFAULT, sizeof(var) - 1); \ + } + +/* Macro for getting required object value: string */ +#define JSON_GET_OBJECT_STRING_REQUIRED(var, json, key) \ + const cJSON * var##_json = cJSON_GetObjectItemCaseSensitive(json, key); \ + if (cJSON_IsString( var##_json) && var##_json->valuestring != NULL) { \ + strncpy(var, var##_json->valuestring, sizeof(var) - 1); \ + } else { \ + pcjs_error = E_INVALID_OBJECT; \ + goto fail; \ + } + +extern void pcjs_init(void); +extern void pcjs_load(int drive, char *fn); +extern void pcjs_close(int drive); +extern const char* pcjs_errmsg(void); + +#endif diff --git a/src/include/cJSON.h b/src/include/cJSON.h new file mode 100644 index 000000000..218cc9ea6 --- /dev/null +++ b/src/include/cJSON.h @@ -0,0 +1,300 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 17 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable address area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/ +#define cJSON_SetBoolValue(object, boolValue) ( \ + (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \ + (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \ + cJSON_Invalid\ +) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif From b9ae4575a2d3b4c24603b746bae26983477b3b74 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 May 2024 21:40:36 +0200 Subject: [PATCH 533/690] Removed fdd_json.c/h. --- src/floppy/fdd_json.c | 704 ----------------------------------- src/include/86box/fdd_json.h | 52 --- 2 files changed, 756 deletions(-) delete mode 100644 src/floppy/fdd_json.c delete mode 100644 src/include/86box/fdd_json.h diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c deleted file mode 100644 index 36a041a68..000000000 --- a/src/floppy/fdd_json.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * Implementation of the PCjs JSON floppy image format. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2019 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/timer.h> -#include <86box/plat.h> -#include <86box/fdd.h> -#include <86box/fdd_86f.h> -#include <86box/fdc.h> -#include <86box/fdd_common.h> -#include <86box/fdd_json.h> - -#define NTRACKS 256 -#define NSIDES 2 -#define NSECTORS 256 - -typedef struct sector_t { - uint8_t track; /* ID: track number */ - uint8_t side; /* side number */ - uint8_t sector; /* sector number 1.. */ - uint16_t size; /* encoded size of sector */ - uint8_t *data; /* allocated data for it */ -} sector_t; - -typedef struct json_t { - FILE *fp; - - /* Geometry. */ - uint8_t tracks; /* number of tracks */ - uint8_t sides; /* number of sides */ - uint8_t sectors; /* number of sectors per track */ - uint8_t spt[NTRACKS][NSIDES]; /* number of sectors per track */ - - uint8_t track; /* current track */ - uint8_t side; /* current side */ - uint8_t sector[NSIDES]; /* current sector */ - - uint8_t dmf; /* disk is DMF format */ - uint8_t interleave; -#if 0 - uint8_t skew; -#endif - uint8_t gap2_len; - uint8_t gap3_len; - int track_width; - - uint16_t disk_flags; /* flags for the entire disk */ - uint16_t track_flags; /* flags for the current track */ - - uint8_t interleave_ordered[NTRACKS][NSIDES]; - - sector_t sects[NTRACKS][NSIDES][NSECTORS]; -} json_t; - -static json_t *images[FDD_NUM]; - -#define ENABLE_JSON_LOG 1 -#ifdef ENABLE_JSON_LOG -int json_do_log = ENABLE_JSON_LOG; - -static void -json_log(const char *fmt, ...) -{ - va_list ap; - - if (json_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define json_log(fmt, ...) -#endif - -static void -handle(json_t *dev, char *name, char *str) -{ - sector_t *sec = NULL; - uint32_t l; - uint32_t pat; - uint8_t *p; - char *sp; - int s; - - /* Point to the currently selected sector. */ - sec = &dev->sects[dev->track][dev->side][dev->dmf - 1]; - - /* If no name given, assume sector is done. */ - if (name == NULL) { - /* If no buffer, assume one with 00's. */ - if (sec->data == NULL) { - sec->data = (uint8_t *) malloc(sec->size); - memset(sec->data, 0x00, sec->size); - } - - /* Encode the sector size. */ - sec->size = fdd_sector_size_code(sec->size); - - /* Set up the rest of the Sector ID. */ - sec->track = dev->track; - sec->side = dev->side; - - return; - } - - if (!strcmp(name, "sector")) { - sec->sector = atoi(str); - sec->size = 512; - } else if (!strcmp(name, "length")) { - sec->size = atoi(str); - } else if (!strcmp(name, "pattern")) { - pat = atol(str); - - if (sec->data == NULL) - sec->data = (uint8_t *) malloc(sec->size); - p = sec->data; - s = (sec->size / sizeof(uint32_t)); - for (int i = 0; i < s; i++) { - l = pat; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - } - } else if (!strcmp(name, "data")) { - if (sec->data == NULL) - sec->data = (uint8_t *) malloc(sec->size); - p = sec->data; - while (str && *str) { - sp = strchr(str, ','); - if (sp != NULL) - *sp++ = '\0'; - l = atol(str); - - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - - str = sp; - } - } -} - -static int -unexpect(int c, int state, int level) -{ - json_log("JSON: Unexpected '%c' in state %d/%d.\n", c, state, level); - - return (-1); -} - -static int -load_image(json_t *dev) -{ - char buff[4096]; - char name[32]; - int c; - int state; - int level; - char *ptr; - - if (dev->fp == NULL) { - json_log("JSON: no file loaded!\n"); - return 0; - } - - /* Initialize. */ - for (uint16_t i = 0; i < NTRACKS; i++) { - for (uint8_t j = 0; j < NSIDES; j++) - memset(dev->sects[i][j], 0x00, sizeof(sector_t)); - } - dev->track = dev->side = dev->dmf = 0; /* "dmf" is "sector#" */ - - /* Now run the state machine. */ - ptr = NULL; - level = state = 0; - while (state >= 0) { - /* Get a character from the input. */ - c = fgetc(dev->fp); - if ((c == EOF) || ferror(dev->fp)) { - state = -1; - break; - } - - /* Process it. */ - switch (state) { - case 0: /* read level header */ - dev->dmf = 1; - if ((c != '[') && (c != '{') && (c != '\r') && (c != '\n')) { - state = unexpect(c, state, level); - } else if (c == '[') { - if (++level == 3) - state++; - } - break; - - case 1: /* read sector header */ - if (c != '{') - state = unexpect(c, state, level); - else - state++; - break; - - case 2: /* begin sector data name */ - if (c != '\"') { - state = unexpect(c, state, level); - } else { - ptr = name; - state++; - } - break; - - case 3: /* read sector data name */ - if (c == '\"') { - *ptr = '\0'; - state++; - } else { - *ptr++ = c; - } - break; - - case 4: /* end of sector data name */ - if (c != ':') { - state = unexpect(c, state, level); - } else { - ptr = buff; - state++; - } - break; - - case 5: /* read sector value data */ - switch (c) { - case ',': - case '}': - *ptr = '\0'; - handle(dev, name, buff); - - if (c == '}') - state = 7; /* done */ - else - state = 2; /* word */ - break; - - case '[': - state++; - break; - - default: - *ptr++ = c; - } - break; - - case 6: /* read sector data complex */ - if (c != ']') - *ptr++ = c; - else - state = 5; - break; - - case 7: /* sector done */ - handle(dev, NULL, NULL); - switch (c) { - case ',': /* next sector */ - dev->dmf++; - state = 1; - break; - - case ']': /* all sectors done */ - if (--level == 0) - state = -1; - else - state++; - break; - - default: - state = unexpect(c, state, level); - } - break; - - case 8: /* side done */ - switch (c) { - case ',': /* next side */ - state = 0; - break; - - case ']': /* all sides done */ - if (--level == 0) - state = -1; - else - state++; - break; - - default: - state = unexpect(c, state, level); - } - dev->spt[dev->track][dev->side] = dev->dmf; - dev->side++; - break; - - case 9: /* track done */ - switch (c) { - case ',': /* next track */ - dev->side = 0; - state = 0; - break; - - case ']': /* all tracks done */ - if (--level == 0) - state = -1; - else - state++; - break; - - default: - state = unexpect(c, state, level); - } - dev->track++; - break; - - default: - break; - } - } - - /* Save derived values. */ - dev->tracks = dev->track; - dev->sides = dev->side; - - return 1; -} - -/* Seek the heads to a track, and prepare to read data from that track. */ -static void -json_seek(int drive, int track) -{ - uint8_t id[4] = { 0, 0, 0, 0 }; - json_t *dev = images[drive]; - int rate; - int gap2; - int gap3; - int pos; - int ssize; - int rsec; - int asec; - - if (dev->fp == NULL) { - json_log("JSON: seek: no file loaded!\n"); - return; - } - - /* Allow for doublestepping tracks. */ - if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; - - /* Set the new track. */ - dev->track = track; - d86f_set_cur_track(drive, track); - - /* Reset the 86F state machine. */ - d86f_reset_index_hole_pos(drive, 0); - d86f_destroy_linked_lists(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - d86f_destroy_linked_lists(drive, 1); - - if (track > dev->tracks) { - d86f_zero_track(drive); - return; - } - - for (uint8_t side = 0; side < dev->sides; side++) { - /* Get transfer rate for this side. */ - rate = dev->track_flags & 0x07; - if (!rate && (dev->track_flags & 0x20)) - rate = 4; - - /* Get correct GAP3 value for this side. */ - gap3 = fdd_get_gap3_size(rate, - dev->sects[track][side][0].size, - dev->spt[track][side]); - - /* Get correct GAP2 value for this side. */ - gap2 = ((dev->track_flags & 0x07) >= 3) ? 41 : 22; - - pos = d86f_prepare_pretrack(drive, side, 0); - - for (uint8_t sector = 0; sector < dev->spt[track][side]; sector++) { - rsec = dev->sects[track][side][sector].sector; - asec = sector; - - id[0] = track; - id[1] = side; - id[2] = rsec; - if (dev->sects[track][side][asec].size > 255) - perror("fdd_json.c: json_seek: sector size too big."); - id[3] = dev->sects[track][side][asec].size & 0xff; - ssize = fdd_sector_code_size(dev->sects[track][side][asec].size & 0xff); - - pos = d86f_prepare_sector( - drive, side, pos, id, - dev->sects[track][side][asec].data, - ssize, gap2, gap3, - 0 /*flags*/ - ); - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } -} - -static uint16_t -disk_flags(int drive) -{ - const json_t *dev = images[drive]; - - return (dev->disk_flags); -} - -static uint16_t -track_flags(int drive) -{ - const json_t *dev = images[drive]; - - return (dev->track_flags); -} - -static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - json_t *dev = images[drive]; - - dev->sector[side] = 0; - - /* Make sure we are on the desired track. */ - if (c != dev->track) - return; - - /* Set the desired side. */ - dev->side = side; - - /* Now loop over all sector ID's on this side to find our sector. */ - for (uint8_t i = 0; i < dev->spt[c][side]; i++) { - if ((dev->sects[dev->track][side][i].track == c) && (dev->sects[dev->track][side][i].side == h) && (dev->sects[dev->track][side][i].sector == r) && (dev->sects[dev->track][side][i].size == n)) { - dev->sector[side] = i; - } - } -} - -static uint8_t -poll_read_data(int drive, int side, uint16_t pos) -{ - const json_t *dev = images[drive]; - uint8_t sec = dev->sector[side]; - - return (dev->sects[dev->track][side][sec].data[pos]); -} - -void -json_init(void) -{ - memset(images, 0x00, sizeof(images)); -} - -void -json_load(int drive, char *fn) -{ - double bit_rate; - int temp_rate; - const sector_t *sec; - json_t *dev; - - /* Just in case- remove ourselves from 86F. */ - d86f_unregister(drive); - - /* Allocate a drive block. */ - dev = (json_t *) malloc(sizeof(json_t)); - memset(dev, 0x00, sizeof(json_t)); - - /* Open the image file. */ - dev->fp = plat_fopen(fn, "rb"); - if (dev->fp == NULL) { - free(dev); - memset(fn, 0x00, sizeof(char)); - return; - } - - /* Our images are always RO. */ - writeprot[drive] = 1; - - /* Set up the drive unit. */ - images[drive] = dev; - - /* Load all sectors from the image file. */ - if (!load_image(dev)) { - json_log("JSON: failed to initialize\n"); - (void) fclose(dev->fp); - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(char)); - return; - } - - json_log("JSON(%d): %s (%i tracks, %i sides, %i sectors)\n", - drive, fn, dev->tracks, dev->sides, dev->spt[0][0]); - - /* - * If the image has more than 43 tracks, then - * the tracks are thin (96 tpi). - */ - dev->track_width = (dev->tracks > 43) ? 1 : 0; - - /* If the image has 2 sides, mark it as such. */ - dev->disk_flags = 0x00; - if (dev->sides == 2) - dev->disk_flags |= 0x08; - - /* JSON files are always assumed to be MFM-encoded. */ - dev->track_flags = 0x08; - - dev->interleave = 0; -#if 0 - dev->skew = 0; -#endif - - temp_rate = 0xff; - sec = &dev->sects[0][0][0]; - for (uint8_t i = 0; i < 6; i++) { - if (dev->spt[0][0] > fdd_max_sectors[sec->size][i]) - continue; - - bit_rate = fdd_bit_rates_300[i]; - temp_rate = fdd_rates[i]; - dev->disk_flags |= (fdd_holes[i] << 1); - - if ((bit_rate == 500.0) && (dev->spt[0][0] == 21) && (sec->size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* - * This is a DMF floppy, set the flag so - * we know to interleave the sectors. - */ - dev->dmf = 1; - } else { - if ((bit_rate == 500.0) && (dev->spt[0][0] == 22) && (sec->size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* - * This is marked specially because of the - * track flag (a RPM slow down is needed). - */ - dev->interleave = 2; - } - - dev->dmf = 0; - } - - break; - } - - if (temp_rate == 0xff) { - json_log("JSON: invalid image (temp_rate=0xff)\n"); - (void) fclose(dev->fp); - dev->fp = NULL; - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(char)); - return; - } - - if (dev->interleave == 2) { - dev->interleave = 1; - dev->disk_flags |= 0x60; - } - - dev->gap2_len = (temp_rate == 3) ? 41 : 22; - if (dev->dmf) - dev->gap3_len = 8; - else - dev->gap3_len = fdd_get_gap3_size(temp_rate, sec->size, dev->spt[0][0]); - - if (!dev->gap3_len) { - json_log("JSON: image of unknown format was inserted into drive %c:!\n", - 'C' + drive); - (void) fclose(dev->fp); - dev->fp = NULL; - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(char)); - return; - } - - dev->track_flags |= (temp_rate & 0x03); /* data rate */ - if (temp_rate & 0x04) - dev->track_flags |= 0x20; /* RPM */ - - json_log(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n", - dev->disk_flags, dev->track_flags, dev->gap3_len); - json_log(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n", - bit_rate, temp_rate, (dev->disk_flags >> 1), dev->dmf); - - /* Set up handlers for 86F layer. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = track_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, 0x0063); - - d86f_common_handlers(drive); - - drives[drive].seek = json_seek; -} - -/* Close the image. */ -void -json_close(int drive) -{ - json_t *dev = images[drive]; - - if (dev == NULL) - return; - - /* Unlink image from the system. */ - d86f_unregister(drive); - - /* Release all the sector buffers. */ - for (uint16_t t = 0; t < 256; t++) { - for (uint8_t h = 0; h < 2; h++) { - memset(dev->sects[t][h], 0x00, sizeof(sector_t)); - for (uint16_t s = 0; s < 256; s++) { - if (dev->sects[t][h][s].data != NULL) - free(dev->sects[t][h][s].data); - dev->sects[t][h][s].data = NULL; - } - } - } - - if (dev->fp != NULL) - (void) fclose(dev->fp); - - /* Release the memory. */ - free(dev); - images[drive] = NULL; -} diff --git a/src/include/86box/fdd_json.h b/src/include/86box/fdd_json.h deleted file mode 100644 index 7f3c9adb4..000000000 --- a/src/include/86box/fdd_json.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * Definitions for the PCjs JSON floppy image format. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef EMU_FLOPPY_JSON_H -#define EMU_FLOPPY_JSON_H - -extern void json_init(void); -extern void json_load(int drive, char *fn); -extern void json_close(int drive); - -#endif /*EMU_FLOPPY_JSON_H*/ From 94c30b06f09eb44e927c1bd0700bdc56b8b535ba Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 20 May 2024 23:54:57 +0200 Subject: [PATCH 534/690] Fix Mach64 LFB in some cases. These few cases where it gets corrupt fonts like in some builds of NT 4.0 and mode changes in Win95's driver. Hopefully this keeps everything else intact. --- src/video/vid_ati_mach64.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 8403e718d..04d497f28 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -4253,13 +4253,6 @@ mach64_read_linear(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; - if (!svga->fast) { - if (svga->chain2_read) { - addr &= ~1; - addr <<= 2; - } - } - addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; @@ -4302,13 +4295,6 @@ mach64_write_linear(uint32_t addr, uint8_t val, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; - if (!svga->fast) { - if (svga->chain2_write) { - addr &= ~1; - addr <<= 2; - } - } - addr &= svga->decode_mask; if (addr >= svga->vram_max) return; From 92d6d71f6bff1f65adeeff1c1cddcea345c58356 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Tue, 21 May 2024 11:31:00 -0400 Subject: [PATCH 535/690] GHA: Remove unused vcpkg/LLVM workflow --- .github/workflows/cmake_windows_llvm.yml | 163 ----------------------- 1 file changed, 163 deletions(-) delete mode 100644 .github/workflows/cmake_windows_llvm.yml diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml deleted file mode 100644 index 93f4db241..000000000 --- a/.github/workflows/cmake_windows_llvm.yml +++ /dev/null @@ -1,163 +0,0 @@ -name: CMake (Windows, vcpkg/LLVM) - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/cmake_windows_llvm.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/cmake_windows_llvm.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - llvm-windows: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }}" - if: 0 - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - - name: Qt GUI - qt: on - slug: -Qt - target: - - name: x86 - triplet: x86-windows-static - toolchain: ./cmake/llvm-win32-i686.cmake - vcvars: x64_x86 - - name: x64 - triplet: x64-windows-static - toolchain: ./cmake/llvm-win32-x86_64.cmake - vcvars: x64 -# - name: ARM -# triplet: arm-windows-static -# toolchain: ./cmake/llvm-win32-arm.cmake -# vcvars: x64_arm - - name: ARM64 - triplet: arm64-windows-static - toolchain: ./cmake/llvm-win32-aarch64.cmake - vcvars: x64_arm64 - exclude: - - dynarec: - new: off - target: - name: ARM64 - - steps: - - name: Prepare VS environment - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.target.vcvars }} - - - name: Add LLVM to path - run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH - - - name: Download Ninja - run: > - Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip && - Expand-Archive ninja-win.zip -DestinationPath . - - - name: Setup NuGet Credentials - run: > - & (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2) - sources add - -source "https://nuget.pkg.github.com/86Box/index.json" - -storepasswordincleartext - -name "GitHub" - -username "86Box" - -password "${{ secrets.GITHUB_TOKEN }}" - - - name: Fix MSVC atomic headers - run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 - - - name: Configure CMake - run: > - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} - -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} - -D VCPKG_HOST_TRIPLET=x64-windows - -D VCPKG_USE_HOST_TOOLS=ON - - - name: Fix Qt - if: matrix.ui.qt == 'on' - run: | - $qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake" - (Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath - - - name: Reconfigure CMake - if: matrix.ui.qt == 'on' - run: | - cmake clean build - - - name: Build - run: | - .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' - path: build/artifacts/** From 5c222f3f6db93caff46dd317a52187f74484a609 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 21 May 2024 22:44:52 +0200 Subject: [PATCH 536/690] Non-ESS SB clones fix: Add sanity checks to prevent segfaults on non-ESS SB clones using the setirq and setdma8 functions. --- src/sound/snd_sb_dsp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 88f690762..65f33f4a3 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -875,9 +875,11 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; - sb_ess_update_irq_drq_readback_regs(dsp, true); + if (IS_ESS(dsp)) { + sb_ess_update_irq_drq_readback_regs(dsp, true); - ESSreg(0xB1) = (ESSreg(0xB1) & 0xEF) | 0x10; + ESSreg(0xB1) = (ESSreg(0xB1) & 0xEF) | 0x10; + } } void @@ -886,7 +888,8 @@ sb_dsp_setdma8(sb_dsp_t *dsp, int dma) sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; - sb_ess_update_irq_drq_readback_regs(dsp, true); + if (IS_ESS(dsp)) + sb_ess_update_irq_drq_readback_regs(dsp, true); } void @@ -1683,7 +1686,7 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; - case SB_SUBTYPE_ESS_ES688: + case SB_SUBTYPE_ESS_ES688: sb_add_data(dsp, 0x68); sb_add_data(dsp, 0x80 | 0x04); break; From 29ac8fd28b44b63d2d552f0d4ad4f4431ef2f13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Wed, 22 May 2024 15:46:53 +0200 Subject: [PATCH 537/690] Fixed line feed in prt_escp.c Per fix by Patrick-Barry, fixes #4477. --- src/printer/prt_escp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 8247ecfab..d91a52e0c 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1475,7 +1475,7 @@ process_char(escp_t *dev, uint8_t ch) } dev->curr_x = dev->left_margin; dev->curr_y += dev->linespacing; - if (dev->curr_y > dev->bottom_margin) + if ((dev->curr_y + 0.0001f) > dev->bottom_margin) new_page(dev, 1, 0); return 1; From d23c2a613df47d68d9ec3988f4eaf4c804501b6e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 00:10:04 +0200 Subject: [PATCH 538/690] 286/386 interpreter: reinstall VM_FLAG check on accessin the debug registers. --- src/cpu/x86_ops_mov_ctrl_2386.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index cae6c9957..6bb00d8da 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -82,7 +82,7 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if ((CPL > 0) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -124,7 +124,7 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if ((CPL > 0) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -282,7 +282,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if ((CPL > 0) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -325,7 +325,7 @@ opMOV_DRx_r_a16(uint32_t fetchdat) static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if ((CPL > 0) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } From a07ffdecab9ecc742d508b76548dc5c43c218ee0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 15 Jan 2024 06:22:38 +0500 Subject: [PATCH 539/690] Restore the debug register operation on 486+ But put it behind a compile-time option due to performance hits Also add the DE flag to CPUID on supported CPUs --- CMakeLists.txt | 1 + src/CMakeLists.txt | 4 + src/cpu/386_common.h | 109 +++++++++++++++++++++++++++ src/cpu/386_dynarec.c | 68 ++++++++++++++++- src/cpu/386_dynarec_ops.c | 1 + src/cpu/cpu.c | 52 +++++++------ src/cpu/x86.c | 4 + src/cpu/x86_ops_flag.h | 12 +++ src/cpu/x86_ops_mov_ctrl.h | 147 +++++++++++++++++++++++++++++++++++-- src/cpu/x86_ops_ret.h | 12 +++ src/io.c | 76 +++++++++++++++++++ src/mem/mem.c | 82 +++++++++++++++++++-- 12 files changed, 531 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0066e04a..fa1d02a15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ option(MINITRACE "Enable Chrome tracing using the modified minitrace library" option(GDBSTUB "Enable GDB stub server for debugging" OFF) option(DEV_BRANCH "Development branch" OFF) option(DISCORD "Discord Rich Presence support" ON) +option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) if(WIN32) set(QT ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6cfaef89c..66fe70821 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,10 @@ if(DISCORD) target_sources(86Box PRIVATE discord.c) endif() +if(DEBUGREGS486) + add_compile_definitions(USE_DEBUG_REGS_486) +endif() + if(VNC) find_package(LibVNCServer) if(LibVNCServer_FOUND) diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index a98a3e930..6ef65771d 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -49,6 +49,82 @@ # define do_mmut_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1) # define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1) # define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1) +#elif defined(USE_DEBUG_REGS_486) +# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) + +# define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7) || (dr[7] & 0xFF)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v + +# define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 4, 0) +# define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 4, 0) + +# define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 1, 1) +# define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 2, 1) +# define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + do_mmutranslate((s) + (a), b, 4, 1) #else # define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) # define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) @@ -263,6 +339,11 @@ fastreadb(uint32_t a) { uint8_t *t; +# ifdef USE_DEBUG_REGS_486 + read_type = 1; + mem_debug_check_addr(a, read_type); + read_type = 4; +# endif if ((a >> 12) == pccache) # if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); @@ -286,6 +367,12 @@ fastreadw(uint32_t a) { uint8_t *t; uint16_t val; +# ifdef USE_DEBUG_REGS_486 + read_type = 1; + mem_debug_check_addr(a, read_type); + mem_debug_check_addr(a + 1, read_type); + read_type = 4; +# endif if ((a & 0xFFF) > 0xFFE) { val = fastreadb(a); val |= (fastreadb(a + 1) << 8); @@ -315,6 +402,14 @@ fastreadl(uint32_t a) { uint8_t *t; uint32_t val; +# ifdef USE_DEBUG_REGS_486 + int i; + read_type = 1; + for (i = 0; i < 4; i++) { + mem_debug_check_addr(a + i, read_type); + } + read_type = 4; +# endif if ((a & 0xFFF) < 0xFFD) { if ((a >> 12) != pccache) { t = getpccache(a); @@ -402,6 +497,12 @@ fastreadw_fetch(uint32_t a) { uint8_t *t; uint16_t val; +# ifdef USE_DEBUG_REGS_486 + read_type = 1; + mem_debug_check_addr(a, read_type); + mem_debug_check_addr(a + 1, read_type); + read_type = 4; +# endif if ((a & 0xFFF) > 0xFFE) { val = fastreadb(a); if (opcode_length[val & 0xff] > 1) @@ -432,6 +533,14 @@ fastreadl_fetch(uint32_t a) { uint8_t *t; uint32_t val; +# ifdef USE_DEBUG_REGS_486 + int i; + read_type = 1; + for (i = 0; i < 4; i++) { + mem_debug_check_addr(a + i, read_type); + } + read_type = 4; +# endif if ((a & 0xFFF) < 0xFFD) { if ((a >> 12) != pccache) { t = getpccache(a); diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index c96e3420d..77914a2a5 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -28,6 +28,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> +#include <86box/plat_fallthrough.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC # include "codegen.h" @@ -224,7 +225,11 @@ fetch_ea_16_long(uint32_t rmdat) #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) +#ifdef USE_DEBUG_REGS_486 +# define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG) && !(dr[7] & 0xFF)) +#else +# define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) +#endif #ifdef USE_DYNAREC int32_t cycles_main = 0; @@ -269,7 +274,11 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; +# ifdef USE_DEBUG_REGS_486 + if (trap & 2) { +# else if (trap == 2) { +# endif /* Handle the T bit in the new TSS first. */ CPU_BLOCK_END(); goto block_ended; @@ -286,6 +295,13 @@ exec386_dynarec_int(void) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; +# ifdef USE_DEBUG_REGS_486 + if (UNLIKELY(cpu_386_check_instruction_fault())) { + x86gen(); + goto block_ended; + } +# endif + fetchdat = fastreadl_fetch(cs + cpu_state.pc); # ifdef ENABLE_386_DYNAREC_LOG if (in_smm) @@ -296,9 +312,16 @@ exec386_dynarec_int(void) opcode = fetchdat & 0xFF; fetchdat >>= 8; +# ifdef USE_DEBUG_REGS_486 + trap |= !!(cpu_state.flags & T_FLAG); +# else trap = cpu_state.flags & T_FLAG; +# endif cpu_state.pc++; +# ifdef USE_DEBUG_REGS_486 + cpu_state.eflags &= ~(RF_FLAG); +# endif x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); } @@ -307,6 +330,16 @@ exec386_dynarec_int(void) cpu_state.pc &= 0xffff; # endif +# ifdef USE_DEBUG_REGS_486 + if (!cpu_state.abrt) { + if (!rf_flag_no_clear) { + cpu_state.eflags &= ~RF_FLAG; + } + + rf_flag_no_clear = 0; + } +# endif + if (((cs + cpu_state.pc) >> 12) != pccache) CPU_BLOCK_END(); @@ -330,7 +363,14 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && trap) { +# ifdef USE_DEBUG_REGS_486 + //pclog("Debug trap 0x%X\n", trap); + if (trap & 2) dr[6] |= 0x8000; + if (trap & 1) dr[6] |= 0x4000; +# else dr[6] |= (trap == 2) ? 0x8000 : 0x4000; +# endif + trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -842,6 +882,13 @@ exec386(int32_t cycs) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; +#ifdef USE_DEBUG_REGS_486 + if (UNLIKELY(cpu_386_check_instruction_fault())) { + x86gen(); + goto block_ended; + } +#endif + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (!cpu_state.abrt) { @@ -851,9 +898,16 @@ exec386(int32_t cycs) #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; +#ifdef USE_DEBUG_REGS_486 + trap |= !!(cpu_state.flags & T_FLAG); +#else trap = cpu_state.flags & T_FLAG; +#endif cpu_state.pc++; +#ifdef USE_DEBUG_REGS_486 + cpu_state.eflags &= ~(RF_FLAG); +#endif x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); if (x86_was_reset) break; @@ -871,6 +925,9 @@ exec386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; +#ifdef USE_DEBUG_REGS_486 +block_ended: +#endif if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -895,12 +952,21 @@ exec386(int32_t cycs) } } else if (trap) { flags_rebuild(); +#ifdef USE_DEBUG_REGS_486 + if (trap & 1) + dr[6] |= 0x4000; + if (trap & 2) + dr[6] |= 0x8000; +#endif + trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; +#ifndef USE_DEBUG_REGS_486 dr[6] |= 0x4000; +#endif x86_int(1); } diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 77b72ef59..066b00dd6 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -24,6 +24,7 @@ #include <86box/gdbstub.h> #include "codegen.h" #include <86box/plat_unused.h> +#include <86box/plat_fallthrough.h> #define CPU_BLOCK_END() cpu_block_end = 1 diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 0f83a5e4b..b812a24f9 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -81,6 +81,12 @@ enum { #define CPUID_3DNOWE (1UL << 30UL) /* Extended 3DNow! instructions */ #define CPUID_3DNOW (1UL << 31UL) /* 3DNow! instructions */ +/* Remove the Debugging Extensions CPUID flag if not compiled + with debug register support for 486 and later CPUs. */ +#ifndef USE_DEBUG_REGS_486 +# define CPUID_DE 0 +#endif + /* Make sure this is as low as possible. */ cpu_state_t cpu_state; fpu_state_t fpu_state; @@ -1973,7 +1979,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) @@ -1999,7 +2005,7 @@ cpu_CPUID(void) case 1: EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) @@ -2010,7 +2016,7 @@ cpu_CPUID(void) break; case 0x80000001: EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) @@ -2048,7 +2054,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; if (cpu_s->cpu_type != CPU_P24T) EDX |= CPUID_MCE; } else @@ -2065,7 +2071,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE; } else EAX = EBX = ECX = EDX = 0; break; @@ -2081,7 +2087,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; break; case 0x80000000: EAX = 0x80000005; @@ -2090,7 +2096,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; break; case 0x80000002: /* Processor name string */ EAX = 0x2D444D41; /* AMD-K5(tm) Proce */ @@ -2126,7 +2132,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000005; @@ -2135,7 +2141,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; break; case 0x80000002: /* Processor name string */ EAX = 0x2D444D41; /* AMD-K6tm w/ mult */ @@ -2183,7 +2189,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; if (cpu_s->cpu_type == CPU_K6_2C) EDX |= CPUID_PGE; break; @@ -2194,7 +2200,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW; if (cpu_s->cpu_type == CPU_K6_2C) EDX |= CPUID_PGE; break; @@ -2233,7 +2239,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; @@ -2242,7 +2248,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -2284,7 +2290,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; @@ -2293,7 +2299,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ @@ -2339,7 +2345,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = EBX = ECX = EDX = 0; break; @@ -2382,7 +2388,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else EAX = EBX = ECX = EDX = 0; break; @@ -2396,7 +2402,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; } else EAX = EBX = ECX = EDX = 0; break; @@ -2411,7 +2417,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries @@ -2434,7 +2440,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries @@ -2457,7 +2463,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries @@ -2496,7 +2502,7 @@ cpu_CPUID(void) case 1: EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 7)) @@ -2507,7 +2513,7 @@ cpu_CPUID(void) break; case 0x80000001: EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 7)) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index cf2867182..32b274f06 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -279,7 +279,11 @@ reset_common(int hard) cr4 = 0; cpu_state.eflags = 0; cgate32 = 0; +#ifdef USE_DEBUG_REGS_486 + if (is386) { +#else if (is386 && !is486) { +#endif for (uint8_t i = 0; i < 4; i++) dr[i] = 0x00000000; dr[6] = 0xffff1ff0; diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index f08b30fce..019472aa0 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -178,6 +178,9 @@ opPOPF_186(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -211,6 +214,9 @@ opPOPF_286(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -264,6 +270,9 @@ opPOPF(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; } flags_extract(); +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -307,6 +316,9 @@ opPOPFD(uint32_t fetchdat) cpu_state.eflags = (templ >> 16) & 3; flags_extract(); +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index b0c841f83..5d6e44e34 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -82,12 +82,43 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } +#ifdef USE_DEBUG_REGS_486 + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } +#endif fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; + } CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); return 0; @@ -95,12 +126,43 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } +#ifdef USE_DEBUG_REGS_486 + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } +#endif fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; + } CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); return 0; @@ -224,27 +286,96 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } +#ifdef USE_DEBUG_REGS_486 + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + x86gen(); + return 1; + } +#endif fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; + } CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); +#ifdef USE_DEBUG_REGS_486 + CPU_BLOCK_END(); +#endif return 0; } static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } +#ifdef USE_DEBUG_REGS_486 + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } +#endif fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; + } CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); +#ifdef USE_DEBUG_REGS_486 + CPU_BLOCK_END(); +#endif return 0; } diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 0d9a6370b..d30d4eb8f 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -135,6 +135,9 @@ opIRET_186(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -175,6 +178,9 @@ opIRET_286(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -243,6 +249,9 @@ opIRET(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -285,6 +294,9 @@ opIRETD(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; +#ifdef USE_DEBUG_REGS_486 + rf_flag_no_clear = 1; +#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); diff --git a/src/io.c b/src/io.c index 0e68049c3..fd87089d0 100644 --- a/src/io.c +++ b/src/io.c @@ -279,6 +279,58 @@ io_handler_interleaved(int set, uint16_t base, int size, io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2); } +#ifdef USE_DEBUG_REGS_486 +extern int trap; +/* Set trap for I/O address breakpoints. */ +void +io_debug_check_addr(uint16_t addr) +{ + int i = 0; + int set_trap = 0; + + if (!(dr[7] & 0xFF)) + return; + + if (!(cr4 & 0x8)) + return; /* No I/O debug trap. */ + + for (i = 0; i < 4; i++) { + uint16_t dr_addr = dr[i] & 0xFFFF; + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); + int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); + if (!breakpoint_enabled) + continue; + if ((len_type_pair & 3) != 2) + continue; + + switch ((len_type_pair >> 2) & 3) + { + case 0x00: + if (dr_addr == addr) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x01: + if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x03: + dr_addr &= ~3; + if (addr >= dr_addr && addr < (dr_addr + 4)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + } + } + if (set_trap) + trap |= 4; +} +#endif + uint8_t inb(uint16_t port) { @@ -290,6 +342,10 @@ inb(uint16_t port) int qfound = 0; #endif +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_read(port, NULL); found = 1; @@ -350,6 +406,10 @@ outb(uint16_t port, uint8_t val) int qfound = 0; #endif +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_write(port, val, NULL); found = 1; @@ -402,6 +462,10 @@ inw(uint16_t port) #endif uint8_t ret8[2]; +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readw(port, NULL); found = 2; @@ -474,6 +538,10 @@ outw(uint16_t port, uint16_t val) int qfound = 0; #endif +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writew(port, val, NULL); found = 2; @@ -542,6 +610,10 @@ inl(uint16_t port) int qfound = 0; #endif +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readl(port, NULL); found = 4; @@ -646,6 +718,10 @@ outl(uint16_t port, uint32_t val) #endif int i = 0; +#ifdef USE_DEBUG_REGS_486 + io_debug_check_addr(port); +#endif + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writel(port, val, NULL); found = 4; diff --git a/src/mem/mem.c b/src/mem/mem.c index 1d373dafb..be097b5f3 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -164,6 +164,46 @@ mem_log(const char *fmt, ...) # define mem_log(fmt, ...) #endif +#ifdef USE_DEBUG_REGS_486 +/* As below, 1 = exec, 4 = read. */ +int read_type = 4; + +/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */ +void +mem_debug_check_addr(uint32_t addr, int flags) +{ + uint32_t bp_addr; + uint32_t bp_mask; + uint32_t len_type_pair; + int bp_enabled; + uint8_t match_flags[4] = { 0, 2, 0, 6 }; + + if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) + return; + + if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) { + bp_addr = dr[i]; + bp_enabled = (dr[7] >> (i << 1)) & 0x03; + len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f; + bp_mask = ~((len_type_pair >> 2) & 0x03); + + if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) { + /* + From the Intel i386 documemntation: + + (Note that the processor sets Bn regardless of whether Gn or + Ln is set. If more than one breakpoint condition occurs at one time and if + the breakpoint trap occurs due to an enabled condition other than n, Bn may + be set, even though neither Gn nor Ln is set.) + */ + dr[6] |= (1 << i); + if (bp_enabled) + trap |= (read_type == 1) ? 8 : 4; + } + } +} +#endif + int mem_addr_is_ram(uint32_t addr) { @@ -793,6 +833,9 @@ readmembl(uint32_t addr) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr, read_type); +#endif addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -822,6 +865,9 @@ writemembl(uint32_t addr, uint8_t val) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr, 2); +#endif addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -908,6 +954,10 @@ readmemwl(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr, read_type); + mem_debug_check_addr(addr + 1, read_type); +#endif GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -966,6 +1016,10 @@ writememwl(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr, 2); + mem_debug_check_addr(addr + 1, 2); +#endif GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -1142,8 +1196,12 @@ readmemll(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr + i, read_type); +#endif + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; @@ -1216,8 +1274,12 @@ writememll(uint32_t addr, uint32_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr + i, 2); +#endif + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; @@ -1420,8 +1482,12 @@ readmemql(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr + i, read_type); +#endif + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); mem_logical_addr = addr; @@ -1486,8 +1552,12 @@ writememql(uint32_t addr, uint64_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr + i, 2); +#endif + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); mem_logical_addr = addr; @@ -1584,7 +1654,9 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) int cond = 1; uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - +#ifdef USE_DEBUG_REGS_486 + mem_debug_check_addr(addr, write ? 2 : read_type); +#endif for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; From 0a9d71a42b48997ff9b63f847bcff3d2ce1ba1ca Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 03:58:37 +0200 Subject: [PATCH 540/690] Correct the NVR mask of the two Compaq Presario's, fixes crashes with the 2240. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 18bcc5a82..4cc5c5736 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11576,7 +11576,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11616,7 +11616,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, From 5ff67132a6530bfed1086bfa8b5c280dea9af1b9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 10:14:41 +0200 Subject: [PATCH 541/690] PCI: Add mechanism for internally wired IRQ routings. --- src/include/86box/pci.h | 9 +++++++++ src/pci.c | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 8483eb417..d2348ba02 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -115,6 +115,11 @@ /* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */ #define PCI_MIRQS_NUM 8 #define PCI_MIRQ_MAX (PCI_MIRQS_NUM - 1) +/* The base for internal IRQ lines accepted by pci_irq(). */ +#define PCI_IIRQ_BASE 0x80 +/* PCI direct IRQ lines - always at 4 per the PCI specification. */ +#define PCI_IIRQS_NUM 4 +#define PCI_IIRQ_MAX (PCI_IIRQS_NUM - 1) /* The base for direct IRQ lines accepted by pci_irq(). */ #define PCI_DIRQ_BASE 0xf0 /* PCI direct IRQ lines (currently 16 because we only emulate the legacy PIC). */ @@ -148,12 +153,16 @@ #define pci_set_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 1, irq_state) +#define pci_set_iirq(pci_int, irq_state) \ + pci_irq(PCI_IIRQ_BASE | 0, pci_int, 0, 1, irq_state) #define pci_set_dirq(irq, irq_state) \ pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 1, irq_state) #define pci_set_irq(slot, pci_int, irq_state) \ pci_irq(slot, pci_int, 0, 1, irq_state) #define pci_clear_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 0, irq_state) +#define pci_clear_iirq(pci_int, irq_state) \ + pci_irq(PCI_IIRQ_BASE | 0, pci_int, 0, 0, irq_state) #define pci_clear_dirq(dirq, irq_state) \ pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 0, irq_state) #define pci_clear_irq(slot, pci_int, irq_state) \ diff --git a/src/pci.c b/src/pci.c index 13b780050..266be4396 100644 --- a/src/pci.c +++ b/src/pci.c @@ -204,6 +204,19 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) } } break; + case (PCI_IIRQ_BASE | 0x00) ... (PCI_IIRQ_BASE | PCI_IIRQ_MAX): + /* PCI internal routing. */ + if (!last_pci_card || (pci_flags & FLAG_NO_IRQ_STEERING)) + return; + + irq_routing = (pci_int_index - PCI_INTA) & PCI_IRQ_MAX; + + irq_line = pci_irqs[irq_routing]; + + /* Ignore what was provided to us as a parameter and override it with whatever + the chipset is set to. */ + level = !!pci_irq_level[irq_routing]; + break; case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): /* MIRQ */ slot &= PCI_MIRQ_MAX; From 07f71aab05740e826e1f6efd59833c6ae538c8e0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 10:37:59 +0200 Subject: [PATCH 542/690] PCI: Fix a bug in the internal IRQ mechanism. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index 266be4396..6fb84010d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -209,7 +209,7 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) if (!last_pci_card || (pci_flags & FLAG_NO_IRQ_STEERING)) return; - irq_routing = (pci_int_index - PCI_INTA) & PCI_IRQ_MAX; + irq_routing = (pci_int_index - PCI_IIRQ_BASE) & PCI_IRQ_MAX; irq_line = pci_irqs[irq_routing]; From b97cbceb0743881208ca222c2a79ea12ee395c4e Mon Sep 17 00:00:00 2001 From: usergithub64 <58270614+usergithub64@users.noreply.github.com> Date: Fri, 24 May 2024 11:50:01 +0300 Subject: [PATCH 543/690] Fixes for translation not working in the main window Also need to add the appropriate translation strings to the language files --- src/qt/qt_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index dc8e1970f..87b86f8e9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -223,8 +223,8 @@ main(int argc, char *argv[]) if(!util::compareUuid()) { QMessageBox movewarnbox; movewarnbox.setIcon(QMessageBox::Icon::Warning); - movewarnbox.setText("This machine might have been moved or copied."); - movewarnbox.setInformativeText("In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure."); + movewarnbox.setText(QObject::tr("This machine might have been moved or copied.")); + movewarnbox.setInformativeText(QObject::tr("In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure.")); const QPushButton *movedButton = movewarnbox.addButton(QObject::tr("I Moved It"), QMessageBox::AcceptRole); const QPushButton *copiedButton = movewarnbox.addButton(QObject::tr("I Copied It"), QMessageBox::DestructiveRole); QPushButton *cancelButton = movewarnbox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole); From 8ced9eba653f2f5e6d7bf641f91abb42aae923fa Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 11:01:58 +0200 Subject: [PATCH 544/690] PCI: More fixes to the internal IRQ mechanism. --- src/include/86box/pci.h | 5 +++-- src/pci.c | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index d2348ba02..097fcf502 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -110,6 +110,7 @@ #define PCI_CARD_MAX (PCI_CARDS_NUM - 1) /* The number of PCI card INT pins - always at 4 per the PCI specification. */ #define PCI_INT_PINS_NUM 4 +#define PCI_INT_PINS_MAX (PCI_INT_PINS_NUM - 1) /* The base for MIRQ lines accepted by pci_irq(). */ #define PCI_MIRQ_BASE PCI_CARDS_NUM /* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */ @@ -154,7 +155,7 @@ #define pci_set_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 1, irq_state) #define pci_set_iirq(pci_int, irq_state) \ - pci_irq(PCI_IIRQ_BASE | 0, pci_int, 0, 1, irq_state) + pci_irq(PCI_IIRQ_BASE | (pci_int), 0, 0, 1, irq_state) #define pci_set_dirq(irq, irq_state) \ pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 1, irq_state) #define pci_set_irq(slot, pci_int, irq_state) \ @@ -162,7 +163,7 @@ #define pci_clear_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 0, irq_state) #define pci_clear_iirq(pci_int, irq_state) \ - pci_irq(PCI_IIRQ_BASE | 0, pci_int, 0, 0, irq_state) + pci_irq(PCI_IIRQ_BASE | (pci_int), 0, 0, 0, irq_state) #define pci_clear_dirq(dirq, irq_state) \ pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 0, irq_state) #define pci_clear_irq(slot, pci_int, irq_state) \ diff --git a/src/pci.c b/src/pci.c index 6fb84010d..3468d7949 100644 --- a/src/pci.c +++ b/src/pci.c @@ -206,16 +206,13 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) break; case (PCI_IIRQ_BASE | 0x00) ... (PCI_IIRQ_BASE | PCI_IIRQ_MAX): /* PCI internal routing. */ - if (!last_pci_card || (pci_flags & FLAG_NO_IRQ_STEERING)) - return; + slot = (slot - 1) & PCI_INT_PINS_MAX; - irq_routing = (pci_int_index - PCI_IIRQ_BASE) & PCI_IRQ_MAX; - - irq_line = pci_irqs[irq_routing]; + irq_line = pci_irqs[slot]; /* Ignore what was provided to us as a parameter and override it with whatever the chipset is set to. */ - level = !!pci_irq_level[irq_routing]; + level = !!pci_irq_level[slot]; break; case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): /* MIRQ */ From b0dc74dbb8c8cc36335291e9616f8115ea5680bb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 11:05:27 +0200 Subject: [PATCH 545/690] PCI: And make it correctly handle all 4 PIRQ's and zero PIRQ (in which case, do nothing at all). --- src/pci.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pci.c b/src/pci.c index 3468d7949..786573179 100644 --- a/src/pci.c +++ b/src/pci.c @@ -204,15 +204,20 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) } } break; - case (PCI_IIRQ_BASE | 0x00) ... (PCI_IIRQ_BASE | PCI_IIRQ_MAX): + case (PCI_IIRQ_BASE | 0x00) ... (PCI_IIRQ_BASE | PCI_IIRQS_NUM): /* PCI internal routing. */ - slot = (slot - 1) & PCI_INT_PINS_MAX; + if (slot > 0x00) { + slot = (slot - 1) & PCI_INT_PINS_MAX; - irq_line = pci_irqs[slot]; + irq_line = pci_irqs[slot]; - /* Ignore what was provided to us as a parameter and override it with whatever - the chipset is set to. */ - level = !!pci_irq_level[slot]; + /* Ignore what was provided to us as a parameter and override it with whatever + the chipset is set to. */ + level = !!pci_irq_level[slot]; + } else { + irq_line = 0xff; + level = 0; + } break; case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): /* MIRQ */ From beddf47de81a0d84c523716e1d4e265fa98ca8b2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 May 2024 19:10:13 +0200 Subject: [PATCH 546/690] Fixed the Super I/O chip and keyboard controller firmware identifications for all the boards that use the SM(S)C FDC73C93x family of Super I/O chips and corrected the socket of the Dell Hannibal+. --- src/include/86box/machine.h | 2 +- src/machine/m_at_socket7.c | 33 ++++ src/machine/m_at_socket7_3v.c | 33 ---- src/machine/machine_table.c | 333 ++++++++++++++++++---------------- 4 files changed, 206 insertions(+), 195 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c0d60c221..a5b922358 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -673,7 +673,6 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); -extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -702,6 +701,7 @@ extern int machine_at_5ivg_init(const machine_t *); extern int machine_at_8500tvxa_init(const machine_t *); extern int machine_at_presario2240_init(const machine_t *); extern int machine_at_presario4500_init(const machine_t *); +extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_p55va_init(const machine_t *); extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_pb680_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 9e2ed9a26..49ad043e8 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -607,6 +607,39 @@ machine_at_presario4500_init(const machine_t *model) return ret; } +int +machine_at_dellhannibalp_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO", + "roms/machines/dellhannibalp/1003DY0J.BI1", + "roms/machines/dellhannibalp/1003DY0J.BI2", + "roms/machines/dellhannibalp/1003DY0J.BI3", + "roms/machines/dellhannibalp/1003DY0J.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_p55va_init(const machine_t *model) { diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index b1a9515f3..380e56e41 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -670,39 +670,6 @@ machine_at_p5vxb_init(const machine_t *model) return ret; } -int -machine_at_dellhannibalp_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO", - "roms/machines/dellhannibalp/1003DY0J.BI1", - "roms/machines/dellhannibalp/1003DY0J.BI2", - "roms/machines/dellhannibalp/1003DY0J.BI3", - "roms/machines/dellhannibalp/1003DY0J.RCV", - 0x3a000, 128); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&fdc37c932fr_device); - device_add(&intel_flash_bxt_ami_device); - - return ret; -} - int machine_at_gw2kte_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4cc5c5736..4b91f1668 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8495,7 +8495,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 2.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, @@ -10155,8 +10155,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS does not send a single non-standard KBC command, but the board has a SMC Super I/O - chip with on-chip KBC and AMI MegaKey KBC firmware. */ + /* Has a SM(S)C FDC37C932 Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ { .name = "[i430FX] HP Vectra VL 5 Series 4", .internal_name = "vectra54", @@ -10177,7 +10177,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 2.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -10485,7 +10485,8 @@ const machine_t machines[] = { }, /* 430HX */ - /* Has a Phoenix Multikey KBC in the SM(S)C SIO. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430HX] Acer M3A", .internal_name = "acerm3a", @@ -10506,7 +10507,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 8192, @@ -10586,7 +10587,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -10627,7 +10628,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -10648,48 +10649,6 @@ const machine_t machines[] = { }, /* 430VX */ - /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the - PC87306 Super I/O chip, command 0xA1 returns '5'. - Command 0xA0 copyright string: (C)1994 AMI . */ - { - .name = "[i430VX] Dell Hannibal+", - .internal_name = "dellhannibalp", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_dellhannibalp_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[i430VX] ECS P5VX-B", @@ -10711,7 +10670,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -10730,9 +10689,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the - PC87306 Super I/O chip, command 0xA1 returns '5'. - Command 0xA0 copyright string: (C)1994 AMI . */ + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ { .name = "[i430VX] Gateway 2000 Tigereye", .internal_name = "gw2kte", @@ -10753,7 +10711,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -10979,7 +10937,9 @@ const machine_t machines[] = { /* Socket 7 (Dual Voltage) machines */ /* 430HX */ - /* Has SST flash and the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ + /* Has SST Flash. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430HX] Acer V35N", .internal_name = "acerv35n", @@ -11059,7 +11019,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430HX] Micronics M7S-Hi", .internal_name = "m7shi", @@ -11080,7 +11041,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -11122,7 +11083,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, @@ -11162,7 +11123,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, @@ -11202,7 +11163,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11242,7 +11203,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11325,7 +11286,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11407,7 +11368,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11447,7 +11408,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11488,7 +11449,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11528,7 +11489,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11547,8 +11508,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS does not send a single non-standard KBC command, but the board has a SMC Super I/O - chip with on-chip KBC and AMI MegaKey KBC firmware. */ + /* Has a SM(S)C FDC37C932QF Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ { .name = "[i430VX] Compaq Presario 2240", .internal_name = "presario2240", @@ -11588,7 +11549,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This most likely has AMI MegaKey as above. */ + /* Has a SM(S)C FDC37C931APM Super I/O chip with on-chip KBC with Compaq + KBC firmware. */ { .name = "[i430VX] Compaq Presario 4500", .internal_name = "presario4500", @@ -11628,7 +11590,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS sends KBC command CB which is an AMI KBC command, so it has an AMI KBC firmware. */ + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Dell Hannibal+", + .internal_name = "dellhannibalp", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_dellhannibalp_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ { .name = "[i430VX] Epox P55-VA", .internal_name = "p55va", @@ -11649,7 +11653,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11668,7 +11672,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS does not send a single non-standard KBC command. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430VX] HP Brio 80xx", .internal_name = "brio80xx", @@ -11731,7 +11736,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11750,7 +11755,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This machine has Phoenix MultiKey/42i KBC */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430VX] Packard Bell PB810", .internal_name = "pb810", @@ -11812,7 +11818,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11853,7 +11859,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -11935,7 +11941,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -11975,7 +11981,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC | MACHINE_USB, .ram = { .min = 8192, @@ -12057,7 +12063,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12077,6 +12083,8 @@ const machine_t machines[] = { .net_device = NULL }, /* PhoenixBIOS 4.0 Rel 6.0 for 430TX, most likely has AMI KBC of some sort. Also has onboard Yamaha YMF701 which can't be emulated yet. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i430TX] Micronics Thunderbolt", .internal_name = "thunderbolt", @@ -12097,7 +12105,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, @@ -12138,7 +12146,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12179,7 +12187,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12219,7 +12227,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12259,7 +12267,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12299,7 +12307,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12342,7 +12350,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12385,7 +12393,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12427,7 +12435,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -12467,7 +12475,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -12507,7 +12515,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -12549,7 +12557,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12589,7 +12597,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12631,7 +12639,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12673,7 +12681,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12713,7 +12721,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12756,7 +12764,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -12797,7 +12805,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, @@ -12837,7 +12845,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCIONLY, + .bus_flags = MACHINE_PS2_PCIONLY | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ .ram = { .min = 8192, @@ -12877,7 +12885,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, @@ -12917,7 +12925,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, @@ -12960,7 +12968,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13001,7 +13009,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13042,7 +13050,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_A97, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -13083,7 +13091,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13125,7 +13133,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13229,7 +13237,8 @@ const machine_t machines[] = { }, /* 440FX */ - /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i440FX] Acer V60N", .internal_name = "acerv60n", @@ -13250,7 +13259,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13290,7 +13299,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13330,7 +13339,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13370,7 +13379,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 3.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -13410,7 +13419,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13452,7 +13461,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 3.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, @@ -13494,7 +13503,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 3.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -13534,7 +13543,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-78xx */ .ram = { .min = 40960, @@ -13553,7 +13562,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i440FX] Micronics M6Mi", .internal_name = "m6mi", @@ -13574,7 +13584,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -13614,7 +13624,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13657,7 +13667,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ .ram = { .min = 1024, @@ -13699,7 +13709,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13740,7 +13750,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, @@ -13783,7 +13793,7 @@ const machine_t machines[] = { .min_multi = 2.0, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13803,7 +13813,7 @@ const machine_t machines[] = { .net_device = NULL }, /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey KBC firmware. */ + MultiKey/42 (version 1.38) KBC firmware. */ { .name = "[i440LX] Micronics Spitfire", .internal_name = "spitfire", @@ -13824,7 +13834,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13865,7 +13875,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13908,7 +13918,7 @@ const machine_t machines[] = { .min_multi = 3.0, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -13951,7 +13961,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7890AB */ .ram = { .min = 8192, @@ -13992,7 +14002,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14033,7 +14043,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14074,7 +14084,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14115,7 +14125,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14156,7 +14166,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: Matrox MGA-G200 and sound: Crystal CS4820 */ .ram = { .min = 8192, @@ -14196,7 +14206,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14237,7 +14247,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, @@ -14278,7 +14288,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14321,7 +14331,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14362,7 +14372,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14405,7 +14415,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14448,7 +14458,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS ES1938S */ .ram = { .min = 8192, @@ -14489,7 +14499,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14530,7 +14540,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14571,7 +14581,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, @@ -14613,7 +14623,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, @@ -14653,7 +14663,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -14697,7 +14707,7 @@ const machine_t machines[] = { .min_multi = 3.0, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_NOISA, + .bus_flags = MACHINE_PS2_NOISA | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, @@ -14741,7 +14751,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14783,7 +14793,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14827,7 +14837,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 16384, @@ -14868,7 +14878,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, @@ -14912,7 +14922,7 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED, }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -14955,7 +14965,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 /* limits assumed */ }, - .bus_flags = MACHINE_PS2_PCI, /* Machine has EISA, possibly for a riser? */ + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has EISA, possibly for a riser? */ + /* Yes, that's a rise slot, not EISA. */ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB | MACHINE_VIDEO, /* Machine has internal video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ .ram = { .min = 8192, @@ -14996,7 +15007,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has quad channel IDE with internal controller: CMD PCI-0648 */ .ram = { .min = 8192, @@ -15037,7 +15048,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 /* limits assumed */ }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -15080,7 +15091,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -15123,7 +15134,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -15164,7 +15175,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, @@ -15207,7 +15218,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -15248,7 +15259,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB | MACHINE_SOUND, .ram = { .min = 8192, @@ -15289,7 +15300,7 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_A97, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, @@ -15330,7 +15341,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_NOI97, /* Has Asus-proprietary LAN/SCSI slot */ + .bus_flags = MACHINE_PS2_NOI97 | MACHINE_BUS_USB, /* Has Asus-proprietary LAN/SCSI slot */ .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, @@ -15373,7 +15384,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, From a614e935fb5dd99f7157da9ff1db2896edb7c172 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 May 2024 02:00:19 +0200 Subject: [PATCH 547/690] Clean-ups in device.c/h and the _params() device add functions now work exactly as originally planned. --- src/device.c | 132 +++++++++++------------------- src/include/86box/device.h | 22 ++--- src/network/net_eeprom_nmc93cxx.c | 12 +-- src/network/net_rtl8139.c | 4 +- src/network/net_tulip.c | 4 +- 5 files changed, 63 insertions(+), 111 deletions(-) diff --git a/src/device.c b/src/device.c index 5e3b394c2..24042b83a 100644 --- a/src/device.c +++ b/src/device.c @@ -45,14 +45,11 @@ #include #include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/ini.h> #include <86box/config.h> #include <86box/device.h> -#include <86box/timer.h> -#include <86box/lpt.h> #include <86box/machine.h> #include <86box/mem.h> #include <86box/rom.h> @@ -94,9 +91,6 @@ device_init(void) void device_set_context(device_context_t *c, const device_t *dev, int inst) { - const void *sec; - void *single_sec; - memset(c, 0, sizeof(device_context_t)); c->dev = dev; c->instance = inst; @@ -106,8 +100,8 @@ device_set_context(device_context_t *c, const device_t *dev, int inst) /* If this is the first instance and a numbered section is not present, but a non-numbered section of the same name is, rename the non-numbered section to numbered. */ if (inst == 1) { - sec = config_find_section(c->name); - single_sec = config_find_section((char *) dev->name); + const void *sec = config_find_section(c->name); + void * single_sec = config_find_section((char *) dev->name); if ((sec == NULL) && (single_sec != NULL)) config_rename_section(single_sec, c->name); } @@ -141,10 +135,18 @@ device_context_restore(void) } static void * -device_add_common(const device_t *dev, const device_t *cd, void *p, void *params, int inst) +device_add_common(const device_t *dev, void *p, void *params, int inst) { - void *priv = NULL; - int c; + device_t *init_dev; + void *priv = NULL; + int c; + + if (params != NULL) { + init_dev = calloc(1, sizeof(device_t)); + memcpy(init_dev, dev, sizeof(device_t)); + init_dev->local |= (uintptr_t) params; + } else + init_dev = (device_t *) dev; for (c = 0; c < 256; c++) { if (!inst && (devices[c] == dev)) { @@ -154,7 +156,7 @@ device_add_common(const device_t *dev, const device_t *cd, void *p, void *params if (devices[c] == NULL) break; } - if ((c >= DEVICE_MAX) || (c >= 256)) { + if (c >= DEVICE_MAX) { fatal("DEVICE: too many devices\n"); return NULL; } @@ -167,33 +169,43 @@ device_add_common(const device_t *dev, const device_t *cd, void *p, void *params if (p == NULL) { memcpy(&device_prev, &device_current, sizeof(device_context_t)); - device_set_context(&device_current, cd, inst); + device_set_context(&device_current, dev, inst); if (dev->init != NULL) { - priv = (dev->flags & DEVICE_EXTPARAMS) ? dev->init_ext(dev, params) : dev->init(dev); + /* Give it our temporary device in case we have dynamically changed info->local. */ + priv = dev->init(init_dev); + if (priv == NULL) { +#ifdef ENABLE_DEVICE_LOG if (dev->name) device_log("DEVICE: device '%s' init failed\n", dev->name); else device_log("DEVICE: device init failed\n"); +#endif devices[c] = NULL; device_priv[c] = NULL; + free(init_dev); + return (NULL); } } +#ifdef ENABLE_DEVICE_LOG if (dev->name) device_log("DEVICE: device '%s' init successful\n", dev->name); else device_log("DEVICE: device init successful\n"); +#endif memcpy(&device_current, &device_prev, sizeof(device_context_t)); device_priv[c] = priv; } else device_priv[c] = p; + free(init_dev); + return priv; } @@ -209,7 +221,7 @@ device_get_internal_name(const device_t *dev) void * device_add(const device_t *dev) { - return device_add_common(dev, dev, NULL, NULL, 0); + return device_add_common(dev, NULL, NULL, 0); } void * @@ -217,105 +229,53 @@ device_add_linked(const device_t *dev, void *priv) { void *ret; device_common_priv = priv; - ret = device_add_common(dev, dev, NULL, NULL, 0); + ret = device_add_common(dev, NULL, NULL, 0); device_common_priv = NULL; return ret; } void * -device_add_parameters(const device_t *dev, void *params) +device_add_params(const device_t *dev, void *params) { - return device_add_common(dev, dev, NULL, params, 0); + return device_add_common(dev, NULL, params, 0); } /* For devices that do not have an init function (internal video etc.) */ void device_add_ex(const device_t *dev, void *priv) { - device_add_common(dev, dev, priv, NULL, 0); + device_add_common(dev, priv, NULL, 0); } void -device_add_ex_parameters(const device_t *dev, void *priv, void *params) +device_add_ex_params(const device_t *dev, void *priv, void *params) { - device_add_common(dev, dev, priv, params, 0); + device_add_common(dev, priv, params, 0); } void * device_add_inst(const device_t *dev, int inst) { - return device_add_common(dev, dev, NULL, NULL, inst); + return device_add_common(dev, NULL, NULL, inst); } void * -device_add_inst_parameters(const device_t *dev, int inst, void *params) +device_add_inst_params(const device_t *dev, int inst, void *params) { - return device_add_common(dev, dev, NULL, params, inst); + return device_add_common(dev, NULL, params, inst); } /* For devices that do not have an init function (internal video etc.) */ void device_add_inst_ex(const device_t *dev, void *priv, int inst) { - device_add_common(dev, dev, priv, NULL, inst); + device_add_common(dev, priv, NULL, inst); } void -device_add_inst_ex_parameters(const device_t *dev, void *priv, int inst, void *params) +device_add_inst_ex_params(const device_t *dev, void *priv, int inst, void *params) { - device_add_common(dev, dev, priv, params, inst); -} - -/* These eight are to add a device with another device's context - will be - used to add machines' internal devices. */ -void * -device_cadd(const device_t *dev, const device_t *cd) -{ - return device_add_common(dev, cd, NULL, NULL, 0); -} - -void * -device_cadd_parameters(const device_t *dev, const device_t *cd, void *params) -{ - return device_add_common(dev, cd, NULL, params, 0); -} - -/* For devices that do not have an init function (internal video etc.) */ -void -device_cadd_ex(const device_t *dev, const device_t *cd, void *priv) -{ - device_add_common(dev, cd, priv, NULL, 0); -} - -void -device_cadd_ex_parameters(const device_t *dev, const device_t *cd, void *priv, void *params) -{ - device_add_common(dev, cd, priv, params, 0); -} - -void * -device_cadd_inst(const device_t *dev, const device_t *cd, int inst) -{ - return device_add_common(dev, cd, NULL, NULL, inst); -} - -void * -device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params) -{ - return device_add_common(dev, cd, NULL, params, inst); -} - -/* For devices that do not have an init function (internal video etc.) */ -void -device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst) -{ - device_add_common(dev, cd, priv, NULL, inst); -} - -void -device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params) -{ - device_add_common(dev, cd, priv, params, inst); + device_add_common(dev, priv, params, inst); } void * @@ -329,8 +289,10 @@ device_close_all(void) { for (int16_t c = (DEVICE_MAX - 1); c >= 0; c--) { if (devices[c] != NULL) { +#ifdef ENABLE_DEVICE_LOG if (devices[c]->name) device_log("Closing device: \"%s\"...\n", devices[c]->name); +#endif if (devices[c]->close != NULL) devices[c]->close(device_priv[c]); devices[c] = device_priv[c] = NULL; @@ -388,21 +350,21 @@ device_get_priv(const device_t *dev) int device_available(const device_t *dev) { - const device_config_t *config = NULL; - const device_config_bios_t *bios = NULL; - int roms_present = 0; - int i = 0; + const device_config_t *config = NULL; + const device_config_bios_t *bios = NULL; if (dev != NULL) { config = dev->config; if (config != NULL) { while (config->type != -1) { if (config->type == CONFIG_BIOS) { + int roms_present = 0; + bios = (const device_config_bios_t *) config->bios; /* Go through the ROM's in the device configuration. */ while (bios->files_no != 0) { - i = 0; + int i = 0; for (int bf = 0; bf < bios->files_no; bf++) i += !!rom_present(bios->files[bf]); if (i == bios->files_no) @@ -615,7 +577,7 @@ device_force_redraw(void) } } -const int +int device_get_instance(void) { return device_current.instance; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index cc564ceb2..30ce1c093 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -102,9 +102,7 @@ enum { DEVICE_LPT = 0x200000, /* requires a parallel port */ DEVICE_KBC = 0x400000, /* is a keyboard controller */ - DEVICE_ONBOARD = 0x20000000, /* is on-board */ - DEVICE_EXTPARAMS = 0x40000000, /* accepts extended parameters */ - + DEVICE_ONBOARD = 0x40000000, /* is on-board */ DEVICE_PIT = 0x80000000, /* device is a PIT */ DEVICE_ALL = 0xffffffff /* match all devices */ @@ -204,21 +202,13 @@ extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); extern void *device_add(const device_t *d); extern void *device_add_linked(const device_t *d, void *priv); -extern void *device_add_parameters(const device_t *dev, void *params); +extern void *device_add_params(const device_t *dev, void *params); extern void device_add_ex(const device_t *dev, void *priv); -extern void device_add_ex_parameters(const device_t *dev, void *priv, void *params); +extern void device_add_ex_params(const device_t *dev, void *priv, void *params); extern void *device_add_inst(const device_t *dev, int inst); -extern void *device_add_inst_parameters(const device_t *dev, int inst, void *params); +extern void *device_add_inst_params(const device_t *dev, int inst, void *params); extern void device_add_inst_ex(const device_t *dev, void *priv, int inst); -extern void device_add_inst_ex_parameters(const device_t *dev, void *priv, int inst, void *params); -extern void *device_cadd(const device_t *dev, const device_t *cd); -extern void *device_cadd_parameters(const device_t *dev, const device_t *cd, void *params); -extern void device_cadd_ex(const device_t *dev, const device_t *cd, void *priv); -extern void device_cadd_ex_parameters(const device_t *dev, const device_t *cd, void *priv, void *params); -extern void *device_cadd_inst(const device_t *dev, const device_t *cd, int inst); -extern void *device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params); -extern void device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst); -extern void device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params); +extern void device_add_inst_ex_params(const device_t *dev, void *priv, int inst, void *params); extern void *device_get_common_priv(void); extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); @@ -246,7 +236,7 @@ extern void device_set_config_hex16(const char *s, int val); extern void device_set_config_hex20(const char *s, int val); extern void device_set_config_mac(const char *s, int val); extern const char *device_get_config_string(const char *name); -extern const int device_get_instance(void); +extern int device_get_instance(void); #define device_get_config_bios device_get_config_string extern const char *device_get_internal_name(const device_t *dev); diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c index 681263717..3ad6bd030 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/network/net_eeprom_nmc93cxx.c @@ -60,14 +60,14 @@ nmc93cxx_eeprom_log(int lvl, const char *fmt, ...) #endif static void * -nmc93cxx_eeprom_init_params(UNUSED(const device_t *info), void *params) +nmc93cxx_eeprom_init(const device_t *info) { uint16_t nwords = 64; uint8_t addrbits = 6; uint8_t filldefault = 1; - nmc93cxx_eeprom_params_t *params_details = (nmc93cxx_eeprom_params_t *) params; + nmc93cxx_eeprom_params_t *params_details = (nmc93cxx_eeprom_params_t *) info->local; nmc93cxx_eeprom_t *eeprom = NULL; - if (!params) + if (info->local == 0) return NULL; nwords = params_details->nwords; @@ -263,7 +263,7 @@ nmc93cxx_eeprom_close(void *priv) uint16_t * nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) { - if (UNLIKELY(!eeprom)) + if (UNLIKELY(eeprom == NULL)) return NULL; /* Get EEPROM data array. */ return &eeprom->dev.data[0]; @@ -272,9 +272,9 @@ nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) const device_t nmc93cxx_device = { .name = "National Semiconductor NMC93Cxx", .internal_name = "nmc93cxx", - .flags = DEVICE_EXTPARAMS, + .flags = 0, .local = 0, - .init_ext = nmc93cxx_eeprom_init_params, + .init = nmc93cxx_eeprom_init, .close = nmc93cxx_eeprom_close, .reset = NULL, { .available = NULL }, diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index a7c007115..2e85d67bf 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3283,8 +3283,8 @@ nic_init(const device_t *info) params.default_content = (uint16_t *) s->eeprom_data; params.filename = filename; snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); - s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); - if (!s->eeprom) { + s->eeprom = device_add_params(&nmc93cxx_device, ¶ms); + if (s->eeprom == NULL) { free(s); return NULL; } diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index e34327eb5..03eb21e88 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1613,8 +1613,8 @@ nic_init(const device_t *info) params.default_content = (uint16_t *) s->eeprom_data; params.filename = filename; snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); - s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); - if (!s->eeprom) { + s->eeprom = device_add_params(&nmc93cxx_device, ¶ms); + if (s->eeprom == NULL) { free(s); return NULL; } From 44a6e7c1b4e698ed2713b88833e961adb3029a03 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 May 2024 02:02:55 +0200 Subject: [PATCH 548/690] Device: Do not free init_dev if points to dev, fixes SIGTRAP. --- src/device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/device.c b/src/device.c index 24042b83a..8517045e2 100644 --- a/src/device.c +++ b/src/device.c @@ -137,8 +137,8 @@ device_context_restore(void) static void * device_add_common(const device_t *dev, void *p, void *params, int inst) { - device_t *init_dev; - void *priv = NULL; + device_t *init_dev = NULL; + void *priv = NULL; int c; if (params != NULL) { @@ -204,7 +204,8 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) } else device_priv[c] = p; - free(init_dev); + if (init_dev != dev) + free(init_dev); return priv; } From 38557b33dc5325e3db4a1200fcc28de5559f493b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 May 2024 17:24:43 +0200 Subject: [PATCH 549/690] Removed the VM_FLAG access from DRx access again. --- src/cpu/x86_ops_mov_ctrl.h | 8 ++++---- src/cpu/x86_ops_mov_ctrl_2386.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 5d6e44e34..bcfed831b 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -82,7 +82,7 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -126,7 +126,7 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -286,7 +286,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -334,7 +334,7 @@ opMOV_DRx_r_a16(uint32_t fetchdat) static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index 6bb00d8da..cae6c9957 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -82,7 +82,7 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -124,7 +124,7 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -282,7 +282,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } @@ -325,7 +325,7 @@ opMOV_DRx_r_a16(uint32_t fetchdat) static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } From e61c6205584e4414fc4a64494be5c6f1aab3e6ff Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 May 2024 20:12:25 +0200 Subject: [PATCH 550/690] ALi M1543(C): USB IRQ level/edge control. --- src/chipset/ali1543.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 5598f30fb..f35ec7590 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -413,6 +413,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x74: /* USB IRQ Routing - we cheat and use MIRQ4 */ dev->pci_conf[addr] = val & 0xdf; /* TODO: MIRQ level/edge control - if bit 4 = 1, it's level */ + pci_set_mirq_level(PCI_MIRQ4, !(val & 0x10)); pci_set_mirq_routing(PCI_MIRQ4, ali1533_irq_routing[val & 0x0f]); break; From 2ac3d289e624c85dc08fd00b79acc6af06974146 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 20:47:22 +0200 Subject: [PATCH 551/690] Video changes part 1 for 4.2 1. Corrected the ATI 1881x clocks for use with the ATI Mach8/32 and VGA Wonder chips. The CPU slowdowns should now be gone. 2. Merged I/O ports common to both the ATI and IBM 8514/A compatible chips where they have identical code (extended behavior is still separate). Code duplication is now less than before. 3. Fixed a general polygon pattern issue in the Mach8/32 affecting calc.exe in Win3.x and other stuff. 4. Mode changes are, once again, changed (ATI and IBM), as close as possible to the real thing without destroying existing resolutions. 5. The 8514/A Vertical Counter has been extended to 0xfff so that it can take 1280x1024 resolutions well offered by the Mach32 as well as a better way to change the IBM/ATI modes through a callback swap where approprietate. 6. in 8514/A mode, reads from the 0x3c6-0x3c9 ramdac range is redirected to the 8514/A RAMDAC (0x2ea-0x2ed). 7. LFB access in the Mach32 now no longer takes account of the SVGA derived rops. Fixes Mach32 display on NeXTSTEP/OPENSTEP 3.x/4.x 8. Reworked the Display Sense Status and Subsystem Status ports so that they're not copycats from MAME and instead follow the datasheet. --- src/include/86box/vid_8514a.h | 3 +- src/include/86box/vid_ati_mach8.h | 1 + src/include/86box/vid_svga.h | 36 +- src/video/vid_8514a.c | 396 +++++++------- src/video/vid_ati_mach8.c | 836 ++++++++++++------------------ src/video/vid_ics2494.c | 97 ++-- src/video/vid_svga.c | 15 +- 7 files changed, 635 insertions(+), 749 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index ac4085089..def3f0f2b 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -41,10 +41,10 @@ typedef union { typedef struct ibm8514_t { rom_t bios_rom; - rom_t bios_rom2; hwcursor8514_t hwcursor; hwcursor8514_t hwcursor_latch; uint8_t pos_regs[8]; + char *rom_path; int force_old_addr; int type; @@ -56,6 +56,7 @@ typedef struct ibm8514_t { uint32_t vram_size; uint32_t vram_mask; uint32_t pallook[512]; + uint32_t bios_addr; PALETTE vgapal; uint8_t hwcursor_oddeven; diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h index 7b5862f35..a25432920 100644 --- a/src/include/86box/vid_ati_mach8.h +++ b/src/include/86box/vid_ati_mach8.h @@ -74,6 +74,7 @@ typedef struct mach_t { uint16_t shadow_set; uint16_t shadow_cntl; int ext_on[2]; + int extended_mode; int compat_mode; struct { diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 9eecebf2c..3d68c1a34 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -78,6 +78,7 @@ typedef struct svga_t { uint8_t overlay_oddeven; uint8_t fcr; uint8_t hblank_overscan; + uint8_t vidsys_ena; int dac_addr; int dac_pos; @@ -199,6 +200,7 @@ typedef struct svga_t { void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); float (*getclock)(int clock, void *priv); + float (*getclock8514)(int clock, void *priv); /* Called when VC=R18 and friends. If this returns zero then MA resetting is skipped. Matrox Mystique in Power mode reuses this counter for @@ -288,26 +290,32 @@ typedef struct svga_t { void * dev8514; void * ext8514; + void * clock_gen8514; void * xga; } svga_t; -extern int vga_on; +extern int vga_on; -extern void ibm8514_poll(void *priv); -extern void ibm8514_recalctimings(svga_t *svga); -extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); -extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); -extern int ibm8514_cpu_src(svga_t *svga); -extern int ibm8514_cpu_dest(svga_t *svga); -extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); -extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); -extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); +extern void ibm8514_poll(void *priv); +extern void ibm8514_recalctimings(svga_t *svga); +extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); +extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); +extern void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len); +extern void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len); +extern uint16_t ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len); +extern uint8_t ibm8514_accel_in(uint16_t port, svga_t *svga); +extern int ibm8514_cpu_src(svga_t *svga); +extern int ibm8514_cpu_dest(svga_t *svga); +extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); +extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); +extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); #ifdef ATI_8514_ULTRA -extern void ati8514_recalctimings(svga_t *svga); -extern uint8_t ati8514_mca_read(int port, void *priv); -extern void ati8514_mca_write(int port, uint8_t val, void *priv); -extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); +extern void ati8514_recalctimings(svga_t *svga); +extern uint8_t ati8514_mca_read(int port, void *priv); +extern void ati8514_mca_write(int port, uint8_t val, void *priv); +extern void ati8514_pos_write(uint16_t port, uint8_t val, void *priv); +extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); #endif extern void xga_poll(void *priv, svga_t *svga); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index ff1470164..fc205dacf 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -44,6 +44,8 @@ #ifdef ATI_8514_ULTRA #define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" + +static video_timings_t timing_8514ultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; #endif static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); @@ -469,7 +471,7 @@ regular_nibble: } } -static void +void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; @@ -500,8 +502,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x86e9: case 0xc6e9: - if (len == 1) + if (len == 1) { dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); + } break; case 0x8ae8: @@ -548,6 +551,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len != 1) dev->test = val; fallthrough; + case 0xd2e8: if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; @@ -577,9 +581,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x96e9: case 0xd6e9: - if (len == 1) { + if (len == 1) dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); - } break; case 0x9ae8: @@ -624,7 +627,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; @@ -646,9 +648,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; + if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); @@ -883,7 +885,7 @@ ibm8514_io_set(svga_t *svga) io_sethandler(0xfee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); } -static void +void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; @@ -894,88 +896,89 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) else { switch (port) { case 0x2e8: - case 0x2e9: + case 0x6e9: WRITE8(port, dev->htotal, val); + ibm8514_log("IBM 8514/A compatible: (0x%04x): htotal=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x6e8: - case 0x6e9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; - } + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1]) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; } - ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); + ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); + svga_recalctimings(svga); break; case 0xae8: - case 0xae9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - } - } - ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + dev->hsync_start = val; + ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_start=%d.\n", port, val, (val + 1) << 3); + svga_recalctimings(svga); break; case 0xee8: - case 0xee9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - } - } - ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + dev->hsync_width = val; + ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); + svga_recalctimings(svga); break; case 0x12e8: case 0x12e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - WRITE8(port, dev->v_total_reg, val); - dev->v_total_reg &= 0x1fff; - dev->vtotal = dev->v_total_reg; - dev->vtotal++; - } + /*In preparation to switch from VGA to 8514/A mode*/ + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->v_total = dev->v_total_reg + 1; + if (dev->interlace) + dev->v_total >>= 1; + + ibm8514_log("IBM 8514/A compatible: (0x%04x): vtotal=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1]) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; + dev->vdisp = (dev->v_disp + 1) >> 1; } - ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); + ibm8514_log("IBM 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ae8: case 0x1ae9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - WRITE8(port, dev->v_sync_start, val); - dev->v_sync_start &= 0x1fff; - dev->vsyncstart = dev->v_sync_start; - dev->vsyncstart++; - } + /*In preparation to switch from VGA to 8514/A mode*/ + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->v_syncstart = dev->v_sync_start + 1; + if (dev->interlace) + dev->v_syncstart >>= 1; + + ibm8514_log("IBM 8514/A compatible: V_SYNCSTART write 1AE8 = %d\n", dev->v_syncstart); + ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncstart=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ee8: case 0x1ee9: - ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + ibm8514_log("IBM 8514/A compatible: V_SYNC_WID write 1EE8 = %02x\n", val); + ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncwidth=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x22e8: - dev->disp_cntl = val & 0x7e; - dev->interlace = !!(val & 0x10); - ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); + dev->disp_cntl = val; + dev->interlace = !!(dev->disp_cntl & 0x10); + ibm8514_log("IBM 8514/A compatible: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); + svga_recalctimings(svga); break; case 0x42e8: - old = dev->subsys_stat; if (val & 1) dev->subsys_stat &= ~1; if (val & 2) @@ -1004,11 +1007,11 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 0; - ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); + ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + ibm8514_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; - default: break; } @@ -1031,73 +1034,14 @@ ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv) ibm8514_accel_out(port, val, svga, 2); } -static uint32_t -ibm8514_accel_in(uint16_t port, svga_t *svga, int len) +uint16_t +ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) { - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint32_t temp = 0; - int cmd; - int vpos = 0; - int vblankend = svga->vblankstart + svga->crtc[0x16]; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t temp = 0; + int cmd = 0; switch (port) { - case 0x2e8: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - temp |= 2; - } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - temp |= 2; - } - break; - - case 0x6e8: - temp = dev->hdisped; - break; - - case 0x22e8: - temp = dev->disp_cntl; - break; - - case 0x26e8: - if (len == 1) - temp = dev->htotal & 0xff; - else - temp = dev->htotal; - break; - case 0x26e9: - if (len == 1) - temp = dev->htotal >> 8; - break; - - case 0x2ee8: - temp = dev->subsys_cntl; - break; - - case 0x42e8: - cmd = dev->accel.cmd >> 13; - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - if (len != 1) { - temp = dev->subsys_stat | 0xa0 | 0x8000; - } else - temp = dev->subsys_stat | 0xa0; - break; - - case 0x42e9: - if (len == 1) - temp |= 0x80; - break; - case 0x82e8: case 0xc2e8: if (len != 1) @@ -1115,6 +1059,11 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) temp = dev->test; break; + case 0x96e8: + if (len != 1) + temp = dev->accel.maj_axis_pcnt; + break; + case 0x9ae8: case 0xdae8: if (len != 1) { @@ -1143,24 +1092,13 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) case 0xe2e8: case 0xe6e8: if (ibm8514_cpu_dest(svga)) { - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(0) - } else { + if (len != 1) { cmd = (dev->accel.cmd >> 13); - READ_PIXTRANS_WORD(dev->accel.cx, 0) + READ_PIXTRANS_WORD(dev->accel.cx, 0); if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { temp &= ~0xff00; temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); } - } - ibm8514_accel_out_pixtrans(svga, port, temp, len); - } - break; - case 0xe2e9: - case 0xe6e9: - if (ibm8514_cpu_dest(svga)) { - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(1) ibm8514_accel_out_pixtrans(svga, port, temp, len); } } @@ -1172,20 +1110,100 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) return temp; } +uint8_t +ibm8514_accel_in(uint16_t port, svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp = 0; + uint16_t clip_b_ibm = dev->accel.multifunc[3]; + uint16_t clip_r_ibm = dev->accel.multifunc[4]; + int cmd = (dev->accel.cmd >> 13); + + switch (port) { + case 0x2e8: + if (dev->vc == dev->v_syncstart) + temp |= 2; + + ibm8514_log("0x2E8 read: Display Status=%02x.\n", temp); + break; + + case 0x6e8: + temp = dev->hdisped; + break; + + case 0x22e8: + temp = dev->disp_cntl; + break; + + case 0x26e8: + case 0x26e9: + READ8(port, dev->htotal); + break; + + case 0x2ee8: + temp = dev->subsys_cntl; + break; + case 0x2ee9: + temp = 0xff; + break; + + case 0x42e8: + case 0x42e9: + if (dev->vc == dev->v_syncstart) + dev->subsys_stat |= 1; + + if (cmd == 6) { + if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) + temp |= 2; + } else { + if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) + temp |= 2; + } + + if (!dev->force_busy) + temp |= 8; + + if (port & 1) + temp = 0x80; + else { + temp |= (dev->subsys_stat | 0x80); + temp |= 0x20; + } + break; + + default: + break; + } + return temp; +} + static uint8_t ibm8514_accel_inb(uint16_t port, void *priv) { svga_t *svga = (svga_t *) priv; + uint8_t temp; - return ibm8514_accel_in(port, svga, 1); + if (port & 0x8000) + temp = ibm8514_accel_in_fifo(svga, port, 1); + else + temp = ibm8514_accel_in(port, svga); + + return temp; } static uint16_t ibm8514_accel_inw(uint16_t port, void *priv) { svga_t *svga = (svga_t *) priv; + uint16_t temp; - return ibm8514_accel_in(port, svga, 2); + if (port & 0x8000) + temp = ibm8514_accel_in_fifo(svga, port, 2); + else { + temp = ibm8514_accel_in(port, svga); + temp |= (ibm8514_accel_in(port + 1, svga) << 8); + } + return temp; } void @@ -2285,7 +2303,6 @@ rect_fill_pix: WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -2448,6 +2465,7 @@ rect_fill_pix: } } } + mix_dat <<= 1; mix_dat |= 1; @@ -2525,6 +2543,7 @@ rect_fill_pix: } } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3385,6 +3404,7 @@ bitblt_pix: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat >>= 1; if (dev->bpp) cpu_dat >>= 16; @@ -3452,7 +3472,6 @@ bitblt_pix: } else { while (count-- && (dev->accel.sy >= 0)) { if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3496,6 +3515,7 @@ bitblt_pix: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3655,6 +3675,7 @@ bitblt: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + dev->accel.temp_cnt--; mix_dat >>= 1; @@ -3779,6 +3800,7 @@ bitblt: } } } + mix_dat <<= 1; mix_dat |= 1; @@ -4147,7 +4169,7 @@ ibm8514_poll(void *priv) dev->hwcursor_oddeven = 1; } - timer_advance_u64(&svga->timer8514, dev->dispofftime); + timer_advance_u64(&svga->timer, dev->dispofftime); svga->cgastat |= 1; dev->linepos = 1; @@ -4192,7 +4214,7 @@ ibm8514_poll(void *priv) if (dev->displine > 1500) dev->displine = 0; } else { - timer_advance_u64(&svga->timer8514, dev->dispontime); + timer_advance_u64(&svga->timer, dev->dispontime); if (dev->dispon) svga->cgastat &= ~1; dev->hdisp_on = 0; @@ -4215,7 +4237,7 @@ ibm8514_poll(void *priv) } dev->vc++; - dev->vc &= 0x7ff; + dev->vc &= 0xfff; if (dev->vc == dev->dispend) { dev->dispon = 0; @@ -4290,43 +4312,37 @@ ibm8514_recalctimings(svga_t *svga) #endif { if (dev->on[0] || dev->on[1]) { - dev->h_disp = dev->hdisp; - dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; - dev->dispend = dev->vdisp; - dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->h_total = dev->htotal + 1; + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + + if (dev->accel.advfunc_cntl & 0x04) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + + if (dev->interlace) + dev->dispend >>= 1; if (dev->dispend == 766) dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { - dev->pitch = 1024; - if (!dev->h_disp) { - dev->h_disp = 1024; - dev->dispend = 768; - } - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - dev->pitch = 640; - if (!dev->h_disp) { - dev->h_disp = 640; - dev->dispend = 480; - } - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } + if (dev->dispend == 478) + dev->dispend += 2; + dev->pitch = 1024; dev->rowoffset = 0x80; svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; @@ -4378,7 +4394,12 @@ ibm8514_mca_reset(void *priv) dev->on[0] = 0; dev->on[1] = 0; vga_on = 1; - ibm8514_mca_write(0x102, 0, svga); +#ifdef ATI_8514_ULTRA + if (dev->extensions) + ati8514_mca_write(0x102, 0, svga); + else +#endif + ibm8514_mca_write(0x102, 0, svga); } static void * @@ -4409,27 +4430,28 @@ ibm8514_init(const device_t *info) switch (dev->extensions) { case 1: if (rom_present(BIOS_MACH8_ROM_PATH)) { - mach = (mach_t *) calloc(1, sizeof(mach_t)); + mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t)); svga->ext8514 = mach; - ati8514_init(svga, svga->ext8514, svga->dev8514); if (dev->type & DEVICE_MCA) { rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xc6800, 0x1000, 0x0fff, - 0x0800, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&dev->bios_rom.mapping); + BIOS_MACH8_ROM_PATH, + 0xc6000, 0x2000, 0x1fff, + 0, MEM_MAPPING_EXTERNAL); dev->pos_regs[0] = 0x88; dev->pos_regs[1] = 0x80; mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0); + mem_mapping_disable(&dev->bios_rom.mapping); } else { rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xd0000, 0x1000, 0x0fff, - 0x0800, MEM_MAPPING_EXTERNAL); + BIOS_MACH8_ROM_PATH, + 0xd0000, 0x2000, 0x1fff, + 0, MEM_MAPPING_EXTERNAL); ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); + dev->bios_addr = dev->bios_rom.mapping.base; } + ati8514_init(svga, svga->ext8514, svga->dev8514); break; } fallthrough; @@ -4454,8 +4476,6 @@ ibm8514_init(const device_t *info) } #endif - timer_add(&svga->timer8514, ibm8514_poll, svga, 1); - return svga; } @@ -4526,7 +4546,7 @@ static const device_config_t ext8514_config[] = { // clang-format off const device_t gen8514_isa_device = { - .name = "Generic 8514/A clone (ISA)", + .name = "IBM 8514/A clone (ISA)", .internal_name = "8514_isa", .flags = DEVICE_AT | DEVICE_ISA, .local = 0, @@ -4536,7 +4556,11 @@ const device_t gen8514_isa_device = { { .available = NULL }, .speed_changed = ibm8514_speed_changed, .force_redraw = ibm8514_force_redraw, +#ifdef ATI_8514_ULTRA + .config = ext8514_config +#else .config = NULL +#endif }; const device_t ibm8514_mca_device = { @@ -4550,7 +4574,11 @@ const device_t ibm8514_mca_device = { { .available = NULL }, .speed_changed = ibm8514_speed_changed, .force_redraw = ibm8514_force_redraw, +#ifdef ATI_8514_ULTRA + .config = ext8514_config +#else .config = NULL +#endif }; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index be2c5d547..83edb4355 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -315,8 +315,6 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; - mach->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { mach->force_busy = 1; dev->force_busy = 1; @@ -817,7 +815,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; - if ((mach->accel.dp_config == 0x5211) || (mach->accel.dp_config == 0x3251)) { + if (mach->accel.dp_config == 0x5211) { if (mach->accel.dest_x_end == 1024) { goto skip_dx; } @@ -1008,6 +1006,7 @@ skip_dx: if (cpu_input) { if (mach->accel.dp_config == 0x3251) { + mach_log("DPCONFIG 3251: monosrc=%d, frgdsel=%d, bkgdsel=%d, pitch=%d.\n", mono_src, frgd_sel, bkgd_sel, dev->pitch); if (dev->accel.sy == mach->accel.height) return; } @@ -1386,15 +1385,7 @@ skip_dx: dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } - if (mach->accel.linedraw_opt & 0x04) { - if (count) { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } - } - } else { + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { @@ -1647,20 +1638,10 @@ skip_dx: } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if (mach->accel.linedraw_opt & 0x04) { - if (count) { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } - } + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else @@ -2374,6 +2355,9 @@ mach_in(uint16_t addr, void *priv) if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if ((addr >= 0x3c6) && (addr <= 0x3c9) && (dev->on[0] || dev->on[1])) + addr -= 0xdc; + switch (addr) { case 0x1ce: temp = mach->index; @@ -2399,9 +2383,9 @@ mach_in(uint16_t addr, void *priv) } break; case 0xb7: - temp = mach->regs[0xb7] & ~8; + temp = mach->regs[0xb7] & ~0x08; if (ati_eeprom_read(&mach->eeprom)) - temp |= 8; + temp |= 0x08; break; case 0xbd: @@ -2429,21 +2413,6 @@ mach_in(uint16_t addr, void *priv) temp = svga_in(addr, svga); break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - rs2 = !!(mach->regs[0xa0] & 0x20); - rs3 = !!(mach->regs[0xa0] & 0x40); - if ((dev->local & 0xff) >= 0x02) { - if (mach->pci_bus && !mach->ramdac_type) - temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); - else - temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else - temp = svga_in(addr, svga); - break; - case 0x3D4: temp = svga->crtcreg; break; @@ -2466,7 +2435,7 @@ mach_in(uint16_t addr, void *priv) static void ati8514_out(uint16_t addr, uint8_t val, void *priv) { - mach_log("ADDON OUT addr=%03x, val=%02x.\n", addr, val); + mach_log("[%04X:%08X]: ADDON OUT addr=%03x, val=%02x.\n", CS, cpu_state.pc, addr, val); svga_out(addr, val, priv); } @@ -2477,26 +2446,43 @@ ati8514_in(uint16_t addr, void *priv) temp = svga_in(addr, priv); - mach_log("ADDON IN addr=%03x, temp=%02x.\n", addr, temp); + mach_log("[%04X:%08X]: ADDON IN addr=%03x, temp=%02x.\n", CS, cpu_state.pc, addr, temp); return temp; } void ati8514_recalctimings(svga_t *svga) { - const mach_t *mach = (mach_t *) svga->ext8514; + mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); if (dev->on[0] || dev->on[1]) { - dev->h_disp = dev->hdisp; + mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = dev->vdisp; + dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + mach->accel.ge_offset = dev->accel.ge_offset; + + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe); + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + + if (dev->accel.advfunc_cntl & 0x04) { + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } if (dev->dispend == 766) dev->dispend += 2; @@ -2504,28 +2490,12 @@ ati8514_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { - if (dev->h_disp != 800) { - dev->h_disp = 1024; - dev->dispend = 768; - } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } + if (dev->dispend == 478) + dev->dispend += 2; dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; } else { @@ -2598,26 +2568,34 @@ mach_recalctimings(svga_t *svga) if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->v_total = dev->v_total_reg + 1; - dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + mach->accel.ge_offset = dev->accel.ge_offset; - mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04); - if ((dev->hdisp != 1024) || dev->bpp) { - /*For VESA/ATI modes in 8514/A mode.*/ + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe); + if (!dev->bpp) { + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + } else { dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; - } else { - /*Default modes for 8514/A mode*/ - if (dev->accel.advfunc_cntl & 0x04) { - dev->h_disp = 1024; - dev->dispend = 768; - } else { - dev->h_disp = 640; - dev->dispend = 480; - } } + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + + if (dev->interlace) + dev->dispend >>= 1; + if (dev->dispend == 766) dev->dispend += 2; @@ -2628,27 +2606,6 @@ mach_recalctimings(svga_t *svga) dev->dispend += 2; if ((dev->local & 0xff) >= 0x02) { - if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - mach_log("HDISP=%d.\n", dev->h_disp); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; @@ -2696,58 +2653,38 @@ mach_recalctimings(svga_t *svga) break; } } - switch (mach->regs[0xb8] & 0xc0) { - case 0x40: - svga->clock8514 *= 2; - break; - case 0x80: - svga->clock8514 *= 3; - break; - case 0xc0: - svga->clock8514 *= 4; - break; - - default: - break; - } } else { - if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - if (mach->regs[0xb8] & 0x40) - svga->clock8514 *= 2; } } if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { - mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - if (mach->regs[0xa7] & 0x80) - svga->clock *= 3; + mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); + if ((dev->local & 0xff) >= 0x02) { + if (mach->regs[0xb8] & 0x40) + svga->clock *= 2; + } else { + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; + + default: + break; + } + } switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ @@ -2799,114 +2736,56 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u switch (port) { case 0x82e8: - case 0xc2e8: - case 0xf6ee: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - else - dev->accel.cur_y = val & 0x7ff; - break; case 0x82e9: - case 0xc2e9: - case 0xf6ef: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - break; - case 0x86e8: - case 0xc6e8: - if (len == 1) - dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - else - dev->accel.cur_x = val & 0x7ff; - break; case 0x86e9: + case 0xc2e8: + case 0xc2e9: + case 0xc6e8: case 0xc6e9: - if (len == 1) { - dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); - } + ibm8514_accel_out_fifo(svga, port, val, len); + break; + case 0xf6ee: + ibm8514_accel_out_fifo(svga, 0x82e8, val, len); + break; + case 0xf6ef: + ibm8514_accel_out_fifo(svga, 0x82e9, val, len); break; case 0x8ae8: case 0xcae8: - if (len == 1) - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; - else { - mach->accel.src_y = val; - dev->accel.desty = val & 0x07ff; - dev->accel.desty_axstp = val & 0x3fff; - if (val & 0x2000) - dev->accel.desty_axstp |= ~0x1fff; - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.src_y = val; break; case 0x8ae9: + case 0x8ee9: case 0xcae9: - if (len == 1) { - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.desty_axstp |= ~0x1fff; - } + case 0xcee9: + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x8ee8: case 0xcee8: - if (len == 1) - dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; - else { - mach->accel.src_x = val; - dev->accel.destx = val & 0x07ff; - dev->accel.destx_distp = val & 0x3fff; - if (val & 0x2000) - dev->accel.destx_distp |= ~0x1fff; - } - break; - case 0x8ee9: - case 0xcee9: - if (len == 1) { - dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.destx_distp |= ~0x1fff; - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.src_x = val; break; case 0x92e8: - if (len != 1) - dev->test = val; - fallthrough; - - case 0xd2e8: - if (len == 1) - dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; - else { - dev->accel.err_term = val & 0x3fff; - if (val & 0x2000) - dev->accel.err_term |= ~0x1fff; - } - break; case 0x92e9: + case 0x96e9: + case 0xd2e8: case 0xd2e9: - if (len == 1) { - dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.err_term |= ~0x1fff; - } + case 0xd6e9: + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x96e8: case 0xd6e8: - if (len == 1) - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val; - else { - mach->accel.test = val & 0x1fff; - dev->accel.maj_axis_pcnt = val & 0x07ff; - dev->accel.maj_axis_pcnt_no_limit = val; - } - break; - case 0x96e9: - case 0xd6e9: - if (len == 1) { - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.test = val & 0x1fff; break; case 0x9ae8: @@ -2952,12 +2831,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x >= 0x600) { + if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - } - if (dev->accel.cur_y >= 0x600) { + + if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - } if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); @@ -3163,56 +3041,22 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xaae8: - case 0xeae8: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; - else { - dev->accel.wrt_mask = val; - mach_log("WrtMask=%04x.\n", val); - } - break; case 0xaae9: - case 0xeae9: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8); - break; - case 0xaee8: - case 0xeee8: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; - else { - dev->accel.rd_mask = val; - mach_log("ReadMask=%04x.\n", val); - } - break; case 0xaee9: - case 0xeee9: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8); - break; - case 0xb2e8: - case 0xf2e8: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val; - else - dev->accel.color_cmp = val; - break; case 0xb2e9: - case 0xf2e9: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8); - break; - case 0xb6e8: - case 0xf6e8: - dev->accel.bkgd_mix = val & 0xff; - break; - case 0xbae8: + case 0xeae8: + case 0xeae9: + case 0xeee8: + case 0xeee9: + case 0xf2e8: + case 0xf2e9: + case 0xf6e8: case 0xfae8: - dev->accel.frgd_mix = val & 0xff; + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xbee8: @@ -3274,9 +3118,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x8eee: - if (len == 1) { + if (len == 1) mach->accel.patt_data[mach->accel.patt_data_idx] = val; - } else { + else { mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff; mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; if (mach->accel.mono_pattern_enable) @@ -3359,9 +3203,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } break; case 0xa2ef: - if (len == 1) { + if (len == 1) mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8); - } break; case 0xa6ee: @@ -3378,9 +3221,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xaaee: if (len == 1) mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val; - else { + else mach->accel.dest_x_end = val & 0x7ff; - } break; case 0xaaef: if (len == 1) @@ -3435,9 +3277,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xbeee: if (len == 1) mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val; - else { + else mach->accel.src_x_end = val & 0x7ff; - } break; case 0xbeef: if (len == 1) @@ -3490,20 +3331,18 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } break; case 0xceef: - if (len == 1) { + if (len == 1) mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8); - } break; case 0xd2ee: mach->accel.patt_len = val & 0x1f; mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val); mach->accel.mono_pattern_enable = !!(val & 0x80); - if (len != 1) { + if (len != 1) mach->accel.patt_len_reg = val; - } else { + else mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val; - } break; case 0xd2ef: if (len == 1) @@ -3519,9 +3358,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("DAEE (extclipl) write val = %d\n", val); if (len == 1) dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val; - else { + else dev->accel.clip_left = val & 0x7ff; - } break; case 0xdaef: if (len == 1) @@ -3532,9 +3370,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("DEEE (extclipt) write val = %d\n", val); if (len == 1) dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val; - else { + else dev->accel.clip_top = val & 0x7ff; - } break; case 0xdeef: if (len == 1) @@ -3545,9 +3382,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("E2EE (extclipr) write val = %d\n", val); if (len == 1) dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val; - else { + else dev->accel.multifunc[4] = val & 0x7ff; - } break; case 0xe2ef: if (len == 1) @@ -3558,9 +3394,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("E6EE (extclipb) write val = %d\n", val); if (len == 1) dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val; - else { + else dev->accel.multifunc[3] = val & 0x7ff; - } break; case 0xe6ef: if (len == 1) @@ -3624,45 +3459,27 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 switch (port) { case 0x2e8: case 0x6e9: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->htotal = val; - - svga_recalctimings(svga); + case 0xae8: + case 0xee8: + case 0x12e8: + case 0x12e9: + case 0x1ae8: + case 0x1ae9: + case 0x1ee8: + case 0x1ee9: + case 0x22e8: + case 0x42e8: + case 0x42e9: + ibm8514_accel_out(port, val, svga, 2); break; case 0x6e8: - /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hdisped = val; - - mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); - mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); - svga_recalctimings(svga); - break; - - case 0xae8: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hsync_start = val; - - mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_start=%d.\n", port, val, (val + 1) << 3); - svga_recalctimings(svga); - break; - - case 0xee8: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hsync_width = val; - - mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); - svga_recalctimings(svga); - break; - - case 0x12e8: - case 0x12e9: /*In preparation to switch from VGA to 8514/A mode*/ if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - WRITE8(port, dev->v_total_reg, val); - dev->v_total_reg &= 0x1fff; + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; } + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); svga_recalctimings(svga); break; @@ -3672,59 +3489,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; + dev->vdisp = (dev->v_disp + 1) >> 1; } - dev->modechange = dev->accel.advfunc_cntl & 0x04; - mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); svga_recalctimings(svga); break; - case 0x1ae8: - case 0x1ae9: - /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - WRITE8(port, dev->v_sync_start, val); - dev->v_sync_start &= 0x1fff; - } - svga_recalctimings(svga); - break; - - case 0x1ee8: - case 0x1ee9: - mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - break; - - case 0x22e8: - dev->disp_cntl = val; - dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); - break; - - case 0x42e8: - old = dev->subsys_stat; - if (val & 1) - dev->subsys_stat &= ~1; - if (val & 2) - dev->subsys_stat &= ~2; - if (val & 4) - dev->subsys_stat &= ~4; - if (val & 8) - dev->subsys_stat &= ~8; - break; - case 0x42e9: - old = dev->subsys_cntl; - dev->subsys_cntl = val; - if ((old ^ val) & 1) - dev->subsys_stat |= 1; - if ((old ^ val) & 2) - dev->subsys_stat |= 2; - if ((old ^ val) & 4) - dev->subsys_stat |= 4; - if ((old ^ val) & 8) - dev->subsys_stat |= 8; - break; - case 0x4ae8: case 0x4ae9: WRITE8(port, dev->accel.advfunc_cntl, val); @@ -3736,9 +3507,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - dev->hdisp = (dev->hdisped + 1) << 3; - dev->vdisp = (dev->v_disp >> 1) + 1; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; @@ -3817,7 +3586,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 else dev->ext_crt_pitch <<= 1; } - mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val); svga_recalctimings(svga); break; @@ -3857,20 +3626,18 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x46ee: case 0x46ef: WRITE8(port, mach->shadow_cntl, val); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); break; case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); dev->on[port & 1] = mach->accel.clock_sel & 0x01; - mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp); + mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d, val=0x%02x.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp, val & 0xfe); mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); mach->ext_on[port & 1] = dev->on[port & 1]; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 1; - dev->hdisp = (dev->hdisped + 1) << 3; - dev->vdisp = (dev->v_disp >> 1) + 1; svga_recalctimings(svga); break; @@ -3889,13 +3656,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x5aee: case 0x5aef: WRITE8(port, mach->shadow_set, val); - mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val); if ((mach->shadow_set & 0x03) == 0x00) mach_log("Primary CRT register set.\n"); else if ((mach->shadow_set & 0x03) == 0x01) - mach_log("Shadow Set 1: 640x480.\n"); + mach_log("CRT Shadow Set 1: 640x480.\n"); else if ((mach->shadow_set & 0x03) == 0x02) - mach_log("Shadow Set 2: 1024x768.\n"); + mach_log("CRT Shadow Set 2: 1024x768.\n"); break; case 0x5eee: @@ -3924,20 +3691,21 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6eee: case 0x6eef: WRITE8(port, mach->accel.ge_offset_lo, val); - dev->accel.ge_offset = mach->accel.ge_offset_lo; + svga_recalctimings(svga); break; case 0x72ee: case 0x72ef: WRITE8(port, mach->accel.ge_offset_hi, val); - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset); + svga_recalctimings(svga); break; case 0x76ee: case 0x76ef: WRITE8(port, mach->accel.ge_pitch, val); dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach_log("ATI 8514/A: (0x%04x) val=%04x, extpitch=%d.\n", port, val, dev->ext_pitch); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, extpitch=%d.\n", port, val, dev->ext_pitch); svga_recalctimings(svga); break; @@ -3973,15 +3741,14 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); svga_recalctimings(svga); } else { - if (mach->accel.ext_ge_config & 0x8080) - ati_eeprom_write(&mach->eeprom, mach->accel.ext_ge_config & 0x4040, mach->accel.ext_ge_config & 0x2020, mach->accel.ext_ge_config & 0x1010); + ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x4040), !!(mach->accel.ext_ge_config & 0x2020), !!(mach->accel.ext_ge_config & 0x1010)); } break; case 0x7eee: case 0x7eef: WRITE8(port, mach->accel.eeprom_control, val); - ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 8, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); + ati_eeprom_write(&mach->eeprom, !!(mach->accel.eeprom_control & 8), !!(mach->accel.eeprom_control & 2), !!(mach->accel.eeprom_control & 1)); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); break; @@ -4012,25 +3779,12 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in switch (port) { case 0x82e8: - case 0xc2e8: - if (len != 1) - temp = dev->accel.cur_y; - break; - case 0x86e8: - case 0xc6e8: - if (len != 1) - temp = dev->accel.cur_x; - break; - case 0x92e8: - if (len != 1) - temp = dev->test; - break; - case 0x96e8: - if (len != 1) - temp = dev->accel.maj_axis_pcnt; + case 0xc2e8: + case 0xc6e8: + temp = ibm8514_accel_in_fifo(svga, port, len); break; case 0x9ae8: @@ -4254,16 +4008,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0x96ee: if (len == 1) - temp = dev->accel.maj_axis_pcnt & 0xff; - else { - temp = dev->accel.maj_axis_pcnt; - if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa)) - temp = mach->accel.test; - } + temp = mach->accel.test & 0xff; + else + temp = mach->accel.test; break; case 0x96ef: if (len == 1) - temp = dev->accel.maj_axis_pcnt >> 8; + temp = mach->accel.test >> 8; break; case 0xa2ee: @@ -4375,23 +4126,29 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xfaee: if (len != 1) { - if (mach->pci_bus) - temp = 0x0017; - else - temp = 0x22f7; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x0017; + else + temp = 0x22f7; + } } else { - if (mach->pci_bus) - temp = 0x17; - else - temp = 0xf7; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x17; + else + temp = 0xf7; + } } break; case 0xfaef: if (len == 1) { - if (mach->pci_bus) - temp = 0x00; - else - temp = 0x22; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x00; + else + temp = 0x22; + } } break; @@ -4407,64 +4164,57 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in static uint8_t mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - uint8_t temp = 0; - uint16_t vpos = 0; - uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; + uint8_t temp = 0; + uint16_t clip_b_ibm = dev->accel.multifunc[3]; + uint16_t clip_r_ibm = dev->accel.multifunc[4]; + int16_t clip_l = dev->accel.clip_left & 0x7ff; + int16_t clip_t = dev->accel.clip_top & 0x7ff; + int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + int cmd = (dev->accel.cmd >> 13); switch (port) { case 0x2e8: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - temp |= 2; - } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - temp |= 2; - } - break; - case 0x6e8: - temp = dev->hdisped; - break; - case 0x22e8: - temp = dev->disp_cntl; - break; - case 0x26e8: - temp = dev->htotal; - break; - + case 0x26e9: case 0x2ee8: - temp = dev->subsys_cntl; - break; case 0x2ee9: - temp = 0xff; + temp = ibm8514_accel_in(port, svga); break; case 0x42e8: case 0x42e9: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - dev->subsys_stat |= 1; + if (dev->vc == dev->v_syncstart) + dev->subsys_stat |= 1; + + if (mach->accel.cmd_type >= 0) { + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) + temp |= 2; } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - dev->subsys_stat |= 1; + if (cmd == 6) { + if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) + temp |= 2; + } else { + if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) + temp |= 2; + } } + if (!dev->force_busy) + temp |= 8; + if (port & 1) temp = 0x80; else { - temp = dev->subsys_stat | 0x80; + temp |= (dev->subsys_stat | 0x80); if (mach->accel.ext_ge_config & 0x08) temp |= ((mach->accel.ext_ge_config & 0x07) << 4); else temp |= 0x20; } - mach_log("Subsystem Status=%04x, 4ae8 shadow set=%02x.\n", temp, dev->accel.advfunc_cntl & 4); + mach_log("0x%04x read: Subsystem Status=%02x.\n", port, temp); break; /*ATI Mach8/32 specific registers*/ @@ -4478,6 +4228,11 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) READ8(port, mach->config2); break; + case 0x1aee: + case 0x1aef: + temp = 0x00; + break; + case 0x22ee: if (mach->pci_bus) temp = mach->pci_cntl_reg; @@ -4541,11 +4296,14 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) temp = dev->pos_regs[5]; } } else { - if (!(port & 1)) { - if (svga->ext8514 != NULL) { - temp = 0x20 | 0x80; + if (svga->ext8514 != NULL) { + temp = ((dev->bios_addr >> 7) - 0x1000) >> 4; + if (port & 1) { + temp &= ~0x80; + temp |= 0x01; } - } + } else + temp = 0x00; } #endif break; @@ -4574,6 +4332,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) mach->force_busy = 0; if (ati_eeprom_read(&mach->eeprom)) temp |= 0x40; + mach_log("Mach busy temp=%02x.\n", temp); break; @@ -4860,9 +4619,8 @@ mach32_decode_addr(svga_t *svga, uint32_t addr, int write) } static __inline void -mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) +mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t *svga) { - svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int writemask2 = svga->writemask; int reset_wm = 0; @@ -5003,29 +4761,59 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) svga->gdcreg[8] = wm; } +#ifdef ATI_8514_ULTRA +static void +ati8514_write(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val, 0, mach, svga); +} + +static void +ati8514_writew(uint32_t addr, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); +} + +static void +ati8514_writel(uint32_t addr, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); + mach32_write_common(addr + 2, val >> 16, 0, mach, svga); + mach32_write_common(addr + 3, val >> 24, 0, mach, svga); +} +#endif + static void mach32_write(uint32_t addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val, 0, mach); + mach32_write_common(addr, val, 0, mach, &mach->svga); } static void mach32_writew(uint32_t addr, uint16_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach); - mach32_write_common(addr + 1, val >> 8, 0, mach); + mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); } static void mach32_writel(uint32_t addr, uint32_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach); - mach32_write_common(addr + 1, val >> 8, 0, mach); - mach32_write_common(addr + 2, val >> 16, 0, mach); - mach32_write_common(addr + 3, val >> 24, 0, mach); + mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); + mach32_write_common(addr + 2, val >> 16, 0, mach, &mach->svga); + mach32_write_common(addr + 3, val >> 24, 0, mach, &mach->svga); } static __inline void @@ -5061,9 +4849,8 @@ mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach) } static __inline uint8_t -mach32_read_common(uint32_t addr, int linear, mach_t *mach) +mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) { - svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint32_t latch_addr = 0; int readplane = svga->readplane; @@ -5153,13 +4940,52 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) return ret; } +#ifdef ATI_8514_ULTRA +static uint8_t +ati8514_read(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint8_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + return ret; +} + +static uint16_t +ati8514_readw(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint16_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + return ret; +} + +static uint32_t +ati8514_readl(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint32_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 24); + return ret; +} +#endif + static uint8_t mach32_read(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; uint8_t ret; - ret = mach32_read_common(addr, 0, mach); + ret = mach32_read_common(addr, 0, mach, &mach->svga); return ret; } @@ -5169,8 +4995,8 @@ mach32_readw(uint32_t addr, void *priv) mach_t *mach = (mach_t *) priv; uint16_t ret; - ret = mach32_read_common(addr, 0, mach); - ret |= (mach32_read_common(addr + 1, 0, mach) << 8); + ret = mach32_read_common(addr, 0, mach, &mach->svga); + ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); return ret; } @@ -5180,10 +5006,10 @@ mach32_readl(uint32_t addr, void *priv) mach_t *mach = (mach_t *) priv; uint32_t ret; - ret = mach32_read_common(addr, 0, mach); - ret |= (mach32_read_common(addr + 1, 0, mach) << 8); - ret |= (mach32_read_common(addr + 2, 0, mach) << 16); - ret |= (mach32_read_common(addr + 3, 0, mach) << 24); + ret = mach32_read_common(addr, 0, mach, &mach->svga); + ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach, &mach->svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, &mach->svga) << 24); return ret; } @@ -5237,7 +5063,7 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) } else { mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val); if (dev->on[0] || dev->on[1]) - mach32_write_common(addr, val, 1, mach); + mach32_write_common(addr, val, 1, mach, svga); else svga_write_linear(addr, val, svga); } @@ -5314,7 +5140,7 @@ mach32_ap_readb(uint32_t addr, void *priv) temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); } else { if (dev->on[0] || dev->on[1]) - temp = mach32_read_common(addr, 1, mach); + temp = mach32_read_common(addr, 1, mach, svga); else temp = svga_read_linear(addr, svga); @@ -5434,10 +5260,18 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) mach->ap_size = 4; mem_mapping_disable(&mach->mmio_linear_mapping); } - if (((dev->local & 0xff) >= 0x02) && (dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) { + if ((dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) { mach_log("ExtON.\n"); - mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); - mem_mapping_set_p(&svga->mapping, mach); +#ifdef ATI_8514_ULTRA + if (svga->ext8514 != NULL) { + mem_mapping_set_handler(&svga->mapping, ati8514_read, ati8514_readw, ati8514_readl, ati8514_write, ati8514_writew, ati8514_writel); + mem_mapping_set_p(&svga->mapping, svga); + } else +#endif + { + mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); + mem_mapping_set_p(&svga->mapping, mach); + } } else { mach_log("ExtOFF.\n"); mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); @@ -5534,6 +5368,7 @@ ati8514_io_set(svga_t *svga) io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x46e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); @@ -5650,6 +5485,7 @@ mach_io_set(mach_t *mach) io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x46e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); @@ -5747,6 +5583,7 @@ mach_io_set(mach_t *mach) io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } @@ -5828,6 +5665,12 @@ ati8514_mca_write(int port, uint8_t val, void *priv) if (dev->pos_regs[2] & 0x01) mem_mapping_enable(&dev->bios_rom.mapping); } + +void +ati8514_pos_write(uint16_t port, uint8_t val, void *priv) +{ + ati8514_mca_write(port, val, priv); +} #endif static uint8_t @@ -6084,8 +5927,8 @@ mach8_init(const device_t *info) mach->config2 = 0x02; svga->clock_gen = device_add(&ati18810_device); } - dev->bpp = 0; - svga->getclock = ics2494_getclock; + dev->bpp = 0; + svga->getclock = ics2494_getclock; dev->on[0] = 0; dev->on[1] = 0; @@ -6107,7 +5950,6 @@ mach8_init(const device_t *info) mach->cursor_col_1 = 0xff; mach->ext_cur_col_1_r = 0xff; mach->ext_cur_col_1_g = 0xff; - io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); if (mach->vlb_bus) ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); else if (mach->mca_bus) { @@ -6134,8 +5976,6 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); - timer_add(&svga->timer8514, ibm8514_poll, svga, 1); - return mach; } @@ -6143,8 +5983,8 @@ mach8_init(const device_t *info) void ati8514_init(svga_t *svga, void *ext8514, void *dev8514) { - mach_t *mach = (mach_t *)ext8514; - ibm8514_t *dev = (ibm8514_t *)dev8514; + mach_t *mach = (mach_t *) ext8514; + ibm8514_t *dev = (ibm8514_t *) dev8514; dev->on[0] = 0; dev->on[1] = 0; diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index 309d07966..e85b4539e 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -56,6 +56,7 @@ ics2494_getclock(int clock, void *priv) if (clock > 15) clock = 15; + ics2494_log("Clock=%d, freq=%f.\n", clock, ics2494->freq[clock]); return ics2494->freq[clock]; } @@ -68,60 +69,60 @@ ics2494_init(const device_t *info) switch (info->local) { case 10: /* ATI 18810 for ATI 28800 */ - ics2494->freq[0x0] = 30240000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 37500000.0; - ics2494->freq[0x3] = 39000000.0; - ics2494->freq[0x4] = 42954000.0; - ics2494->freq[0x5] = 48771000.0; - ics2494->freq[0x6] = 16657000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 40000000.0; - ics2494->freq[0x9] = 56644000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 28322000.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 42954000.0; + ics2494->freq[0x1] = 48771000.0; + ics2494->freq[0x2] = 0.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 30240000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 37500000.0; + ics2494->freq[0xb] = 39000000.0; + ics2494->freq[0xc] = 40000000.0; + ics2494->freq[0xd] = 56644000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 110: /* ATI 18811-0 for ATI Mach32 */ - ics2494->freq[0x0] = 30240000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 110000000.0; - ics2494->freq[0x3] = 80000000.0; - ics2494->freq[0x4] = 42954000.0; - ics2494->freq[0x5] = 48771000.0; - ics2494->freq[0x6] = 92400000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 39910000.0; - ics2494->freq[0x9] = 44900000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 0.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 42954000.0; + ics2494->freq[0x1] = 48771000.0; + ics2494->freq[0x2] = 92400000.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 30240000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 110000000.0; + ics2494->freq[0xb] = 80000000.0; + ics2494->freq[0xc] = 39910000.0; + ics2494->freq[0xd] = 44900000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 111: /* ATI 18811-1 for ATI Mach32 MCA */ - ics2494->freq[0x0] = 135000000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 110000000.0; - ics2494->freq[0x3] = 80000000.0; - ics2494->freq[0x4] = 100000000.0; - ics2494->freq[0x5] = 126000000.0; - ics2494->freq[0x6] = 92400000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 39910000.0; - ics2494->freq[0x9] = 44900000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 0.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 100000000.0; + ics2494->freq[0x1] = 126000000.0; + ics2494->freq[0x2] = 92400000.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 135000000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 110000000.0; + ics2494->freq[0xb] = 80000000.0; + ics2494->freq[0xc] = 39910000.0; + ics2494->freq[0xd] = 44900000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 305: /* ICS2494A(N)-205 for S3 86C924 */ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 4632ab85e..307f455c3 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -46,6 +46,7 @@ #include <86box/vid_xga_device.h> void svga_doblit(int wx, int wy, svga_t *svga); +void svga_poll(void *priv); svga_t *svga_8514; @@ -121,6 +122,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv) if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) return; + if (addr >= 0x3c6 && addr <= 0x3c9) + svga_log("VGA OUT addr=%03x, val=%02x.\n", addr, val); + switch (addr) { case 0x2ea: dev->dac_mask = val; @@ -528,6 +532,9 @@ svga_in(uint16_t addr, void *priv) break; } + if ((addr >= 0x3c6) && (addr <= 0x3c9)) + svga_log("VGA IN addr=%03x, temp=%02x.\n", addr, ret); + return ret; } @@ -935,11 +942,11 @@ svga_recalctimings(svga_t *svga) if (dev->dispofftime < TIMER_USEC) dev->dispofftime = TIMER_USEC; - timer_disable(&svga->timer); - timer_set_delay_u64(&svga->timer8514, TIMER_USEC); + svga_log("IBM 8514/A poll.\n"); + timer_set_callback(&svga->timer, ibm8514_poll); } else { - timer_disable(&svga->timer8514); - timer_set_delay_u64(&svga->timer, TIMER_USEC); + svga_log("SVGA Poll.\n"); + timer_set_callback(&svga->timer, svga_poll); } } From 6d2ea183c221c480ed5f35a3cbe9d895513217ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 29 May 2024 23:18:43 +0200 Subject: [PATCH 552/690] PAS Plus: Fix ID. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 243332257..d88a498d5 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -823,7 +823,7 @@ pas16_in(uint16_t port, void *priv) - 2 = FM (1 = stereo, 0 = mono); - 3 = Code (1 = 16-bit, 0 = 8-bit). */ - ret = pas16->type ? pas16->type : 0x06; + ret = pas16->type ? pas16->type : 0x07; break; case 0xf000: From ff5d5273ed3ea8d957e02c05d5605786181b47e5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 23:45:00 +0200 Subject: [PATCH 553/690] Video changes part 2 1. Added the Diamond Stealth 64 Video VRAM 968-based card. 2. Removed the useless VLB-based Phoenix 868 and 968 cards. 3. The Diamond Stealth 64 Video VRAM specific drivers apparently use 0x83ca-0x83cb as aliases of the RAMDAC ports 0x83c6-0x83c7 (New MMIO mode). This makes the hardware cursor visible in those drivers on win3.1 using the IBM RGB RAMDAC. 4. A few more logs and sanity checks around LFB access and MMIO as well. --- src/include/86box/video.h | 4 +- src/video/vid_s3.c | 149 +++++++++++++++++++++++++------------- src/video/vid_table.c | 4 +- 3 files changed, 104 insertions(+), 53 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 1c8b61015..e1a1a7502 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -507,15 +507,15 @@ extern const device_t s3_phoenix_vision864_pci_device; extern const device_t s3_phoenix_vision864_vlb_device; extern const device_t s3_9fx_531_pci_device; extern const device_t s3_phoenix_vision868_pci_device; -extern const device_t s3_phoenix_vision868_vlb_device; extern const device_t s3_diamond_stealth64_pci_device; extern const device_t s3_diamond_stealth64_vlb_device; extern const device_t s3_diamond_stealth64_964_pci_device; extern const device_t s3_diamond_stealth64_964_vlb_device; +extern const device_t s3_diamond_stealth64_968_pci_device; +extern const device_t s3_diamond_stealth64_968_vlb_device; extern const device_t s3_mirovideo_40sv_ergo_968_pci_device; extern const device_t s3_9fx_771_pci_device; extern const device_t s3_phoenix_vision968_pci_device; -extern const device_t s3_phoenix_vision968_vlb_device; extern const device_t s3_spea_mercury_p64v_pci_device; extern const device_t s3_elsa_winner2000_pro_x_964_pci_device; extern const device_t s3_elsa_winner2000_pro_x_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8fa86dfe0..e74ff8c06 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -75,6 +75,7 @@ #define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" #define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN" #define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" +#define ROM_DIAMOND_STEALTH64_968 "roms/video/s3/vv_303.rom" enum { S3_NUMBER9_9FX, @@ -115,7 +116,8 @@ enum { S3_NUMBER9_9FX_531, S3_NUMBER9_9FX_771, S3_SPEA_MERCURY_LITE_PCI, - S3_86C805_ONBOARD + S3_86C805_ONBOARD, + S3_DIAMOND_STEALTH64_968 }; enum { @@ -2770,13 +2772,15 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: + case 0x3CA: /*0x3c6 alias*/ + case 0x3CB: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) svga_out(addr, val, svga); else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { rs3 = !!(svga->crtc[0x55] & 0x02); bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -2957,10 +2961,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x58: case 0x59: case 0x5a: + s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); s3_updatemapping(s3); break; case 0x55: + s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { if (val & 0x28) { svga->hwcursor_draw = NULL; @@ -3093,6 +3099,8 @@ s3_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: + case 0x3ca: /*0x3c6 alias*/ + case 0x3cb: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) return svga_in(addr, svga); @@ -3103,7 +3111,7 @@ s3_in(uint16_t addr, void *priv) rs3 = !!(svga->crtc[0x55] & 0x02); temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -3138,6 +3146,7 @@ s3_in(uint16_t addr, void *priv) } break; case 0x30: + s3_log("[%04X:%08X]: Read CRTC30=%02x.\n", CS, cpu_state.pc, s3->id); return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); @@ -3168,6 +3177,7 @@ s3_in(uint16_t addr, void *priv) /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C to be mirrors of 59 and 5A. */ case 0x6b: + s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); @@ -3178,6 +3188,7 @@ s3_in(uint16_t addr, void *priv) return svga->crtc[0x6b]; break; case 0x6c: + s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return 0x00; @@ -3190,6 +3201,7 @@ s3_in(uint16_t addr, void *priv) default: break; } + s3_log("[%04X:%08X]: Read CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); return svga->crtc[svga->crtcreg]; default: @@ -3458,6 +3470,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -3640,6 +3653,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -3827,6 +3841,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -4039,6 +4054,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -4369,6 +4385,7 @@ s3_updatemapping(s3_t *s3) s3->linear_base &= 0x00ffffff; } + s3_log("LinearBase=%x, crtc58bits=%x.\n", s3->linear_base, svga->crtc[0x58] & 0x13); if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -4414,7 +4431,11 @@ s3_updatemapping(s3_t *s3) else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) s3->linear_base &= 0xfe000000; - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + s3_log("LinearBase update=%x, size=%x.\n", s3->linear_base, s3->linear_size); + if (s3->linear_base) + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + else + mem_mapping_disable(&s3->linear_mapping); } svga->fb_only = 1; } else { @@ -4437,8 +4458,12 @@ s3_updatemapping(s3_t *s3) } /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) - mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); + if (svga->crtc[0x53] & 0x08) { + if (s3->linear_base) + mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); + else + mem_mapping_disable(&s3->new_mmio_mapping); + } else mem_mapping_disable(&s3->new_mmio_mapping); } @@ -9178,11 +9203,13 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return 0x00; /*Supports VGA interface*/ else return 0x01; + break; case 0x0b: if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) return 0x03; else return 0x00; + break; case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; @@ -9461,6 +9488,7 @@ s3_reset(void *priv) svga->crtc[0x5a] = 0x0a; break; + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: @@ -9639,10 +9667,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION868: bios_fn = ROM_PHOENIX_VISION868; chip = S3_VISION868; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); break; case S3_DIAMOND_STEALTH64_964: bios_fn = ROM_DIAMOND_STEALTH64_964; @@ -9662,6 +9687,14 @@ s3_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); } break; + case S3_DIAMOND_STEALTH64_968: + bios_fn = ROM_DIAMOND_STEALTH64_968; + chip = S3_VISION968; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); + break; case S3_MIROVIDEO40SV_ERGO_968: bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI; chip = S3_VISION968; @@ -9675,10 +9708,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: bios_fn = ROM_PHOENIX_VISION968; chip = S3_VISION968; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); break; case S3_ELSAWIN2KPROX_964: bios_fn = ROM_ELSAWIN2KPROX_964; @@ -9843,7 +9873,7 @@ s3_init(const device_t *info) mem_mapping_disable(&s3->mmio_mapping); mem_mapping_disable(&s3->new_mmio_mapping); - if (chip == S3_VISION964 || chip == S3_VISION968) + if ((chip == S3_VISION964) || (chip == S3_VISION968)) svga_init(info, &s3->svga, s3, vram_size, s3_recalctimings, s3_in, s3_out, @@ -9881,16 +9911,14 @@ s3_init(const device_t *info) case S3_VISION968: switch (info->local) { + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; break; - case S3_SPEA_MERCURY_P64V: - case S3_MIROVIDEO40SV_ERGO_968: - svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; - break; default: + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; break; } break; @@ -10125,6 +10153,7 @@ s3_init(const device_t *info) } break; + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: @@ -10132,8 +10161,9 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision968*/ - s3->id_ext = s3->id_ext_pci = 0xf0; - s3->packed_mmio = 1; + s3->id_ext = 0xf0; + s3->id_ext_pci = s3->id_ext; + s3->packed_mmio = 1; if (s3->pci) { svga->crtc[0x53] = 0x18; svga->crtc[0x58] = 0x10; @@ -10147,6 +10177,7 @@ s3_init(const device_t *info) } switch (info->local) { + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: @@ -10376,6 +10407,12 @@ s3_diamond_stealth64_964_available(void) return rom_present(ROM_DIAMOND_STEALTH64_964); } +static int +s3_diamond_stealth64_968_available(void) +{ + return rom_present(ROM_DIAMOND_STEALTH64_968); +} + static int s3_mirovideo_40sv_ergo_968_pci_available(void) { @@ -10593,6 +10630,20 @@ static const device_config_t s3_968_config[] = { { .type = CONFIG_END } }; +static const device_config_t s3_standard_config2[] = { + { .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .selection = { + { .description = "2 MB", + .value = 2 }, + { .description = "4 MB", + .value = 4 }, + { .description = "" } } }, + { .type = CONFIG_END } +}; + const device_t s3_orchid_86c911_isa_device = { .name = "S3 86c911 ISA (Orchid Fahrenheit 1280)", .internal_name = "orchid_s3_911", @@ -10873,6 +10924,34 @@ const device_t s3_diamond_stealth64_964_pci_device = { .config = s3_standard_config }; +const device_t s3_diamond_stealth64_968_vlb_device = { + .name = "S3 Vision968 VLB (Diamond Stealth64 Video VRAM)", + .internal_name = "stealth64vv_vlb", + .flags = DEVICE_VLB, + .local = S3_DIAMOND_STEALTH64_968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_diamond_stealth64_968_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config2 +}; + +const device_t s3_diamond_stealth64_968_pci_device = { + .name = "S3 Vision968 PCI (Diamond Stealth64 Video VRAM)", + .internal_name = "stealth64vv_pci", + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH64_968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_diamond_stealth64_968_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config2 +}; + const device_t s3_9fx_771_pci_device = { .name = "S3 Vision968 PCI (Number 9 9FX 771)", .internal_name = "n9_9fx_771_pci", @@ -10901,20 +10980,6 @@ const device_t s3_phoenix_vision968_pci_device = { .config = s3_standard_config }; -const device_t s3_phoenix_vision968_vlb_device = { - .name = "S3 Vision968 VLB (Phoenix)", - .internal_name = "px_vision968_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION968, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, - { .available = s3_phoenix_vision968_available }, - .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config -}; - const device_t s3_mirovideo_40sv_ergo_968_pci_device = { .name = "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)", .internal_name = "mirovideo40sv_pci", @@ -11195,20 +11260,6 @@ const device_t s3_9fx_531_pci_device = { .config = s3_9fx_config }; -const device_t s3_phoenix_vision868_vlb_device = { - .name = "S3 Vision868 VLB (Phoenix)", - .internal_name = "px_vision868_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION868, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, - { .available = s3_phoenix_vision868_available }, - .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config -}; - const device_t s3_phoenix_vision868_pci_device = { .name = "S3 Vision868 PCI (Phoenix)", .internal_name = "px_vision868_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index b2686b2f3..c99a41544 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -188,6 +188,7 @@ video_cards[] = { { &s3_diamond_stealth64_pci_device }, { &s3_9fx_pci_device }, { &s3_phoenix_trio64_pci_device }, + { &s3_diamond_stealth64_968_pci_device }, { &s3_elsa_winner2000_pro_x_pci_device }, { &s3_mirovideo_40sv_ergo_968_pci_device }, { &s3_9fx_771_pci_device }, @@ -252,8 +253,7 @@ video_cards[] = { { &s3_9fx_vlb_device }, { &s3_phoenix_trio64_vlb_device }, { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, + { &s3_diamond_stealth64_968_vlb_device }, { &s3_stb_powergraph_64_video_vlb_device }, { &ht216_32_standalone_device }, { &tgui9400cxi_device }, From e9f19ec32b11a8d36ecb37af9b1b67200889dd98 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 23:54:39 +0200 Subject: [PATCH 554/690] Fix compile warning. See above. --- src/video/vid_s3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e74ff8c06..8ecd3711e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -145,7 +145,6 @@ static video_timings_t timing_s3_stealth64_vlb = { .type = VIDEO_BUS, .write_b = static video_timings_t timing_s3_stealth64_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_s3_vision864_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision864_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; -static video_timings_t timing_s3_vision868_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision868_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision964_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision964_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; From 11d7afd5780a5a7eb3fee560decc14934354bf63 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:13:29 +0200 Subject: [PATCH 555/690] Video changes part 3 (minor though) 1. Added an on-board S3 ViRGE DX (375) video card to the Intel AP440FX socket 8-based machine alongside its on-board CS4236B audio. 2. Sanity check for on-board S3 ViRGE devices. --- src/include/86box/video.h | 1 + src/machine/m_at_socket8.c | 7 +++++ src/machine/machine_table.c | 14 +++++----- src/video/vid_s3_virge.c | 51 +++++++++++++++++++++++++++---------- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e1a1a7502..83930122b 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -528,6 +528,7 @@ extern const device_t s3_diamond_stealth_2000_pci_device; extern const device_t s3_diamond_stealth_3000_pci_device; extern const device_t s3_stb_velocity_3d_pci_device; extern const device_t s3_virge_375_pci_device; +extern const device_t s3_virge_375_onboard_pci_device; extern const device_t s3_diamond_stealth_2000pro_pci_device; extern const device_t s3_virge_385_pci_device; extern const device_t s3_virge_357_pci_device; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e8262a6f4..8c2688c1a 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -33,6 +33,7 @@ #include <86box/timer.h> #include <86box/nvr.h> #include <86box/sio.h> +#include <86box/sound.h> #include <86box/hwm.h> #include <86box/spd.h> #include <86box/video.h> @@ -322,6 +323,12 @@ machine_at_ap440fx_init(const machine_t *model) device_add(&pc87307_device); device_add(&intel_flash_bxt_ami_device); + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cs4236b_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&s3_virge_375_onboard_pci_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4b91f1668..9d38686bd 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5182,7 +5182,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The board has a "ASII KB-100" which I was not able to find any information about, + /* The board has a "ASII KB-100" which I was not able to find any information about, but the BIOS sends commands C9 without a parameter and D5, both of which are Phoenix MultiKey commands. */ { @@ -10606,7 +10606,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. + /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ { .name = "[i430HX] Supermicro P55T2S", @@ -12658,7 +12658,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { @@ -13051,7 +13051,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13462,7 +13462,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_VIDEO | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 131072, @@ -13476,8 +13476,8 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, + .vid_device = &s3_virge_375_onboard_pci_device, + .snd_device = &cs4236b_device, .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4d64dffbd..26560c498 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -295,6 +295,8 @@ typedef struct virge_t { void *i2c, *ddc; int waiting; + + int has_bios; } virge_t; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -1070,14 +1072,13 @@ s3_virge_updatemapping(virge_t *virge) virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0); mem_mapping_disable(&virge->linear_mapping); } else { - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) { + if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) virge->linear_base &= 0xfe000000; - } else { + else virge->linear_base &= 0xfc000000; - } mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } @@ -4069,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x30: - ret = virge->pci_regs[0x30] & 0x01; + ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: - ret = virge->pci_regs[0x32]; + ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00; break; case 0x33: - ret = virge->pci_regs[0x33]; + ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00; break; case 0x34: @@ -4202,6 +4203,8 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x30: case 0x32: case 0x33: + if (!virge->has_bios) + return; virge->pci_regs[addr] = val; if (virge->pci_regs[0x30] & 0x01) { uint32_t biosaddr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); @@ -4337,7 +4340,8 @@ s3_virge_reset(void *priv) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - mem_mapping_disable(&virge->bios_rom.mapping); + if (virge->has_bios) + mem_mapping_disable(&virge->bios_rom.mapping); s3_virge_updatemapping(virge); @@ -4360,6 +4364,8 @@ s3_virge_init(const device_t *info) else virge->memory_size = device_get_config_int("memory"); + virge->has_bios = !!(info->local & 0x100); + switch (info->local) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; @@ -4374,7 +4380,7 @@ s3_virge_init(const device_t *info) bios_fn = ROM_STB_VELOCITY_3D; break; case S3_VIRGE_DX: - bios_fn = ROM_VIRGE_DX; + bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL; break; case S3_DIAMOND_STEALTH3D_2000PRO: bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; @@ -4408,11 +4414,12 @@ s3_virge_init(const device_t *info) rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&virge->bios_rom.mapping); } - mem_mapping_disable(&virge->bios_rom.mapping); - - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + mem_mapping_add(&virge->linear_mapping, 0, 0, + svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, @@ -4421,7 +4428,8 @@ s3_virge_init(const device_t *info) NULL, MEM_MAPPING_EXTERNAL, &virge->svga); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_add(&virge->mmio_mapping, 0, 0, + s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -4430,7 +4438,8 @@ s3_virge_init(const device_t *info) NULL, MEM_MAPPING_EXTERNAL, virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, + s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -4896,6 +4905,20 @@ const device_t s3_virge_375_pci_device = { .config = s3_virge_config }; +const device_t s3_virge_375_onboard_pci_device = { + .name = "S3 ViRGE/DX (375) On-Board PCI", + .internal_name = "virge375_onboard_pci", + .flags = DEVICE_PCI, + .local = S3_VIRGE_DX | 0x100, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, + { .available = NULL }, + .speed_changed = s3_virge_speed_changed, + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config +}; + const device_t s3_diamond_stealth_2000pro_pci_device = { .name = "S3 ViRGE/DX (Diamond Stealth 3D 2000 Pro) PCI", .internal_name = "stealth3d_2000pro_pci", From 3d74f43b9557e13c1d7c18cb4d4a744417315b78 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:25:29 +0200 Subject: [PATCH 556/690] NCR 53c400 timing fixes. See above (CD-ROM speeds too for said SCSI chips). --- src/scsi/scsi_ncr53c400.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index ca4d28ffb..0e772c16c 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -146,8 +146,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr400->busy = 1; - if (!(ncr->mode & MODE_MONITOR_BUSY)) - timer_on_auto(&ncr400->timer, ncr->period / 280.0); + if (!(ncr->mode & MODE_MONITOR_BUSY) && ((scsi_device_get_callback(dev) > 0.0))) + timer_on_auto(&ncr400->timer, ncr->period / 250.0); } } break; @@ -182,9 +182,12 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); if (ncr->mode & MODE_MONITOR_BUSY) timer_on_auto(&ncr400->timer, ncr->period); - else + else if (scsi_device_get_callback(dev) > 0.0) timer_on_auto(&ncr400->timer, 40.0); - ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); + else + timer_on_auto(&ncr400->timer, ncr->period); + + ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); } break; @@ -239,8 +242,8 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); - if (!(ncr->mode & MODE_MONITOR_BUSY)) - timer_on_auto(&ncr400->timer, ncr->period / 280.0); + if (!(ncr->mode & MODE_MONITOR_BUSY) && (scsi_device_get_callback(dev) > 0.0)) + timer_on_auto(&ncr400->timer, ncr->period / 250.0); } } break; From 0897eea7df06d51b7343e053e4e6060909c604f2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:43:00 +0200 Subject: [PATCH 557/690] Plus a compile fix. --- src/video/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 26560c498..352fe2bd8 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -1072,7 +1072,7 @@ s3_virge_updatemapping(virge_t *virge) virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); mem_mapping_disable(&virge->linear_mapping); } else { if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) From eff32906c5797a9a4a2ede39053ad94e20716e2e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 16:35:32 +0200 Subject: [PATCH 558/690] Fix onboard flag for actual onboard ViRGE BIOSes. So that ViRGE cards can work again without black screening. --- src/video/vid_s3_virge.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 352fe2bd8..7982f816e 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -296,7 +296,7 @@ typedef struct virge_t { int waiting; - int has_bios; + int onboard; } virge_t; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -4070,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x30: - ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00; + ret = (!virge->onboard) ? (virge->pci_regs[0x30] & 0x01) : 0x00; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: - ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00; + ret = (!virge->onboard) ? virge->pci_regs[0x32] : 0x00; break; case 0x33: - ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00; + ret = (!virge->onboard) ? virge->pci_regs[0x33] : 0x00; break; case 0x34: @@ -4203,7 +4203,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x30: case 0x32: case 0x33: - if (!virge->has_bios) + if (virge->onboard) return; virge->pci_regs[addr] = val; if (virge->pci_regs[0x30] & 0x01) { @@ -4340,7 +4340,7 @@ s3_virge_reset(void *priv) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - if (virge->has_bios) + if (!virge->onboard) mem_mapping_disable(&virge->bios_rom.mapping); s3_virge_updatemapping(virge); @@ -4364,7 +4364,7 @@ s3_virge_init(const device_t *info) else virge->memory_size = device_get_config_int("memory"); - virge->has_bios = !!(info->local & 0x100); + virge->onboard = !!(info->local & 0x100); switch (info->local) { case S3_VIRGE_325: @@ -4380,7 +4380,7 @@ s3_virge_init(const device_t *info) bios_fn = ROM_STB_VELOCITY_3D; break; case S3_VIRGE_DX: - bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL; + bios_fn = virge->onboard ? NULL : ROM_VIRGE_DX; break; case S3_DIAMOND_STEALTH3D_2000PRO: bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; From c68a4445ae9dd8bcbe95c0338875c3df9adf9ccf Mon Sep 17 00:00:00 2001 From: Shelby Jueden Date: Thu, 30 May 2024 08:13:04 -0700 Subject: [PATCH 559/690] Add years to the Machine Type names --- src/machine/machine_table.c | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9d38686bd..69a87e325 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -58,28 +58,28 @@ extern const device_t ps1_2011_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, - { "8088", MACHINE_TYPE_8088 }, - { "8086", MACHINE_TYPE_8086 }, - { "80286", MACHINE_TYPE_286 }, - { "i386SX", MACHINE_TYPE_386SX }, - { "486SLC", MACHINE_TYPE_486SLC }, - { "i386DX", MACHINE_TYPE_386DX }, - { "i386DX/i486", MACHINE_TYPE_386DX_486 }, - { "i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, - { "i486 (Socket 2)", MACHINE_TYPE_486_S2 }, - { "i486 (Socket 3)", MACHINE_TYPE_486_S3 }, - { "i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, - { "Socket 4", MACHINE_TYPE_SOCKET4 }, - { "Socket 5", MACHINE_TYPE_SOCKET5 }, - { "Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, - { "Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, - { "Super Socket 7", MACHINE_TYPE_SOCKETS7 }, - { "Socket 8", MACHINE_TYPE_SOCKET8 }, - { "Slot 1", MACHINE_TYPE_SLOT1 }, - { "Slot 1/2", MACHINE_TYPE_SLOT1_2 }, - { "Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, - { "Slot 2", MACHINE_TYPE_SLOT2 }, - { "Socket 370", MACHINE_TYPE_SOCKET370 }, + { "[1979] 8088", MACHINE_TYPE_8088 }, + { "[1978] 8086", MACHINE_TYPE_8086 }, + { "[1982] 80286", MACHINE_TYPE_286 }, + { "[1988] i386SX", MACHINE_TYPE_386SX }, + { "[1992] 486SLC", MACHINE_TYPE_486SLC }, + { "[1985] i386DX", MACHINE_TYPE_386DX }, + { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 }, + { "[1992] i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, + { "[1992] i486 (Socket 2)", MACHINE_TYPE_486_S2 }, + { "[1994] i486 (Socket 3)", MACHINE_TYPE_486_S3 }, + { "[1992] i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, + { "[1993] Socket 4", MACHINE_TYPE_SOCKET4 }, + { "[1994] Socket 5", MACHINE_TYPE_SOCKET5 }, + { "[1995] Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, + { "[1995] Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, + { "[1998] Super Socket 7", MACHINE_TYPE_SOCKETS7 }, + { "[1995] Socket 8", MACHINE_TYPE_SOCKET8 }, + { "[1996] Slot 1", MACHINE_TYPE_SLOT1 }, + { "[1998] Slot 1/2", MACHINE_TYPE_SLOT1_2 }, + { "[1998] Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, + { "[1998] Slot 2", MACHINE_TYPE_SLOT2 }, + { "[1998] Socket 370", MACHINE_TYPE_SOCKET370 }, { "Miscellaneous", MACHINE_TYPE_MISC } }; From 3f0e5ccf27c21c6d4ddfdf4ab3c9a5989321ca7e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:38:07 -0400 Subject: [PATCH 560/690] Add the lo-tech EMS Board --- src/device/isamem.c | 149 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 70f51ce8d..9ff61bc45 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -33,8 +33,10 @@ * * * Authors: Fred N. van Kempen, + * Jasmine Iwanek * - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 Fred N. van Kempen. + * Copyright 2022-2024 Jasmine Iwanek. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -98,6 +100,7 @@ #define ISAMEM_ABOVEBOARD_CARD 12 #define ISAMEM_BRAT_CARD 13 #define ISAMEM_EV165A_CARD 14 +#define ISAMEM_LOTECH_CARD 15 #define ISAMEM_DEBUG 0 @@ -318,6 +321,26 @@ ems_read(uint16_t port, void *priv) return ret; } +/* Handle a READ operation from one of our registers. */ +static uint8_t +consecutive_ems_read(uint16_t port, void *priv) +{ + const memdev_t *dev = (memdev_t *) priv; + uint8_t ret = 0xff; + int vpage; + + /* Get the viewport page number. */ + vpage = (port - dev->base_addr); + + isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage); + + ret = dev->ems[vpage].page; + if (dev->ems[vpage].enabled) + ret |= 0x80; + + return ret; +} + /* Handle a WRITE operation to one of our registers. */ static void ems_write(uint16_t port, uint8_t val, void *priv) @@ -393,6 +416,47 @@ ems_write(uint16_t port, uint8_t val, void *priv) } } +/* Handle a WRITE operation to one of our registers. */ +static void +consecutive_ems_write(uint16_t port, uint8_t val, void *priv) +{ + memdev_t *dev = (memdev_t *) priv; + int vpage; + + /* Get the viewport page number. */ + vpage = (port - dev->base_addr); + + isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage); + + isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val); + /* Set the page number. */ + dev->ems[vpage].enabled = (val & 0xff); + dev->ems[vpage].page = (val & 0xff); + + /* Make sure we can do that.. */ + if (dev->flags & FLAG_CONFIG) { + if (dev->ems[vpage].page < dev->ems_pages) { + /* Pre-calculate the page address in EMS RAM. */ + dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0xff) * EMS_PGSIZE); + } else { + /* That page does not exist. */ + dev->ems[vpage].enabled = 0; + } + + if (dev->ems[vpage].enabled) { + /* Update the EMS RAM address for this page. */ + mem_mapping_set_exec(&dev->ems[vpage].mapping, + dev->ems[vpage].addr); + + /* Enable this page. */ + mem_mapping_enable(&dev->ems[vpage].mapping); + } else { + /* Disable this page. */ + mem_mapping_disable(&dev->ems[vpage].mapping); + } + } +} + /* Initialize the device for use. */ static void * isamem_init(const device_t *info) @@ -476,6 +540,13 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; + case ISAMEM_LOTECH_CARD: + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; + dev->frame_addr = device_get_config_hex20("frame"); + dev->flags |= (FLAG_EMS | FLAG_CONFIG); + default: break; } @@ -663,9 +734,14 @@ isamem_init(const device_t *info) mem_mapping_disable(&dev->ems[i].mapping); /* Set up an I/O port handler. */ - io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2, - ems_read, NULL, NULL, ems_write, NULL, NULL, dev); + if (dev->board != ISAMEM_LOTECH_CARD) + io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2, + ems_read, NULL, NULL, ems_write, NULL, NULL, dev); } + + if (dev->board == ISAMEM_LOTECH_CARD) + io_sethandler(dev->base_addr, 4, + consecutive_ems_read, NULL, NULL, consecutive_ems_write, NULL, NULL, dev); } /* Let them know our device instance. */ @@ -1439,6 +1515,72 @@ static const device_t brat_device = { }; #endif +static const device_config_t lotech_config[] = { +// clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0260, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "260H", .value = 0x0260 }, + { .description = "264H", .value = 0x0264 }, + { .description = "268H", .value = 0x0268 }, + { .description = "26CH", .value = 0x026C }, + { .description = "" } + }, + }, + { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xe0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0x00000 }, + { .description = "C000H", .value = 0xC0000 }, + { .description = "D000H", .value = 0xD0000 }, + { .description = "E000H", .value = 0xE0000 }, + { .description = "" } + }, + }, + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 2048, + .file_filter = "", + .spinner = { + .min = 512, + .max = 4096, + .step = 512 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +static const device_t lotech_device = { + .name = "Lo-tech EMS Board", + .internal_name = "lotechems", + .flags = DEVICE_ISA, + .local = ISAMEM_LOTECH_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lotech_config +}; + #if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) static const device_config_t rampage_config[] = { // clang-format off @@ -1676,6 +1818,7 @@ static const struct { #if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) { &iab_device }, #endif + { &lotech_device }, { NULL } // clang-format on }; From 028142136a4a031c0ead105b27b9cd0431ed8069 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:44:04 -0400 Subject: [PATCH 561/690] Fix Max EMS per board --- src/device/isamem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 9ff61bc45..fea9c0d88 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -108,7 +108,7 @@ #define RAM_UMAMEM (384 << 10) /* upper memory block */ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ -#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ +#define EMS_MAXSIZE (4096 << 10) /* max EMS memory size */ #define EMS_PGSIZE (16 << 10) /* one page is this big */ #define EMS_MAXPAGE 4 /* number of viewport pages */ @@ -696,7 +696,7 @@ isamem_init(const device_t *info) /* If EMS is enabled, use the remainder for EMS. */ if (dev->flags & FLAG_EMS) { - /* EMS 3.2 cannot have more than 2048KB per board. */ + /* EMS 3.2 cannot have more than 4096KB per board. */ t = k; if (t > EMS_MAXSIZE) t = EMS_MAXSIZE; From bd28ad2fe44f70d75b00db38049e1db55acab032 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:45:33 -0400 Subject: [PATCH 562/690] Fix trivial bug in EMS5150 --- src/device/isamem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index fea9c0d88..09374f30d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -499,6 +499,7 @@ isamem_init(const device_t *info) case ISAMEM_EMS5150_CARD: /* Micro Mainframe EMS-5150(T) */ dev->base_addr = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; dev->frame_addr = 0xD0000; dev->flags |= (FLAG_EMS | FLAG_CONFIG); break; From ab137e999e9339f660219c3df4186a99b7278f04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 1 Jun 2024 02:00:22 +0200 Subject: [PATCH 563/690] VIA Apollo VPX: Fix SMRAM handling. --- src/chipset/via_apollo.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 7c1203c3a..20e2c7f74 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -444,7 +444,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); break; } - else + else if (dev->id == VIA_595) switch (val & 0x03) { case 0x00: apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0); @@ -468,6 +468,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) default: break; } + else { + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, + (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01), + dev->pci_conf[0x63] & 0x01); + flushmmucache(); + } break; case 0x65: if (dev->id == VIA_585) @@ -532,6 +538,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0x6d] = (dev->pci_conf[0x6d] & ~0x7f) | (val & 0x7f); else dev->pci_conf[0x6d] = val; + if (dev->id == VIA_585) { + smram_disable_all(); + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, + (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01), + dev->pci_conf[0x63] & 0x01); + flushmmucache(); + } break; case 0x6e: if ((dev->id == VIA_595) || (dev->id == VIA_694)) From b7994ab917a9657290279438550208deca8358fa Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 22:40:52 -0400 Subject: [PATCH 564/690] A few formatting cleanups in fdd.c --- src/floppy/fdd.c | 83 +++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 72d6ac648..32cc2a570 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -104,7 +104,7 @@ static const struct void (*close)(int drive); int size; } loaders[] = { - {"001", img_load, img_close, -1}, + { "001", img_load, img_close, -1}, { "002", img_load, img_close, -1}, { "003", img_load, img_close, -1}, { "004", img_load, img_close, -1}, @@ -139,59 +139,42 @@ static const struct { 0, 0, 0, 0 } }; -static const struct -{ +static const struct { int max_track; int flags; const char *name; const char *internal_name; -} drive_types[] = -{ - { /*None*/ - 0, 0, "None", "none" - }, - { /*5.25" 1DD*/ - 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd" - }, - { /*5.25" DD*/ - 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" - }, - { /*5.25" QD*/ - 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" - }, - { /*5.25" HD PS/2*/ - 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" - }, - { /*5.25" HD*/ - 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" - }, - { /*5.25" HD Dual RPM*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" - }, - { /*3.5" 1DD*/ - 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" - }, - { /*3.5" DD*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" - }, - { /*3.5" HD PS/2*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" - }, - { /*3.5" HD*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" - }, - { /*3.5" HD PC-98*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" - }, - { /*3.5" HD 3-Mode*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" - }, - { /*3.5" ED*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" - }, - { /*End of list*/ - -1, -1, "", "" - } +} drive_types[] = { + /* None */ + { 0, 0, "None", "none" }, + /* 5.25" 1DD */ + { 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd" }, + /* 5.25" DD */ + { 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" }, + /* 5.25" QD */ + { 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" }, + /* 5.25" HD PS/2 */ + { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" }, + /* 5.25" HD */ + { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" }, + /* 5.25" HD Dual RPM */ + { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" }, + /* 3.5" 1DD */ + { 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" }, + /* 3.5" DD */ + { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" }, + /* 3.5" HD PS/2 */ + { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" }, + /* 3.5" HD */ + { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" }, + /* 3.5" HD PC-98 */ + { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" }, + /* 3.5" HD 3-Mode */ + { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" }, + /* 3.5" ED */ + { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" }, + /* End of list */ + { -1, -1, "", "" } }; #ifdef ENABLE_FDD_LOG From 33eb7993fb35076cf521c3c2769f0ff0f1a2485f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 23:42:07 -0400 Subject: [PATCH 565/690] Add some notes on drive equivalents --- src/floppy/fdd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 32cc2a570..351742b44 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -161,17 +161,17 @@ static const struct { { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" }, /* 3.5" 1DD */ { 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" }, - /* 3.5" DD */ + /* 3.5" DD, Equivalent to TEAC FD-235F */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" }, /* 3.5" HD PS/2 */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" }, - /* 3.5" HD */ + /* 3.5" HD, Equivalent to TEAC FD-235HF */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" }, /* 3.5" HD PC-98 */ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" }, - /* 3.5" HD 3-Mode */ + /* 3.5" HD 3-Mode, Equivalent to TEAC FD-235HG */ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" }, - /* 3.5" ED */ + /* 3.5" ED, Equivalent to TEAC FD-235J */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" }, /* End of list */ { -1, -1, "", "" } From 77d1da5e8ff582adcb2af4162a31e3b3da0191aa Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 23:50:48 -0400 Subject: [PATCH 566/690] Add ED dual RPM drive --- src/floppy/fdd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 351742b44..8d3d40ecc 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -173,6 +173,8 @@ static const struct { { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" }, /* 3.5" ED, Equivalent to TEAC FD-235J */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" }, + /* 3.5" ED Dual RPM, Equivalent to TEAC FD-335J */ + { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M 300/360 RPM", "35_2ed_dualrpm" }, /* End of list */ { -1, -1, "", "" } }; From 8e556ada7ec6fc9ec48078b50d66c24cc3dc02a1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 23:51:55 -0400 Subject: [PATCH 567/690] Add (commented out) eqiv of the TEAC FD-235GF Commented out because it could actually be our existing 35_2hd_nec, we need to check whether this needs the INVERT_DENSEL flag or not --- src/floppy/fdd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 8d3d40ecc..81edcc8b8 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -167,6 +167,8 @@ static const struct { { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" }, /* 3.5" HD, Equivalent to TEAC FD-235HF */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" }, + /* TODO: 3.5" DD, Equivalent to TEAC FD-235GF */ +// { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.25M", "35_2hd_2mode" }, /* 3.5" HD PC-98 */ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" }, /* 3.5" HD 3-Mode, Equivalent to TEAC FD-235HG */ From af03a0147e3b6c74b65911c7348cd9656300c1a9 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 02:06:05 -0400 Subject: [PATCH 568/690] Two fixes to lo-tech EMS board --- src/device/isamem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 09374f30d..df5161bb6 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -430,14 +430,14 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv) isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val); /* Set the page number. */ - dev->ems[vpage].enabled = (val & 0xff); - dev->ems[vpage].page = (val & 0xff); + dev->ems[vpage].enabled = 1; + dev->ems[vpage].page = val; /* Make sure we can do that.. */ if (dev->flags & FLAG_CONFIG) { if (dev->ems[vpage].page < dev->ems_pages) { /* Pre-calculate the page address in EMS RAM. */ - dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0xff) * EMS_PGSIZE); + dev->ems[vpage].addr = dev->ram + dev->ems_start + (val * EMS_PGSIZE); } else { /* That page does not exist. */ dev->ems[vpage].enabled = 0; @@ -1543,7 +1543,6 @@ static const device_config_t lotech_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "Disabled", .value = 0x00000 }, { .description = "C000H", .value = 0xC0000 }, { .description = "D000H", .value = 0xD0000 }, { .description = "E000H", .value = 0xE0000 }, From 066f153dee624310f29f5df67f2b99ac72e1a07f Mon Sep 17 00:00:00 2001 From: Jose Phillips Date: Sat, 1 Jun 2024 18:39:40 -0500 Subject: [PATCH 569/690] Added Machine Motherboard Acer100T --- src/chipset/CMakeLists.txt | 2 +- src/chipset/ali1409.c | 199 +++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 1 + src/include/86box/video.h | 1 + src/machine/m_at_286_386sx.c | 25 +++++ src/machine/machine_table.c | 40 +++++++ src/video/vid_oak_oti.c | 80 ++++++++++++-- 8 files changed, 341 insertions(+), 8 deletions(-) create mode 100644 src/chipset/ali1409.c diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0406ea0b8..4daccd2d8 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -14,7 +14,7 @@ # add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c - ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c + ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c ali1409.c headland.c ims8848.c intel_82335.c compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c diff --git a/src/chipset/ali1409.c b/src/chipset/ali1409.c new file mode 100644 index 000000000..3e4286f80 --- /dev/null +++ b/src/chipset/ali1409.c @@ -0,0 +1,199 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M1409 chipset. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering. + * + * + * + * Authors: Jose Phillips, + * Sarah Walker, + * + * Copyright 2024 Jose Phillips. + * Copyright 2008-2018 Sarah Walker. + */ + + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/apm.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/smram.h> +#include <86box/chipset.h> + + + +#ifdef ENABLE_ALI1409_LOG +int ali1409_do_log = ENABLE_ALI1409_LOG; + +static void +ali1409_log(const char *fmt, ...) +{ + va_list ap; + + if (ali1409_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ali1409_log(fmt, ...) +#endif + +typedef struct ali_1409_t { + uint8_t is_g; + uint8_t index; + uint8_t cfg_locked; + uint8_t reg_57h; + uint8_t regs[256]; + uint8_t last_reg; +} ali1409_t; + + +static void +ali1409_write(uint16_t addr, uint8_t val, void *priv) +{ + ali1409_t *dev = (ali1409_t *) priv; + ali1409_log ("INPUT:addr %02x ,Value %02x \n" , addr , val); + + if (addr & 1) { + if (dev->cfg_locked) { + if (dev->last_reg == 0x14 && val == 0x09) + dev->cfg_locked = 0; + + dev->last_reg = val; + return; + } + + if (dev->index == 0xff && val == 0xff) + dev->cfg_locked = 1; + else { + ali1409_log("Write reg %02x %02x %08x\n", dev->index, val, cs); + dev->regs[dev->index] = val; + + switch (dev->index) { + case 0xa: + switch ((val >> 4) & 3) { + case 0: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + case 0xb: + switch ((val >> 4) & 3) { + case 0: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 2: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY| MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + } + } + } else + dev->index = val; +} + + +static uint8_t +ali1409_read(uint16_t addr, void *priv) +{ + ali1409_log ("reading at %02X\n",addr); + const ali1409_t *dev = (ali1409_t *) priv; + uint8_t ret = 0xff; + + if (dev->cfg_locked) + ret = 0xff; + if (addr & 1) { + if ((dev->index >= 0xc0 || dev->index == 0x20) && cpu_iscyrix) + ret = 0xff; + ret = dev->regs[dev->index]; + } else + ret = dev->index; + return ret; +} + + + +static void +ali1409_close(void *priv) +{ + ali1409_t *dev = (ali1409_t *) priv; + + free(dev); +} + +static void * +ali1409_init(const device_t *info) +{ + ali1409_t *dev = (ali1409_t *) malloc(sizeof(ali1409_t)); + memset(dev, 0, sizeof(ali1409_t)); + + dev->cfg_locked = 1; + + /* M1409 Ports: + 22h Index Port + 23h Data Port + */ + + ali1409_log ("Bus speed: %i",cpu_busspeed); + + + io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); + io_sethandler(0x037f, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); + io_sethandler(0x03f3, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); + + return dev; +} + +const device_t ali1409_device = { + .name = "ALi M1409", + .internal_name = "ali1409", + .flags = 0, + .local = 0, + .init = ali1409_init, + .close = ali1409_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index d5a96baf9..4be7c2ae2 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -24,6 +24,7 @@ extern const device_t acc2168_device; extern const device_t ali1217_device; extern const device_t ali1429_device; extern const device_t ali1429g_device; +extern const device_t ali1409_device; extern const device_t ali1435_device; extern const device_t ali1489_device; extern const device_t ali1531_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index a5b922358..7ff00ed52 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -481,6 +481,7 @@ extern int machine_at_325ax_init(const machine_t *); extern int machine_at_mr1217_init(const machine_t *); extern int machine_at_pja511m_init(const machine_t *); extern int machine_at_prox1332_init(const machine_t *); +extern int machine_at_acer100t_init(const machine_t *); extern int machine_at_awardsx_init(const machine_t *); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 83930122b..ed7064f9c 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -453,6 +453,7 @@ extern const device_t oti037c_device; extern const device_t oti067_device; extern const device_t oti067_acer386_device; extern const device_t oti067_ama932j_device; +extern const device_t oti077_acer100t_device; extern const device_t oti077_device; /* Paradise/WD (S)VGA */ diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index b2470bae2..a1c3d7772 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -705,6 +705,31 @@ machine_at_awardsx_init(const machine_t *model) return ret; } +int +machine_at_acer100t_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acer100t/acer386.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ps2_ide_init(model); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&ali1409_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&oti077_acer100t_device); + + + return ret; +} + + int machine_at_arb1374_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 69a87e325..f97fab901 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4168,6 +4168,46 @@ const machine_t machines[] = { .vid_device = NULL, .snd_device = NULL, .net_device = NULL + }, + { + .name = "[ALI M1409] Acer 100T", + .internal_name = "acer100t", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1409, + .init = machine_at_acer100t_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 16000000, + .max_bus = 25000000, /* Limited to 25 due a inaccurate cpu speed */ + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0, + + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/ + .ram = { + .min = 2048, + .max = 16256, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &oti077_acer100t_device, + .snd_device = NULL, + .net_device = NULL }, /* Has IBM PS/2 Type 1 KBC firmware. */ { diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index f5bc449e6..f21e9d66c 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -36,13 +36,16 @@ #define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM" #define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM" #define BIOS_077_PATH "roms/video/oti/oti077.vbi" +#define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN" + enum { OTI_037C = 0, OTI_067 = 2, OTI_067_AMA932J = 3, OTI_067_M300 = 4, - OTI_077 = 5 + OTI_077 = 5, + OTI_077_ACER100T = 6 }; typedef struct { @@ -92,7 +95,7 @@ oti_out(uint16_t addr, uint8_t val, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077) + if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); @@ -153,7 +156,7 @@ oti_out(uint16_t addr, uint8_t val, void *priv) mem_mapping_disable(&svga->mapping); else mem_mapping_enable(&svga->mapping); - } else if (oti->chip_id == OTI_077) { + } else if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) { svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; switch ((val & 0xc0) >> 6) { @@ -238,7 +241,7 @@ oti_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077) + if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); return svga_in(addr, svga); @@ -464,6 +467,12 @@ oti_init(const device_t *info) oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); break; + case OTI_077_ACER100T: + romfn = BIOS_077_ACER100T_PATH; + oti->vram_size = device_get_config_int("memory"); + oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ + io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); + break; default: break; @@ -476,12 +485,19 @@ oti_init(const device_t *info) oti->vram_mask = (oti->vram_size << 10) - 1; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); + if (oti->chip_id == OTI_077_ACER100T){ + /* josephillips: Required to show all BIOS + information on Acer 100T only + */ + video_inform(0x1,&timing_oti); + }else{ + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); + } svga_init(info, &oti->svga, oti, oti->vram_size << 10, oti_recalctimings, oti_in, oti_out, NULL, NULL); - if (oti->chip_id == OTI_077) + if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ io_sethandler(0x03c0, 32, @@ -489,7 +505,7 @@ oti_init(const device_t *info) oti->svga.miscout = 1; oti->svga.packed_chain4 = 1; - + return oti; } @@ -531,6 +547,12 @@ oti067_ama932j_available(void) return (rom_present(BIOS_067_AMA932J_PATH)); } +static int +oti077_acer100t_available(void) +{ + return (rom_present(BIOS_077_ACER100T_PATH)); +} + static int oti067_077_available(void) { @@ -597,6 +619,35 @@ static const device_config_t oti067_ama932j_config[] = { } }; +static const device_config_t oti077_acer100t_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 kB", + .value = 256 + }, + { + .description = "512 kB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + static const device_config_t oti077_config[] = { { .name = "memory", @@ -683,6 +734,21 @@ const device_t oti067_ama932j_device = { .config = oti067_ama932j_config }; +const device_t oti077_acer100t_device = { + .name = "Oak OTI-077 (Acer 100T)", + .internal_name = "oti077_acer100t", + .flags = DEVICE_ISA, + .local = 6, + .init = oti_init, + .close = oti_close, + .reset = NULL, + { .available = oti077_acer100t_available }, + .speed_changed = oti_speed_changed, + .force_redraw = oti_force_redraw, + .config = oti077_acer100t_config +}; + + const device_t oti077_device = { .name = "Oak OTI-077", .internal_name = "oti077", From ca74d3a5bdf46d4cbb4a50998498dc41f66e0673 Mon Sep 17 00:00:00 2001 From: Jose Phillips Date: Sat, 1 Jun 2024 21:24:02 -0500 Subject: [PATCH 570/690] Fixing bus type --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f97fab901..9723d53cd 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4190,7 +4190,7 @@ const machine_t machines[] = { .max_multi = 0, }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2, .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/ .ram = { .min = 2048, From b5312b949944b5842640cf0191c6254aa6f98749 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 1 Jun 2024 04:20:07 -0400 Subject: [PATCH 571/690] Add BocaRAM/XT --- src/device/isamem.c | 76 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index df5161bb6..571e5bc8d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -98,9 +98,10 @@ #define ISAMEM_EV159_CARD 10 #define ISAMEM_RAMPAGEXT_CARD 11 #define ISAMEM_ABOVEBOARD_CARD 12 -#define ISAMEM_BRAT_CARD 13 -#define ISAMEM_EV165A_CARD 14 -#define ISAMEM_LOTECH_CARD 15 +#define ISAMEM_BRXT_CARD 13 +#define ISAMEM_BRAT_CARD 14 +#define ISAMEM_EV165A_CARD 15 +#define ISAMEM_LOTECH_CARD 16 #define ISAMEM_DEBUG 0 @@ -533,7 +534,8 @@ isamem_init(const device_t *info) case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ dev->base_addr = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); - dev->start_addr = device_get_config_int("start"); + if (!!device_get_config_int("start")) + dev->start_addr = device_get_config_int("start"); dev->frame_addr = device_get_config_hex20("frame"); if (!!device_get_config_int("width")) dev->flags |= FLAG_WIDE; @@ -541,6 +543,7 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; + case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ case ISAMEM_LOTECH_CARD: dev->base_addr = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); @@ -1421,6 +1424,70 @@ static const device_t ev165a_device = { .config = ev165a_config }; +static const device_config_t brxt_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0268, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "208H", .value = 0x0208 }, + { .description = "218H", .value = 0x0218 }, + { .description = "258H", .value = 0x0258 }, + { .description = "268H", .value = 0x0268 }, + { .description = "" } + }, + }, + { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "D000H", .value = 0xD0000 }, + { .description = "E000H", .value = 0xE0000 }, + { .description = "" } + }, + }, + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 512, + .file_filter = "", + .spinner = { + .min = 0, + .max = 2048, + .step = 512 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t brxt_device = { + .name = "BocaRAM/XT", + .internal_name = "brxt", + .flags = DEVICE_ISA, + .local = ISAMEM_BRXT_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = brxt_config +}; + #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) static const device_config_t brat_config[] = { // clang-format off @@ -1809,6 +1876,7 @@ static const struct { { &ems5150_device }, { &ev159_device }, { &ev165a_device }, + { &brxt_device }, #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) { &brat_device }, #endif From c39abcc09cd1fd840c1a23280f826015488aae5a Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 1 Jun 2024 14:17:55 -0400 Subject: [PATCH 572/690] A few fixes to to the BocaRAM/AT --- src/device/isamem.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 571e5bc8d..a825d6a2a 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -411,7 +411,7 @@ ems_write(uint16_t port, uint8_t val, void *priv) if (val) dev->flags |= FLAG_CONFIG; break; - + default: break; } @@ -537,6 +537,7 @@ isamem_init(const device_t *info) if (!!device_get_config_int("start")) dev->start_addr = device_get_config_int("start"); dev->frame_addr = device_get_config_hex20("frame"); + dev->flags |= (FLAG_EMS); if (!!device_get_config_int("width")) dev->flags |= FLAG_WIDE; if (!!device_get_config_int("speed")) @@ -1496,7 +1497,7 @@ static const device_config_t brat_config[] = { .description = "Address", .type = CONFIG_HEX16, .default_string = "", - .default_int = 0x0258, + .default_int = 0x0268, .file_filter = "", .spinner = { 0 }, .selection = { @@ -1512,11 +1513,10 @@ static const device_config_t brat_config[] = { .description = "Frame Address", .type = CONFIG_HEX20, .default_string = "", - .default_int = 0, + .default_int = 0xD0000, .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "Disabled", .value = 0x00000 }, { .description = "D000H", .value = 0xD0000 }, { .description = "E000H", .value = 0xE0000 }, { .description = "" } @@ -1555,15 +1555,28 @@ static const device_config_t brat_config[] = { .description = "Memory Size", .type = CONFIG_SPINNER, .default_string = "", - .default_int = 128, + .default_int = 512, .file_filter = "", .spinner = { .min = 0, - .max = 8192, + .max = 4096, .step = 512 }, .selection = { { 0 } } }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { + .min = 0, + .max = 14336, + .step = 512 + }, + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; From d0e01cfa5e4aee22b2f054df2bf07d506e736324 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 1 Jun 2024 23:57:22 -0400 Subject: [PATCH 573/690] Corrections to AST Rampage --- src/device/isamem.c | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index a825d6a2a..55caf23ce 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1662,6 +1662,8 @@ static const device_t lotech_device = { }; #if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) +// TODO: Dual Paging support +// TODO: Conventional memory suppport static const device_config_t rampage_config[] = { // clang-format off { @@ -1699,45 +1701,17 @@ static const device_config_t rampage_config[] = { { .description = "" } }, }, - { - .name = "width", - .description = "I/O Width", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 8, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "8-bit", .value = 8 }, - { .description = "16-bit", .value = 16 }, - { .description = "" } - }, - }, - { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Standard", .value = 0 }, - { .description = "High-Speed", .value = 1 }, - { .description = "" } - } - }, { .name = "size", .description = "Memory Size", .type = CONFIG_SPINNER, .default_string = "", - .default_int = 128, + .default_int = 256, /* Technically 128k, but banks 2-7 must be 256, headaches elsewise */ .file_filter = "", .spinner = { - .min = 0, - .max = 8192, - .step = 128 + .min = 256, + .max = 2048, + .step = 256 }, .selection = { { 0 } } }, From d6baa289922b09fcfd72df409edb5bdcbef81c0c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 3 Jun 2024 03:37:47 +0200 Subject: [PATCH 574/690] ISA memory cards: Implement EMS frame address recalculation. --- src/device/isamem.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 55caf23ce..0eac6d097 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -363,27 +363,24 @@ ems_write(uint16_t port, uint8_t val, void *priv) dev->ems[vpage].enabled = (val & 0x80); dev->ems[vpage].page = (val & 0x7f); - /* Make sure we can do that.. */ - if (dev->flags & FLAG_CONFIG) { - if (dev->ems[vpage].page < dev->ems_pages) { - /* Pre-calculate the page address in EMS RAM. */ - dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE); - } else { - /* That page does not exist. */ - dev->ems[vpage].enabled = 0; - } + if (dev->ems[vpage].page < dev->ems_pages) { + /* Pre-calculate the page address in EMS RAM. */ + dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE); + } else { + /* That page does not exist. */ + dev->ems[vpage].enabled = 0; + } - if (dev->ems[vpage].enabled) { - /* Update the EMS RAM address for this page. */ - mem_mapping_set_exec(&dev->ems[vpage].mapping, - dev->ems[vpage].addr); + if (dev->ems[vpage].enabled) { + /* Update the EMS RAM address for this page. */ + mem_mapping_set_exec(&dev->ems[vpage].mapping, + dev->ems[vpage].addr); - /* Enable this page. */ - mem_mapping_enable(&dev->ems[vpage].mapping); - } else { - /* Disable this page. */ - mem_mapping_disable(&dev->ems[vpage].mapping); - } + /* Enable this page. */ + mem_mapping_enable(&dev->ems[vpage].mapping); + } else { + /* Disable this page. */ + mem_mapping_disable(&dev->ems[vpage].mapping); } break; @@ -408,8 +405,13 @@ ems_write(uint16_t port, uint8_t val, void *priv) */ isamem_log("EMS: write(%02x) to register 1 !\n"); dev->ems[vpage].frame = val; - if (val) - dev->flags |= FLAG_CONFIG; + dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) || + ((dev->ems[1].frame & 0x80) >> 6) || + ((dev->ems[0].frame & 0x80) >> 7)) << 14); + mem_mapping_disable(&dev->ems[0].mapping); + mem_mapping_disable(&dev->ems[1].mapping); + mem_mapping_disable(&dev->ems[2].mapping); + mem_mapping_disable(&dev->ems[3].mapping); break; default: From 27248397d25dae91d37dc9b9773ac7839fb72b91 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 3 Jun 2024 04:01:00 +0200 Subject: [PATCH 575/690] ATi Mach 8: Fix a warning. --- src/video/vid_ati_mach8.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 83edb4355..6abdc213a 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -3451,8 +3451,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u static void mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - uint8_t old = 0; - if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9) mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); From 9d7cffb7a84a3bb847aa6b2fa696e60acd8fb7fe Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 3 Jun 2024 00:07:32 -0400 Subject: [PATCH 576/690] Improve EMS logging --- src/device/isamem.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 0eac6d097..2c76939e2 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -315,9 +315,7 @@ ems_read(uint16_t port, void *priv) break; } -#if ISAMEM_DEBUG - isamem_log("ISAMEM: read(%04x) = %02x)\n", port, ret); -#endif + isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage); return ret; } @@ -333,12 +331,13 @@ consecutive_ems_read(uint16_t port, void *priv) /* Get the viewport page number. */ vpage = (port - dev->base_addr); - isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage); - + ret = dev->ems[vpage].page; if (dev->ems[vpage].enabled) ret |= 0x80; + isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage); + return ret; } @@ -353,12 +352,10 @@ ems_write(uint16_t port, uint8_t val, void *priv) vpage = (port / EMS_PGSIZE); port &= (EMS_PGSIZE - 1); -#if ISAMEM_DEBUG - isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage); -#endif - switch (port - dev->base_addr) { case 0x0000: /* page mapping registers */ + isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! page=%d\n", port, val, vpage); + /* Set the page number. */ dev->ems[vpage].enabled = (val & 0x80); dev->ems[vpage].page = (val & 0x7f); @@ -385,6 +382,8 @@ ems_write(uint16_t port, uint8_t val, void *priv) break; case 0x0001: /* page frame registers */ + isamem_log("ISAMEM: write(%04x, %02x) to page frame registers! page=%d\n", port, val, vpage); + /* * The EV-159 EMM driver configures the frame address * by setting bits in these registers. The information @@ -403,7 +402,6 @@ ems_write(uint16_t port, uint8_t val, void *priv) * 80 c0 e0 DC000 * 80 c0 e0 E0000 */ - isamem_log("EMS: write(%02x) to register 1 !\n"); dev->ems[vpage].frame = val; dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) || ((dev->ems[1].frame & 0x80) >> 6) || @@ -429,9 +427,8 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv) /* Get the viewport page number. */ vpage = (port - dev->base_addr); - isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage); + isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! (page=%d)\n", port, val, vpage); - isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val); /* Set the page number. */ dev->ems[vpage].enabled = 1; dev->ems[vpage].page = val; From 99957425f022ddbdbf1ba7d26ff2a9cb32d3061d Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 3 Jun 2024 00:39:05 -0400 Subject: [PATCH 577/690] Yet more improvements to Rampage/XT --- src/device/isamem.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 2c76939e2..ba60ddd2a 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -529,6 +529,14 @@ isamem_init(const device_t *info) break; case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */ + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = dev->total_size; + dev->flags |= FLAG_EMS; + dev->frame_addr = 0xE0000; + break; + case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */ case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ dev->base_addr = device_get_config_hex16("base"); @@ -1670,7 +1678,7 @@ static const device_config_t rampage_config[] = { .description = "Address", .type = CONFIG_HEX16, .default_string = "", - .default_int = 0x0258, + .default_int = 0x0218, .file_filter = "", .spinner = { 0 }, .selection = { @@ -1684,22 +1692,6 @@ static const device_config_t rampage_config[] = { { .description = "" } }, }, - { - .name = "frame", - .description = "Frame Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Disabled", .value = 0x00000 }, - { .description = "C000H", .value = 0xC0000 }, - { .description = "D000H", .value = 0xD0000 }, - { .description = "E000H", .value = 0xE0000 }, - { .description = "" } - }, - }, { .name = "size", .description = "Memory Size", @@ -1714,6 +1706,19 @@ static const device_config_t rampage_config[] = { }, .selection = { { 0 } } }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 640, + .file_filter = "", + .spinner = { + .min = 0, + .max = 640, + .step = 64 + }, + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; From a529359993e6fee41c4099817ca991a340911795 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Mon, 3 Jun 2024 22:40:46 -0300 Subject: [PATCH 578/690] config: Fix incorrect saving of cpu_override_interpreter --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 77ec89125..ab23ddb4f 100644 --- a/src/config.c +++ b/src/config.c @@ -1927,7 +1927,7 @@ save_machine(void) else ini_section_delete_var(cat, "cpu_override"); if (cpu_override_interpreter) - ini_section_set_int(cat, "cpu_override_interpreter", cpu_override); + ini_section_set_int(cat, "cpu_override_interpreter", cpu_override_interpreter); else ini_section_delete_var(cat, "cpu_override_interpreter"); From 0c6f54ac0e8656c9087fe3dd136984be9d0fc169 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 5 Jun 2024 22:10:26 +0200 Subject: [PATCH 579/690] Ported the "latest" YMFM changes. To 86box. --- src/sound/ymfm/ymfm.h | 3 +++ src/sound/ymfm/ymfm_fm.ipp | 2 +- src/sound/ymfm/ymfm_ssg.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index 4f8ba1243..c5986d66b 100644 --- a/src/sound/ymfm/ymfm.h +++ b/src/sound/ymfm/ymfm.h @@ -485,6 +485,8 @@ public: class ymfm_engine_callbacks { public: + virtual ~ymfm_engine_callbacks() = default; + // timer callback; called by the interface when a timer fires virtual void engine_timer_expired(uint32_t tnum) = 0; @@ -506,6 +508,7 @@ class ymfm_interface template friend class fm_engine_base; public: + virtual ~ymfm_interface() = default; // the following functions must be implemented by any derived classes; the // default implementations are sufficient for some minimal operation, but will // likely need to be overridden to integrate with the outside world; they are diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp index 55cdd643d..a3ee8d333 100644 --- a/src/sound/ymfm/ymfm_fm.ipp +++ b/src/sound/ymfm/ymfm_fm.ipp @@ -1518,7 +1518,7 @@ void fm_engine_base::engine_timer_expired(uint32_t tnum) for (uint32_t chnum = 0; chnum < CHANNELS; chnum++) if (bitfield(RegisterType::CSM_TRIGGER_MASK, chnum)) { - m_channel[chnum]->keyonoff(1, KEYON_CSM, chnum); + m_channel[chnum]->keyonoff(0xf, KEYON_CSM, chnum); m_modified_channels |= 1 << chnum; } diff --git a/src/sound/ymfm/ymfm_ssg.h b/src/sound/ymfm/ymfm_ssg.h index 749ad146f..cb7ec9e7c 100644 --- a/src/sound/ymfm/ymfm_ssg.h +++ b/src/sound/ymfm/ymfm_ssg.h @@ -49,6 +49,8 @@ namespace ymfm class ssg_override { public: + virtual ~ssg_override() = default; + // reset our status virtual void ssg_reset() = 0; From fc6d93598f028eb549e064976fef47646c15de7e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 6 Jun 2024 02:37:22 +0200 Subject: [PATCH 580/690] Tyan Trinity: Move the Winbond Super I/O chip onto ports 3F0h/3F1h where it's supposed to be, fixes internal device mess in Windows ME. --- src/machine/m_at_socket370.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 9e686ae8b..010aee3da 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -100,7 +100,7 @@ machine_at_s1857_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977ef_370_device); + device_add(&w83977ef_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); From b3e72559a78999eb07a3573a104360e507b8406b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Jun 2024 06:25:49 +0200 Subject: [PATCH 581/690] ISA Memory cards: Partial rewrite of EMS to support up to two ranges on each EV-159, and make the page frame address changing actually work. --- src/device/isamem.c | 347 +++++++++++++++++++++++++++----------------- 1 file changed, 211 insertions(+), 136 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index ba60ddd2a..63f8955f1 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -124,6 +124,11 @@ typedef struct emsreg_t { char pad; uint8_t *addr; /* start addr in EMS RAM */ mem_mapping_t mapping; /* mapping entry for page */ + uint8_t *ram; + uint8_t *frame_val; + uint16_t *ems_size; + uint16_t *ems_pages; + uint32_t *frame_addr; } emsreg_t; typedef struct ext_ram_t { @@ -136,20 +141,23 @@ typedef struct memdev_t { uint8_t board : 6; /* board type */ uint8_t reserved : 2; - uint8_t flags; + uint8_t flags; #define FLAG_CONFIG 0x01 /* card is configured */ #define FLAG_WIDE 0x10 /* card uses 16b mode */ #define FLAG_FAST 0x20 /* fast (<= 120ns) chips */ #define FLAG_EMS 0x40 /* card has EMS mode enabled */ - uint16_t total_size; /* configured size in KB */ - uint32_t base_addr; /* configured I/O address */ - uint32_t start_addr; /* configured memory start */ - uint32_t frame_addr; /* configured frame address */ + uint8_t frame_val[2]; - uint16_t ems_size; /* EMS size in KB */ - uint16_t ems_pages; /* EMS size in pages */ - uint32_t ems_start; /* start of EMS in RAM */ + uint16_t total_size; /* configured size in KB */ + uint16_t base_addr[2]; /* configured I/O address */ + + uint32_t start_addr; /* configured memory start */ + uint32_t frame_addr[2]; /* configured frame address */ + + uint16_t ems_size[2]; /* EMS size in KB */ + uint16_t ems_pages[2]; /* EMS size in pages */ + uint32_t ems_start[2]; /* start of EMS in RAM */ uint8_t *ram; /* allocated RAM buffer */ @@ -158,7 +166,7 @@ typedef struct memdev_t { mem_mapping_t low_mapping; /* mapping for low mem */ mem_mapping_t high_mapping; /* mapping for high mem */ - emsreg_t ems[EMS_MAXPAGE]; /* EMS controller registers */ + emsreg_t ems[EMS_MAXPAGE * 2]; /* EMS controller registers */ } memdev_t; #ifdef ENABLE_ISAMEM_LOG @@ -231,14 +239,14 @@ ram_writew(uint32_t addr, uint16_t val, void *priv) static uint8_t ems_readb(uint32_t addr, void *priv) { - memdev_t *dev = (memdev_t *) priv; + emsreg_t *dev = (emsreg_t *) priv; uint8_t ret = 0xff; /* Grab the data. */ - ret = *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)); + ret = *(uint8_t *) (dev->addr + (addr & 0x3fff)); #if ISAMEM_DEBUG if ((addr % 4096) == 0) - isamem_log("EMS readb(%06x) = %02x\n", addr - dev & 0x3fff, ret); + isamem_log("EMS readb(%06x) = %02x\n", addr & 0x3fff, ret); #endif return ret; @@ -248,14 +256,14 @@ ems_readb(uint32_t addr, void *priv) static uint16_t ems_readw(uint32_t addr, void *priv) { - memdev_t *dev = (memdev_t *) priv; + emsreg_t *dev = (emsreg_t *) priv; uint16_t ret = 0xffff; /* Grab the data. */ - ret = *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)); + ret = *(uint16_t *) (dev->addr + (addr & 0x3fff)); #if ISAMEM_DEBUG if ((addr % 4096) == 0) - isamem_log("EMS readw(%06x) = %04x\n", addr - dev & 0x3fff, ret); + isamem_log("EMS readw(%06x) = %04x\n", addr & 0x3fff, ret); #endif return ret; @@ -265,46 +273,50 @@ ems_readw(uint32_t addr, void *priv) static void ems_writeb(uint32_t addr, uint8_t val, void *priv) { - memdev_t *dev = (memdev_t *) priv; + emsreg_t *dev = (emsreg_t *) priv; /* Write the data. */ #if ISAMEM_DEBUG if ((addr % 4096) == 0) - isamem_log("EMS writeb(%06x, %02x)\n", addr - dev & 0x3fff, val); + isamem_log("EMS writeb(%06x, %02x)\n", addr & 0x3fff, val); #endif - *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val; + *(uint8_t *) (dev->addr + (addr & 0x3fff)) = val; } /* Write one word to onboard paged RAM. */ static void ems_writew(uint32_t addr, uint16_t val, void *priv) { - memdev_t *dev = (memdev_t *) priv; + emsreg_t *dev = (emsreg_t *) priv; /* Write the data. */ #if ISAMEM_DEBUG if ((addr % 4096) == 0) isamem_log("EMS writew(%06x, %04x)\n", addr & 0x3fff, val); #endif - *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val; + *(uint16_t *) (dev->addr + (addr & 0x3fff)) = val; } /* Handle a READ operation from one of our registers. */ static uint8_t -ems_read(uint16_t port, void *priv) +ems_in(uint16_t port, void *priv) { - const memdev_t *dev = (memdev_t *) priv; - uint8_t ret = 0xff; + const emsreg_t *dev = (emsreg_t *) priv; + uint8_t ret = 0xff; +#ifdef ENABLE_ISAMEM_LOG int vpage; +#endif /* Get the viewport page number. */ +#ifdef ENABLE_ISAMEM_LOG vpage = (port / EMS_PGSIZE); +#endif port &= (EMS_PGSIZE - 1); - switch (port - dev->base_addr) { + switch (port & 0x0001) { case 0x0000: /* page number register */ - ret = dev->ems[vpage].page; - if (dev->ems[vpage].enabled) + ret = dev->page; + if (dev->enabled) ret |= 0x80; break; @@ -322,15 +334,14 @@ ems_read(uint16_t port, void *priv) /* Handle a READ operation from one of our registers. */ static uint8_t -consecutive_ems_read(uint16_t port, void *priv) +consecutive_ems_in(uint16_t port, void *priv) { const memdev_t *dev = (memdev_t *) priv; uint8_t ret = 0xff; int vpage; /* Get the viewport page number. */ - vpage = (port - dev->base_addr); - + vpage = (port - dev->base_addr[0]); ret = dev->ems[vpage].page; if (dev->ems[vpage].enabled) @@ -343,73 +354,71 @@ consecutive_ems_read(uint16_t port, void *priv) /* Handle a WRITE operation to one of our registers. */ static void -ems_write(uint16_t port, uint8_t val, void *priv) +ems_out(uint16_t port, uint8_t val, void *priv) { - memdev_t *dev = (memdev_t *) priv; + emsreg_t *dev = (emsreg_t *) priv; int vpage; /* Get the viewport page number. */ vpage = (port / EMS_PGSIZE); port &= (EMS_PGSIZE - 1); - switch (port - dev->base_addr) { + switch (port & 0x0001) { case 0x0000: /* page mapping registers */ - isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! page=%d\n", port, val, vpage); - /* Set the page number. */ - dev->ems[vpage].enabled = (val & 0x80); - dev->ems[vpage].page = (val & 0x7f); + dev->enabled = (val & 0x80); + dev->page = (val & 0x7f); - if (dev->ems[vpage].page < dev->ems_pages) { + if (dev->enabled && (dev->page < *dev->ems_pages)) { /* Pre-calculate the page address in EMS RAM. */ - dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE); - } else { - /* That page does not exist. */ - dev->ems[vpage].enabled = 0; - } + dev->addr = dev->ram + ((val & 0x7f) * EMS_PGSIZE); + + isamem_log("ISAMEM: map port %04X, page %i, starting at %08X: %08X -> %08X\n", port, + vpage, *dev->frame_addr, + *dev->frame_addr + (EMS_PGSIZE * (vpage & 3)), dev->addr - dev->ram); + mem_mapping_set_addr(&dev->mapping, *dev->frame_addr + (EMS_PGSIZE * vpage), EMS_PGSIZE); - if (dev->ems[vpage].enabled) { /* Update the EMS RAM address for this page. */ - mem_mapping_set_exec(&dev->ems[vpage].mapping, - dev->ems[vpage].addr); + mem_mapping_set_exec(&dev->mapping, dev->addr); /* Enable this page. */ - mem_mapping_enable(&dev->ems[vpage].mapping); + mem_mapping_enable(&dev->mapping); } else { + isamem_log("ISAMEM: map port %04X, page %i, starting at %08X: %08X -> N/A\n", + port, vpage, *dev->frame_addr, *dev->frame_addr + (EMS_PGSIZE * vpage)); + /* Disable this page. */ - mem_mapping_disable(&dev->ems[vpage].mapping); + mem_mapping_disable(&dev->mapping); } break; case 0x0001: /* page frame registers */ - isamem_log("ISAMEM: write(%04x, %02x) to page frame registers! page=%d\n", port, val, vpage); - - /* - * The EV-159 EMM driver configures the frame address - * by setting bits in these registers. The information - * in their manual is unclear, but here is what was - * found out by repeatedly changing EMM's config: - * - * 00 04 08 Address - * ----------------- - * 80 c0 e0 C0000 - * 80 c0 e0 C4000 - * 80 c0 e0 C8000 - * 80 c0 e0 CC000 - * 80 c0 e0 D0000 - * 80 c0 e0 D4000 - * 80 c0 e0 D8000 - * 80 c0 e0 DC000 - * 80 c0 e0 E0000 - */ - dev->ems[vpage].frame = val; - dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) || - ((dev->ems[1].frame & 0x80) >> 6) || - ((dev->ems[0].frame & 0x80) >> 7)) << 14); - mem_mapping_disable(&dev->ems[0].mapping); - mem_mapping_disable(&dev->ems[1].mapping); - mem_mapping_disable(&dev->ems[2].mapping); - mem_mapping_disable(&dev->ems[3].mapping); + /* + * The EV-159 EMM driver configures the frame address + * by setting bits in these registers. The information + * in their manual is unclear, but here is what was + * found out by repeatedly changing EMM's config: + * + * 08 04 00 Address + * ----------------- + * 00 00 00 C4000 + * 00 00 80 C8000 + * 00 80 00 CC000 + * 00 80 80 D0000 + * 80 00 00 D4000 + * 80 00 80 D8000 + * 80 80 00 DC000 + * 80 80 80 E0000 + */ + dev->frame = val; + *dev->frame_val = (*dev->frame_val & ~(1 << vpage)) | ((val >> 7) << vpage); + *dev->frame_addr = 0x000c4000 + (*dev->frame_val << 14); + isamem_log("ISAMEM: map port %04X page %i: frame_addr = %08X\n", port, vpage, *dev->frame_addr); + /* Destroy the page registers. */ + for (uint8_t i = 0; i < 4; i ++) { + isamem_log(" "); + outb((port & 0x3ffe) + (i << 14), 0x00); + } break; default: @@ -419,13 +428,13 @@ ems_write(uint16_t port, uint8_t val, void *priv) /* Handle a WRITE operation to one of our registers. */ static void -consecutive_ems_write(uint16_t port, uint8_t val, void *priv) +consecutive_ems_out(uint16_t port, uint8_t val, void *priv) { memdev_t *dev = (memdev_t *) priv; int vpage; /* Get the viewport page number. */ - vpage = (port - dev->base_addr); + vpage = (port - dev->base_addr[0]); isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! (page=%d)\n", port, val, vpage); @@ -435,9 +444,9 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv) /* Make sure we can do that.. */ if (dev->flags & FLAG_CONFIG) { - if (dev->ems[vpage].page < dev->ems_pages) { + if (dev->ems[vpage].page < dev->ems_pages[0]) { /* Pre-calculate the page address in EMS RAM. */ - dev->ems[vpage].addr = dev->ram + dev->ems_start + (val * EMS_PGSIZE); + dev->ems[vpage].addr = dev->ram + dev->ems_start[0] + (val * EMS_PGSIZE); } else { /* That page does not exist. */ dev->ems[vpage].enabled = 0; @@ -474,6 +483,9 @@ isamem_init(const device_t *info) dev->name = info->name; dev->board = info->local; + dev->base_addr[1] = 0x0000; + dev->frame_addr[1] = 0x00000000; + /* Do per-board initialization. */ tot = 0; switch (dev->board) { @@ -497,67 +509,69 @@ isamem_init(const device_t *info) break; case ISAMEM_EMS5150_CARD: /* Micro Mainframe EMS-5150(T) */ - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); - dev->start_addr = 0; - dev->frame_addr = 0xD0000; - dev->flags |= (FLAG_EMS | FLAG_CONFIG); + dev->base_addr[0] = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; + dev->frame_addr[0] = 0xd0000; + dev->flags |= (FLAG_EMS | FLAG_CONFIG); break; case ISAMEM_EV159_CARD: /* Everex EV-159 RAM 3000 */ - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); - dev->start_addr = device_get_config_int("start"); - tot = device_get_config_int("length"); + dev->base_addr[0] = device_get_config_hex16("base"); + dev->base_addr[1] = device_get_config_hex16("base2"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = device_get_config_int("length"); if (!!device_get_config_int("width")) - dev->flags |= FLAG_WIDE; + dev->flags |= FLAG_WIDE; if (!!device_get_config_int("speed")) - dev->flags |= FLAG_FAST; + dev->flags |= FLAG_FAST; if (!!device_get_config_int("ems")) - dev->flags |= FLAG_EMS; - dev->frame_addr = 0xE0000; + dev->flags |= FLAG_EMS; + dev->frame_addr[0] = 0xd0000; + dev->frame_addr[1] = 0xe0000; break; case ISAMEM_EV165A_CARD: /* Everex Maxi Magic EV-165A */ - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); - dev->start_addr = device_get_config_int("start"); - tot = device_get_config_int("length"); + dev->base_addr[0] = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = device_get_config_int("length"); if (!!device_get_config_int("ems")) - dev->flags |= FLAG_EMS; - dev->frame_addr = 0xE0000; + dev->flags |= FLAG_EMS; + dev->frame_addr[0] = 0xe0000; break; case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */ - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); - dev->start_addr = device_get_config_int("start"); - tot = dev->total_size; - dev->flags |= FLAG_EMS; - dev->frame_addr = 0xE0000; + dev->base_addr[0] = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = dev->total_size; + dev->flags |= FLAG_EMS; + dev->frame_addr[0] = 0xe0000; break; case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */ case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); + dev->base_addr[0] = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); if (!!device_get_config_int("start")) dev->start_addr = device_get_config_int("start"); - dev->frame_addr = device_get_config_hex20("frame"); - dev->flags |= (FLAG_EMS); + dev->frame_addr[0] = device_get_config_hex20("frame"); + dev->flags |= (FLAG_EMS); if (!!device_get_config_int("width")) - dev->flags |= FLAG_WIDE; + dev->flags |= FLAG_WIDE; if (!!device_get_config_int("speed")) - dev->flags |= FLAG_FAST; + dev->flags |= FLAG_FAST; break; case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ case ISAMEM_LOTECH_CARD: - dev->base_addr = device_get_config_hex16("base"); - dev->total_size = device_get_config_int("size"); - dev->start_addr = 0; - dev->frame_addr = device_get_config_hex20("frame"); - dev->flags |= (FLAG_EMS | FLAG_CONFIG); + dev->base_addr[0] = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; + dev->frame_addr[0] = device_get_config_hex20("frame"); + dev->flags |= (FLAG_EMS | FLAG_CONFIG); default: break; @@ -714,25 +728,48 @@ isamem_init(const device_t *info) t = EMS_MAXSIZE; /* Set up where EMS begins in local RAM, and how much we have. */ - dev->ems_start = ptr - dev->ram; - dev->ems_size = t >> 10; - dev->ems_pages = t / EMS_PGSIZE; - isamem_log("ISAMEM: EMS enabled, I/O=%04XH, %iKB (%i pages)", - dev->base_addr, dev->ems_size, dev->ems_pages); - if (dev->frame_addr > 0) - isamem_log(", Frame=%05XH", dev->frame_addr); + dev->ems_start[0] = ptr - dev->ram; + if ((dev->board == ISAMEM_EV159_CARD) && (t > 2048)) { + dev->ems_size[0] = 2 << 10; + dev->ems_pages[0] = (2 << 20) / EMS_PGSIZE; + } else { + dev->ems_size[0] = t >> 10; + dev->ems_pages[0] = t / EMS_PGSIZE; + } + isamem_log("ISAMEM: EMS #1 enabled, I/O=%04XH, %iKB (%i pages)", + dev->base_addr[0], dev->ems_size[0], dev->ems_pages[0]); + if (dev->frame_addr[0] > 0) + isamem_log(", Frame[0]=%05XH", dev->frame_addr[0]); isamem_log("\n"); + if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) { + dev->ems_start[1] = dev->ems_start[0] + (2 << 20); + dev->ems_size[1] = (t - (2 << 20)) >> 10; + dev->ems_pages[1] = (t - (2 << 20)) / EMS_PGSIZE; + isamem_log("ISAMEM: EMS #2 enabled, I/O=%04XH, %iKB (%i pages)", + dev->base_addr[1], dev->ems_size[1], dev->ems_pages[1]); + if (dev->frame_addr[1] > 0) + isamem_log(", Frame[1]=%05XH", dev->frame_addr[1]); + + isamem_log("\n"); + } + /* * For each supported page (we can have a maximum of 4), * create, initialize and disable the mappings, and set * up the I/O control handler. */ for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { + dev->ems[i].ram = dev->ram + dev->ems_start[0]; + dev->ems[i].frame_val = &dev->frame_val[0]; + dev->ems[i].ems_size = &dev->ems_size[0]; + dev->ems[i].ems_pages = &dev->ems_pages[0]; + dev->ems[i].frame_addr = &dev->frame_addr[0]; + /* Create and initialize a page mapping. */ mem_mapping_add(&dev->ems[i].mapping, - dev->frame_addr + (EMS_PGSIZE * i), EMS_PGSIZE, + dev->frame_addr[0] + (EMS_PGSIZE * i), EMS_PGSIZE, ems_readb, (dev->flags & FLAG_WIDE) ? ems_readw : NULL, NULL, @@ -740,20 +777,46 @@ isamem_init(const device_t *info) (dev->flags & FLAG_WIDE) ? ems_writew : NULL, NULL, ptr, MEM_MAPPING_EXTERNAL, - dev); + &(dev->ems[i])); /* For now, disable it. */ mem_mapping_disable(&dev->ems[i].mapping); /* Set up an I/O port handler. */ - if (dev->board != ISAMEM_LOTECH_CARD) - io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2, - ems_read, NULL, NULL, ems_write, NULL, NULL, dev); + if (dev->board != ISAMEM_LOTECH_CARD) + io_sethandler(dev->base_addr[0] + (EMS_PGSIZE * i), 2, + ems_in, NULL, NULL, ems_out, NULL, NULL, &(dev->ems[i])); + + if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) { + dev->ems[i | 4].ram = dev->ram + dev->ems_start[1]; + dev->ems[i | 4].frame_val = &dev->frame_val[1]; + dev->ems[i | 4].ems_size = &dev->ems_size[1]; + dev->ems[i | 4].ems_pages = &dev->ems_pages[1]; + dev->ems[i | 4].frame_addr = &dev->frame_addr[1]; + + /* Create and initialize a page mapping. */ + mem_mapping_add(&dev->ems[i | 4].mapping, + dev->frame_addr[1] + (EMS_PGSIZE * i), EMS_PGSIZE, + ems_readb, + (dev->flags & FLAG_WIDE) ? ems_readw : NULL, + NULL, + ems_writeb, + (dev->flags & FLAG_WIDE) ? ems_writew : NULL, + NULL, + ptr + (2 << 20), MEM_MAPPING_EXTERNAL, + &(dev->ems[i | 4])); + + /* For now, disable it. */ + mem_mapping_disable(&dev->ems[i | 4].mapping); + + io_sethandler(dev->base_addr[1] + (EMS_PGSIZE * i), 2, + ems_in, NULL, NULL, ems_out, NULL, NULL, &(dev->ems[i | 4])); + } } if (dev->board == ISAMEM_LOTECH_CARD) - io_sethandler(dev->base_addr, 4, - consecutive_ems_read, NULL, NULL, consecutive_ems_write, NULL, NULL, dev); + io_sethandler(dev->base_addr[0], 4, + consecutive_ems_in, NULL, NULL, consecutive_ems_out, NULL, NULL, dev); } /* Let them know our device instance. */ @@ -766,13 +829,6 @@ isamem_close(void *priv) { memdev_t *dev = (memdev_t *) priv; - if (dev->flags & FLAG_EMS) { - for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { - io_removehandler(dev->base_addr + (EMS_PGSIZE * i), 2, - ems_read, NULL, NULL, ems_write, NULL, NULL, dev); - } - } - if (dev->ram != NULL) free(dev->ram); @@ -1319,6 +1375,25 @@ static const device_config_t ev159_config[] = { { .description = "" } }, }, + { + .name = "base2", + .description = "Address for > 2 MB", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0268, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "208H", .value = 0x0208 }, + { .description = "218H", .value = 0x0218 }, + { .description = "258H", .value = 0x0258 }, + { .description = "268H", .value = 0x0268 }, + { .description = "2A8H", .value = 0x02A8 }, + { .description = "2B8H", .value = 0x02B8 }, + { .description = "2E8H", .value = 0x02E8 }, + { .description = "" } + }, + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; From 3258ed67f94985096d0301b542c546e16255b8ad Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 01:37:51 -0400 Subject: [PATCH 582/690] Improve lotech EMS --- src/device/isamem.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 63f8955f1..99e6e51b6 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -109,7 +109,8 @@ #define RAM_UMAMEM (384 << 10) /* upper memory block */ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ -#define EMS_MAXSIZE (4096 << 10) /* max EMS memory size */ +#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ +#define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */ #define EMS_PGSIZE (16 << 10) /* one page is this big */ #define EMS_MAXPAGE 4 /* number of viewport pages */ @@ -143,6 +144,7 @@ typedef struct memdev_t { uint8_t flags; #define FLAG_CONFIG 0x01 /* card is configured */ +#define FLAG_LOTECH 0x02 /* Lotech EMS supports upto 4MB with a hack */ #define FLAG_WIDE 0x10 /* card uses 16b mode */ #define FLAG_FAST 0x20 /* fast (<= 120ns) chips */ #define FLAG_EMS 0x40 /* card has EMS mode enabled */ @@ -565,8 +567,9 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; - case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ - case ISAMEM_LOTECH_CARD: + case ISAMEM_LOTECH_CARD: /* Lotech EMS */ + dev->flags |= FLAG_LOTECH; + case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ dev->base_addr[0] = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); dev->start_addr = 0; @@ -724,7 +727,10 @@ isamem_init(const device_t *info) if (dev->flags & FLAG_EMS) { /* EMS 3.2 cannot have more than 4096KB per board. */ t = k; - if (t > EMS_MAXSIZE) + if ((dev->flags & FLAG_LOTECH) && (t > EMS_LOTECH_MAXSIZE)) + /* Lotech EMS cannot have more than 4096KB per board. */ + t = EMS_LOTECH_MAXSIZE; + else if (t > EMS_MAXSIZE) t = EMS_MAXSIZE; /* Set up where EMS begins in local RAM, and how much we have. */ From e290347433fb2dc0963f4f081f191e98e12b1996 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 01:38:32 -0400 Subject: [PATCH 583/690] Remove needless parens --- src/device/isamem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 99e6e51b6..1f071388c 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -560,7 +560,7 @@ isamem_init(const device_t *info) if (!!device_get_config_int("start")) dev->start_addr = device_get_config_int("start"); dev->frame_addr[0] = device_get_config_hex20("frame"); - dev->flags |= (FLAG_EMS); + dev->flags |= FLAG_EMS; if (!!device_get_config_int("width")) dev->flags |= FLAG_WIDE; if (!!device_get_config_int("speed")) From 0f5fd9fbd0f8b20310b25c96070cde40cccfae5d Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 02:08:28 -0400 Subject: [PATCH 584/690] Fixed EV159's max ram and remove flag kludge --- src/device/isamem.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 1f071388c..7f01f2c4d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -110,6 +110,7 @@ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ #define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ +#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for lotech cards */ #define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */ #define EMS_PGSIZE (16 << 10) /* one page is this big */ #define EMS_MAXPAGE 4 /* number of viewport pages */ @@ -144,7 +145,6 @@ typedef struct memdev_t { uint8_t flags; #define FLAG_CONFIG 0x01 /* card is configured */ -#define FLAG_LOTECH 0x02 /* Lotech EMS supports upto 4MB with a hack */ #define FLAG_WIDE 0x10 /* card uses 16b mode */ #define FLAG_FAST 0x20 /* fast (<= 120ns) chips */ #define FLAG_EMS 0x40 /* card has EMS mode enabled */ @@ -567,9 +567,8 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; - case ISAMEM_LOTECH_CARD: /* Lotech EMS */ - dev->flags |= FLAG_LOTECH; case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ + case ISAMEM_LOTECH_CARD: /* Lotech EMS */ dev->base_addr[0] = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); dev->start_addr = 0; @@ -725,12 +724,14 @@ isamem_init(const device_t *info) /* If EMS is enabled, use the remainder for EMS. */ if (dev->flags & FLAG_EMS) { - /* EMS 3.2 cannot have more than 4096KB per board. */ t = k; - if ((dev->flags & FLAG_LOTECH) && (t > EMS_LOTECH_MAXSIZE)) + if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE)) /* Lotech EMS cannot have more than 4096KB per board. */ t = EMS_LOTECH_MAXSIZE; + else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE)) + t = EMS_EV159_MAXSIZE; else if (t > EMS_MAXSIZE) + /* EMS 3.2 cannot have more than 4096KB per board. */ t = EMS_MAXSIZE; /* Set up where EMS begins in local RAM, and how much we have. */ From 603fdb0331252213c2f1ed2e71967fa077c1fb11 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 02:33:21 -0400 Subject: [PATCH 585/690] Fix various comments in isamem.c --- src/device/isamem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 7f01f2c4d..e4a37b8a3 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -110,7 +110,7 @@ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ #define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ -#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for lotech cards */ +#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for EV-159 cards */ #define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */ #define EMS_PGSIZE (16 << 10) /* one page is this big */ #define EMS_MAXPAGE 4 /* number of viewport pages */ @@ -726,12 +726,13 @@ isamem_init(const device_t *info) if (dev->flags & FLAG_EMS) { t = k; if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE)) - /* Lotech EMS cannot have more than 4096KB per board. */ + /* The Lotech EMS cannot have more than 4096KB per board. */ t = EMS_LOTECH_MAXSIZE; else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE)) + /* The EV-159 cannot have more than 3072KB per board. */ t = EMS_EV159_MAXSIZE; else if (t > EMS_MAXSIZE) - /* EMS 3.2 cannot have more than 4096KB per board. */ + /* EMS 3.2 cannot have more than 2048KB per board. */ t = EMS_MAXSIZE; /* Set up where EMS begins in local RAM, and how much we have. */ From ddc36d66df12cb980917c7be4fd02c8d7f91c646 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 6 Jun 2024 23:41:56 -0400 Subject: [PATCH 586/690] Add IBM PC/AT 128KB Memory Expansion Option --- src/device/isamem.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index e4a37b8a3..d611cfaf2 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -90,11 +90,12 @@ #define ISAMEM_GENXT_CARD 1 #define ISAMEM_RAMCARD_CARD 2 #define ISAMEM_SYSTEMCARD_CARD 3 -#define ISAMEM_IBMAT_CARD 4 -#define ISAMEM_GENAT_CARD 5 -#define ISAMEM_P5PAK_CARD 6 -#define ISAMEM_A6PAK_CARD 7 -#define ISAMEM_EMS5150_CARD 8 +#define ISAMEM_IBMAT_128K_CARD 4 +#define ISAMEM_IBMAT_CARD 5 +#define ISAMEM_GENAT_CARD 6 +#define ISAMEM_P5PAK_CARD 7 +#define ISAMEM_A6PAK_CARD 8 +#define ISAMEM_EMS5150_CARD 9 #define ISAMEM_EV159_CARD 10 #define ISAMEM_RAMPAGEXT_CARD 11 #define ISAMEM_ABOVEBOARD_CARD 12 @@ -502,6 +503,13 @@ isamem_init(const device_t *info) tot = dev->total_size; break; + case ISAMEM_IBMAT_128K_CARD: /* IBM PC/AT 128K Memory Expansion Option */ + dev->total_size = 128; + dev->start_addr = 512; + tot = dev->total_size; + dev->flags |= FLAG_WIDE; + break; + case ISAMEM_IBMAT_CARD: /* IBM PC/AT Memory Expansion Card */ case ISAMEM_GENAT_CARD: /* Generic PC/AT Memory Expansion Card */ dev->total_size = device_get_config_int("size"); @@ -1035,6 +1043,20 @@ static const device_t mssystemcard_device = { .config = mssystemcard_config }; +static const device_t ibmat_128k_device = { + .name = "IBM PC/AT 128KB Memory Expansion Option", + .internal_name = "ibmat_128k", + .flags = DEVICE_ISA, + .local = ISAMEM_IBMAT_128K_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + static const device_config_t ibmat_config[] = { // clang-format off { @@ -1939,12 +1961,16 @@ static const struct { } boards[] = { // clang-format off { &isa_none_device }, + // XT Ram Expansion Cards { &ibmxt_device }, { &genericxt_device }, { &msramcard_device }, { &mssystemcard_device }, + // AT RAM Expansion Cards + { &ibmat_128k_device }, { &ibmat_device }, { &genericat_device }, + // EMS Cards { &p5pak_device }, { &a6pak_device }, { &ems5150_device }, From 0e386ffad733adec6b502008640be9692b905ff0 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 6 Jun 2024 23:47:04 -0400 Subject: [PATCH 587/690] Add IBM PC/XT 32K Memory Expansion Option --- src/device/isamem.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index d611cfaf2..74f984416 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -851,6 +851,54 @@ isamem_close(void *priv) free(dev); } +static const device_config_t ibmxt_32k_config[] = { + // clang-format off + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 32, + .file_filter = "", + .spinner = { + .min = 32, + .max = 576, + .step = 32 + }, + .selection = { { 0 } } + }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 64, + .file_filter = "", + .spinner = { + .min = 0, + .max = 608, + .step = 32 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t ibmxt_32k_device = { + .name = "IBM PC/XT 32K Memory Expansion Option", + .internal_name = "ibmxt_32k", + .flags = DEVICE_ISA, + .local = ISAMEM_IBMXT_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt_32k_config +}; + static const device_config_t ibmxt_config[] = { // clang-format off { @@ -1962,6 +2010,7 @@ static const struct { // clang-format off { &isa_none_device }, // XT Ram Expansion Cards + { &ibmxt_32k_device }, { &ibmxt_device }, { &genericxt_device }, { &msramcard_device }, From a206a2ee544e5aaaa290d65c0305a05ba75e01e3 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 6 Jun 2024 23:52:21 -0400 Subject: [PATCH 588/690] Add IBM PC/XT 64K Memory Expansion Option --- src/device/isamem.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index 74f984416..04f04eef7 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -899,6 +899,54 @@ static const device_t ibmxt_32k_device = { .config = ibmxt_32k_config }; +static const device_config_t ibmxt_64k_config[] = { + // clang-format off + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 64, + .file_filter = "", + .spinner = { + .min = 64, + .max = 576, + .step = 64 + }, + .selection = { { 0 } } + }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 64, + .file_filter = "", + .spinner = { + .min = 0, + .max = 576, + .step = 64 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t ibmxt_64k_device = { + .name = "IBM PC/XT 64K Memory Expansion Option", + .internal_name = "ibmxt_64k", + .flags = DEVICE_ISA, + .local = ISAMEM_IBMXT_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt_64k_config +}; + static const device_config_t ibmxt_config[] = { // clang-format off { @@ -2011,6 +2059,7 @@ static const struct { { &isa_none_device }, // XT Ram Expansion Cards { &ibmxt_32k_device }, + { &ibmxt_64k_device }, { &ibmxt_device }, { &genericxt_device }, { &msramcard_device }, From 006207151f6cf4df9e1095982a5910c07cfe8024 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 6 Jun 2024 23:59:28 -0400 Subject: [PATCH 589/690] 64/256KB Memory Expansion Option --- src/device/isamem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 04f04eef7..dbbd779a4 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -957,9 +957,9 @@ static const device_config_t ibmxt_config[] = { .default_int = 128, .file_filter = "", .spinner = { - .min = 0, - .max = 512, - .step = 16 + .min = 64, + .max = 576, + .step = 64 }, .selection = { { 0 } } }, @@ -982,7 +982,7 @@ static const device_config_t ibmxt_config[] = { }; static const device_t ibmxt_device = { - .name = "IBM PC/XT Memory Expansion", + .name = "IBM PC/XT 64/256K Memory Expansion Option", .internal_name = "ibmxt", .flags = DEVICE_ISA, .local = ISAMEM_IBMXT_CARD, From 1ea76d2e378bcd3c03a869a27a26805907d5ad86 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 02:39:45 -0400 Subject: [PATCH 590/690] Correct onboard memory on the 5170 --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9723d53cd..e841a8538 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2545,8 +2545,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 15872, - .step = 128 + .max = 512, + .step = 256 }, .nvrmask = 63, .kbc_device = NULL, From 86de260b245de535fe839182a2e4d23d75da265e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Jun 2024 14:19:10 +0200 Subject: [PATCH 591/690] mem.c: Double the pages array size for 386SX, fixes the segmentation fault when trying to use the Amstrad MegaPC with more than 16 MB and the 486+ interpreter. --- 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 be097b5f3..5fe7f3c29 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2833,8 +2833,8 @@ mem_reset(void) */ if (is286) { if (cpu_16bitbus) { - /* 80286/386SX; maximum address space is 16MB. */ - m = 4096; + /* 80286/386SX; maximum address space is 16MB + 16 MB for EMS. */ + m = 8192; /* ALi M6117; maximum address space is 64MB. */ if (is6117) m <<= 2; From dc7b93dc04669d984be2f7ea51e78fa021fbc494 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Jun 2024 18:21:55 +0200 Subject: [PATCH 592/690] device/isamem.c: Fix the two bugs reported by lemondrops. --- src/device/isamem.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index dbbd779a4..cd59aa02d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -478,6 +478,8 @@ isamem_init(const device_t *info) uint32_t t; uint32_t addr; uint32_t tot; + /* EMS 3.2 cannot have more than 2048KB per board. */ + uint32_t ems_max = EMS_MAXSIZE; uint8_t *ptr; /* Find our device and create an instance. */ @@ -527,6 +529,8 @@ isamem_init(const device_t *info) break; case ISAMEM_EV159_CARD: /* Everex EV-159 RAM 3000 */ + /* The EV-159 cannot have more than 3072KB per board. */ + ems_max = EMS_EV159_MAXSIZE; dev->base_addr[0] = device_get_config_hex16("base"); dev->base_addr[1] = device_get_config_hex16("base2"); dev->total_size = device_get_config_int("size"); @@ -575,13 +579,16 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; - case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ case ISAMEM_LOTECH_CARD: /* Lotech EMS */ + /* The Lotech EMS cannot have more than 4096KB per board. */ + ems_max = EMS_LOTECH_MAXSIZE; + case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ dev->base_addr[0] = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); dev->start_addr = 0; dev->frame_addr[0] = device_get_config_hex20("frame"); dev->flags |= (FLAG_EMS | FLAG_CONFIG); + break; default: break; @@ -733,19 +740,13 @@ isamem_init(const device_t *info) /* If EMS is enabled, use the remainder for EMS. */ if (dev->flags & FLAG_EMS) { t = k; - if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE)) - /* The Lotech EMS cannot have more than 4096KB per board. */ - t = EMS_LOTECH_MAXSIZE; - else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE)) - /* The EV-159 cannot have more than 3072KB per board. */ - t = EMS_EV159_MAXSIZE; - else if (t > EMS_MAXSIZE) - /* EMS 3.2 cannot have more than 2048KB per board. */ - t = EMS_MAXSIZE; + + if (t > ems_max) + t = ems_max; /* Set up where EMS begins in local RAM, and how much we have. */ dev->ems_start[0] = ptr - dev->ram; - if ((dev->board == ISAMEM_EV159_CARD) && (t > 2048)) { + if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) { dev->ems_size[0] = 2 << 10; dev->ems_pages[0] = (2 << 20) / EMS_PGSIZE; } else { From ec0287cd2f3739fd3d6d947f95e93c47d2bdcb99 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Jun 2024 18:23:16 +0200 Subject: [PATCH 593/690] Added the missing fallthrough marker. --- src/device/isamem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index cd59aa02d..a53f5e66c 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -582,6 +582,7 @@ isamem_init(const device_t *info) case ISAMEM_LOTECH_CARD: /* Lotech EMS */ /* The Lotech EMS cannot have more than 4096KB per board. */ ems_max = EMS_LOTECH_MAXSIZE; + fallthrough; case ISAMEM_BRXT_CARD: /* BocaRAM/XT */ dev->base_addr[0] = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); From f95b1d984d72e056b3076f5aac8f0588f77de6dc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Jun 2024 04:35:29 +0200 Subject: [PATCH 594/690] ISA memory and RTC cards: Only enable the configure button if the device actually has a configuration structure present. --- src/device/isamem.c | 9 +++++++++ src/device/isartc.c | 9 +++++++++ src/include/86box/isamem.h | 1 + src/include/86box/isartc.h | 1 + src/qt/qt_settingsotherperipherals.cpp | 13 +++++++------ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index a53f5e66c..fcbbbfb15 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -2145,3 +2145,12 @@ isamem_get_device(int board) /* Add the instance to the system. */ return boards[board].dev; } + +int +isamem_has_config(int board) +{ + if (boards[board].dev == NULL) + return 0; + + return (boards[board].dev->config ? 1 : 0); +} diff --git a/src/device/isartc.c b/src/device/isartc.c index 46f31c137..fea108426 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -815,3 +815,12 @@ isartc_get_device(int board) { return (boards[board].dev); } + +int +isartc_has_config(int board) +{ + if (boards[board].dev == NULL) + return 0; + + return (boards[board].dev->config ? 1 : 0); +} diff --git a/src/include/86box/isamem.h b/src/include/86box/isamem.h index 9a1841c53..51fe50e33 100644 --- a/src/include/86box/isamem.h +++ b/src/include/86box/isamem.h @@ -64,6 +64,7 @@ extern const char *isamem_get_name(int t); extern const char *isamem_get_internal_name(int t); extern int isamem_get_from_internal_name(const char *s); extern const device_t *isamem_get_device(int t); +extern int isamem_has_config(int board); #ifdef __cplusplus } diff --git a/src/include/86box/isartc.h b/src/include/86box/isartc.h index 92c58e350..0224180b3 100644 --- a/src/include/86box/isartc.h +++ b/src/include/86box/isartc.h @@ -58,6 +58,7 @@ extern void isartc_reset(void); extern const char *isartc_get_internal_name(int t); extern int isartc_get_from_internal_name(char *s); extern const device_t *isartc_get_device(int t); +extern int isartc_has_config(int board); #ifdef __cplusplus } diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index 3904b653a..a7db551ad 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -81,6 +81,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ++d; } ui->comboBoxRTC->setCurrentIndex(selectedRow); + ui->pushButtonConfigureRTC->setEnabled((isartc_type != 0) && isartc_has_config(isartc_type) && machineHasIsa); for (int c = 0; c < ISAMEM_MAX; c++) { auto *cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); @@ -106,7 +107,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); cbox->setEnabled(machineHasIsa); - findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machineHasIsa); + findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled((isamem_type[c] != 0) && isamem_has_config(isamem_type[c]) && machineHasIsa); } } @@ -138,7 +139,7 @@ SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureRTC->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureRTC->setEnabled((index != 0) && isartc_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void @@ -153,7 +154,7 @@ SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureCard1->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureCard1->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void @@ -168,7 +169,7 @@ SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureCard2->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureCard2->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void @@ -183,7 +184,7 @@ SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureCard3->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureCard3->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void @@ -198,7 +199,7 @@ SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureCard4->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureCard4->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void From 1d325d411de7977ff419cb243174aaeea07934bd Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 22:34:22 -0400 Subject: [PATCH 595/690] Fix underlying segfaults too --- src/qt/qt_deviceconfig.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index b031e6544..d24db2ed4 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -120,6 +120,9 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) int p; int q; + if (config == NULL) + return; + while (config->type != -1) { const int config_type = config->type & CONFIG_TYPE_MASK; @@ -363,7 +366,11 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se dc.ProcessConfig(&device_context, config, false); dc.setFixedSize(dc.minimumSizeHint()); + if (dc.exec() == QDialog::Accepted) { + if (config == NULL) + return; + config = device->config; while (config->type != -1) { switch (config->type) { From 152c0cbf1d6f85fdd0b69798de6b324d8cf5e70b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Jun 2024 05:02:58 +0200 Subject: [PATCH 596/690] Settings: Changed the List View to a Table View - now the pages rows are no longer as small as they used to be. --- src/qt/qt_settings.cpp | 4 ++-- src/qt/qt_settings.ui | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index e9767083a..caabdbfca 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -182,8 +182,8 @@ Settings::Settings(QWidget *parent) [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->resizeColumnsToContents(); + ui->listView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); ui->listView->setCurrentIndex(model->index(0, 0)); diff --git a/src/qt/qt_settings.ui b/src/qt/qt_settings.ui index 7b4d28bec..fd92f7f58 100644 --- a/src/qt/qt_settings.ui +++ b/src/qt/qt_settings.ui @@ -36,10 +36,25 @@ 0 - - - QListView::ListMode + + + QAbstractItemView::NoEditTriggers + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + false + From 4c74fdd4cc8968a00f6650f14cdf97fa9f9bdada Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 7 Jun 2024 23:56:37 -0400 Subject: [PATCH 597/690] Correct max mem on IBM 286 clones and the XT/286 --- src/machine/machine_table.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e841a8538..da3df57b6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2665,7 +2665,7 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 15872, + .max = 640, .step = 128 }, .nvrmask = 127, @@ -2705,8 +2705,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 15872, - .step = 128 + .max = 512, + .step = 256 }, .nvrmask = 63, .kbc_device = NULL, @@ -3030,8 +3030,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 15872, - .step = 128 + .max = 512, + .step = 256 }, .nvrmask = 63, .kbc_device = NULL, @@ -3070,8 +3070,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 15872, - .step = 128 + .max = 512, + .step = 256 }, .nvrmask = 63, .kbc_device = NULL, From 4b77ef6823cc6840150e0ee2bf11e40cd7d8caa6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Jun 2024 19:58:16 +0200 Subject: [PATCH 598/690] 286: Make LOCK legal with all instructions, per the Programmers' Reference Manual. --- src/cpu/386_common.c | 64 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index f3926f170..801b543c3 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -426,42 +426,44 @@ x386_common_log(const char *fmt, ...) int is_lock_legal(uint32_t fetchdat) { - int legal; - fetch_dat_t fetch_dat; + int legal = 1; - fetch_dat.fd = fetchdat; + if (is386) { + fetch_dat_t fetch_dat; + fetch_dat.fd = fetchdat; - legal = lock_legal[fetch_dat.b[0]]; - if (legal == 1) - legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - else if (legal == 2) { - legal = lock_legal_0f[fetch_dat.b[1]]; + legal = lock_legal[fetch_dat.b[0]]; if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ - else if (legal == 3) { - legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal_0f[fetch_dat.b[1]]; if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; } - } else if (legal == 3) switch(fetch_dat.b[0]) { - case 0x80 ... 0x83: - legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xf6 ... 0xf7: - legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xfe ... 0xff: - legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - default: - legal = 0; - break; } return legal; From 0f29bcddf196763c4742a75dcdaaed7045372340 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 9 Jun 2024 23:08:46 +0200 Subject: [PATCH 599/690] Upgrade to softfloat3e. This should solve licensing problems as well. --- src/codegen/codegen_ops_x86-64.h | 8 +- src/codegen/codegen_ops_x86.h | 40 +- src/codegen_new/codegen_backend_arm64_uops.c | 12 +- src/codegen_new/codegen_backend_arm_uops.c | 12 +- src/codegen_new/codegen_backend_x86-64_uops.c | 4 +- src/codegen_new/codegen_backend_x86_uops.c | 4 +- src/codegen_new/codegen_ops_fpu_arith.c | 22 +- src/cpu/CMakeLists.txt | 4 +- src/cpu/cpu.h | 4 +- src/cpu/softfloat/CMakeLists.txt | 17 - src/cpu/softfloat/config.h | 51 - src/cpu/softfloat/softfloat-compare.h | 496 -- src/cpu/softfloat/softfloat-macros.h | 686 --- src/cpu/softfloat/softfloat-muladd.cc | 558 --- src/cpu/softfloat/softfloat-round-pack.cc | 896 ---- src/cpu/softfloat/softfloat-round-pack.h | 309 -- src/cpu/softfloat/softfloat-specialize.cc | 187 - src/cpu/softfloat/softfloat-specialize.h | 789 ---- src/cpu/softfloat/softfloat.cc | 4012 ----------------- src/cpu/softfloat/softfloat.h | 488 -- src/cpu/softfloat/softfloat16.cc | 129 - src/cpu/softfloat/softfloatx80.cc | 384 -- src/cpu/softfloat/softfloatx80.h | 121 - src/cpu/softfloat3e/CMakeLists.txt | 56 + src/cpu/softfloat3e/COPYING.txt | 37 + src/cpu/softfloat3e/README.html | 49 + src/cpu/softfloat3e/README.txt | 21 + src/cpu/softfloat3e/config.h | 14 + src/cpu/softfloat3e/consts.cc | 51 + .../softfloat3e/doc/SoftFloat-history.html | 258 ++ src/cpu/softfloat3e/doc/SoftFloat-source.html | 686 +++ src/cpu/softfloat3e/doc/SoftFloat.html | 1527 +++++++ src/cpu/softfloat3e/extF80_addsub.cc | 106 + src/cpu/softfloat3e/extF80_class.cc | 71 + src/cpu/softfloat3e/extF80_compare.cc | 147 + src/cpu/softfloat3e/extF80_div.cc | 188 + src/cpu/softfloat3e/extF80_extract.cc | 97 + src/cpu/softfloat3e/extF80_mul.cc | 153 + src/cpu/softfloat3e/extF80_rem.cc | 199 + src/cpu/softfloat3e/extF80_roundToInt.cc | 123 + src/cpu/softfloat3e/extF80_scale.cc | 136 + src/cpu/softfloat3e/extF80_sqrt.cc | 159 + src/cpu/softfloat3e/extF80_to_f128.cc | 75 + src/cpu/softfloat3e/extF80_to_f16.cc | 89 + src/cpu/softfloat3e/extF80_to_f32.cc | 89 + src/cpu/softfloat3e/extF80_to_f64.cc | 89 + src/cpu/softfloat3e/extF80_to_i32.cc | 82 + src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc | 93 + src/cpu/softfloat3e/extF80_to_i64.cc | 88 + src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc | 90 + src/cpu/softfloat3e/extF80_to_ui32.cc | 83 + .../softfloat3e/extF80_to_ui32_r_minMag.cc | 87 + src/cpu/softfloat3e/extF80_to_ui64.cc | 83 + .../softfloat3e/extF80_to_ui64_r_minMag.cc | 87 + src/cpu/softfloat3e/f128_addsub.cc | 88 + src/cpu/softfloat3e/f128_div.cc | 187 + src/cpu/softfloat3e/f128_mul.cc | 148 + src/cpu/softfloat3e/f128_mulAdd.cc | 332 ++ src/cpu/softfloat3e/f128_roundToInt.cc | 142 + src/cpu/softfloat3e/f128_to_extF80.cc | 94 + src/cpu/softfloat3e/f128_to_f32.cc | 83 + src/cpu/softfloat3e/f128_to_f64.cc | 87 + src/cpu/softfloat3e/f128_to_i32.cc | 80 + src/cpu/softfloat3e/f128_to_i32_r_minMag.cc | 89 + src/cpu/softfloat3e/f128_to_i64.cc | 90 + src/cpu/softfloat3e/f128_to_i64_r_minMag.cc | 104 + src/cpu/softfloat3e/f128_to_ui32.cc | 81 + src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc | 83 + src/cpu/softfloat3e/f128_to_ui64.cc | 90 + src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc | 99 + src/cpu/softfloat3e/f16_addsub.c | 60 + src/cpu/softfloat3e/f16_class.c | 64 + src/cpu/softfloat3e/f16_compare.c | 92 + src/cpu/softfloat3e/f16_div.c | 149 + src/cpu/softfloat3e/f16_getExp.c | 73 + src/cpu/softfloat3e/f16_getMant.c | 108 + src/cpu/softfloat3e/f16_minmax.c | 69 + src/cpu/softfloat3e/f16_mul.c | 139 + src/cpu/softfloat3e/f16_mulAdd.c | 232 + src/cpu/softfloat3e/f16_range.c | 135 + src/cpu/softfloat3e/f16_roundToInt.c | 112 + src/cpu/softfloat3e/f16_sqrt.c | 130 + src/cpu/softfloat3e/f16_to_extF80.cc | 88 + src/cpu/softfloat3e/f16_to_f32.c | 81 + src/cpu/softfloat3e/f16_to_f64.c | 81 + src/cpu/softfloat3e/f16_to_i32.c | 81 + src/cpu/softfloat3e/f16_to_i32_r_minMag.c | 82 + src/cpu/softfloat3e/f16_to_i64.c | 80 + src/cpu/softfloat3e/f16_to_i64_r_minMag.c | 82 + src/cpu/softfloat3e/f16_to_ui32.c | 79 + src/cpu/softfloat3e/f16_to_ui32_r_minMag.c | 81 + src/cpu/softfloat3e/f16_to_ui64.c | 79 + src/cpu/softfloat3e/f16_to_ui64_r_minMag.c | 81 + src/cpu/{softfloat => softfloat3e}/f2xm1.cc | 69 +- src/cpu/softfloat3e/f32_addsub.c | 60 + src/cpu/softfloat3e/f32_class.c | 64 + src/cpu/softfloat3e/f32_compare.c | 92 + src/cpu/softfloat3e/f32_div.c | 146 + src/cpu/softfloat3e/f32_frc.c | 101 + src/cpu/softfloat3e/f32_getExp.c | 73 + src/cpu/softfloat3e/f32_getMant.c | 108 + src/cpu/softfloat3e/f32_minmax.c | 69 + src/cpu/softfloat3e/f32_mul.c | 137 + src/cpu/softfloat3e/f32_mulAdd.c | 233 + src/cpu/softfloat3e/f32_range.c | 134 + src/cpu/softfloat3e/f32_roundToInt.c | 112 + src/cpu/softfloat3e/f32_scalef.c | 155 + src/cpu/softfloat3e/f32_sqrt.c | 117 + src/cpu/softfloat3e/f32_to_extF80.cc | 88 + src/cpu/softfloat3e/f32_to_f128.cc | 86 + src/cpu/softfloat3e/f32_to_f16.c | 82 + src/cpu/softfloat3e/f32_to_f64.c | 81 + src/cpu/softfloat3e/f32_to_i32.c | 78 + src/cpu/softfloat3e/f32_to_i32_r_minMag.c | 83 + src/cpu/softfloat3e/f32_to_i64.c | 79 + src/cpu/softfloat3e/f32_to_i64_r_minMag.c | 88 + src/cpu/softfloat3e/f32_to_ui32.c | 80 + src/cpu/softfloat3e/f32_to_ui32_r_minMag.c | 83 + src/cpu/softfloat3e/f32_to_ui64.c | 79 + src/cpu/softfloat3e/f32_to_ui64_r_minMag.c | 84 + src/cpu/softfloat3e/f64_addsub.c | 70 + src/cpu/softfloat3e/f64_class.c | 64 + src/cpu/softfloat3e/f64_compare.c | 92 + src/cpu/softfloat3e/f64_div.c | 165 + src/cpu/softfloat3e/f64_frc.c | 101 + src/cpu/softfloat3e/f64_getExp.c | 73 + src/cpu/softfloat3e/f64_getMant.c | 108 + src/cpu/softfloat3e/f64_minmax.c | 69 + src/cpu/softfloat3e/f64_mul.c | 139 + src/cpu/softfloat3e/f64_mulAdd.c | 243 + src/cpu/softfloat3e/f64_range.c | 135 + src/cpu/softfloat3e/f64_roundToInt.c | 112 + src/cpu/softfloat3e/f64_scalef.c | 156 + src/cpu/softfloat3e/f64_sqrt.c | 130 + src/cpu/softfloat3e/f64_to_extF80.cc | 88 + src/cpu/softfloat3e/f64_to_f128.cc | 89 + src/cpu/softfloat3e/f64_to_f16.c | 83 + src/cpu/softfloat3e/f64_to_f32.c | 83 + src/cpu/softfloat3e/f64_to_i32.c | 77 + src/cpu/softfloat3e/f64_to_i32_r_minMag.c | 89 + src/cpu/softfloat3e/f64_to_i64.c | 78 + src/cpu/softfloat3e/f64_to_i64_r_minMag.c | 95 + src/cpu/softfloat3e/f64_to_ui32.c | 77 + src/cpu/softfloat3e/f64_to_ui32_r_minMag.c | 83 + src/cpu/softfloat3e/f64_to_ui64.c | 76 + src/cpu/softfloat3e/f64_to_ui64_r_minMag.c | 87 + src/cpu/{softfloat => softfloat3e}/fpatan.cc | 169 +- src/cpu/{softfloat => softfloat3e}/fprem.cc | 144 +- .../{softfloat => softfloat3e}/fpu_constant.h | 2 +- src/cpu/softfloat3e/fpu_trans.h | 117 + src/cpu/{softfloat => softfloat3e}/fsincos.cc | 176 +- src/cpu/{softfloat => softfloat3e}/fyl2x.cc | 223 +- src/cpu/softfloat3e/i32_to_extF80.cc | 62 + src/cpu/softfloat3e/i32_to_f128.cc | 59 + src/cpu/softfloat3e/i32_to_f16.c | 61 + src/cpu/softfloat3e/i32_to_f32.c | 52 + src/cpu/softfloat3e/i32_to_f64.c | 56 + src/cpu/softfloat3e/i64_to_extF80.cc | 62 + src/cpu/softfloat3e/i64_to_f128.cc | 69 + src/cpu/softfloat3e/i64_to_f16.c | 61 + src/cpu/softfloat3e/i64_to_f32.c | 61 + src/cpu/softfloat3e/i64_to_f64.c | 53 + src/cpu/softfloat3e/internals.h | 150 + src/cpu/softfloat3e/isNaN.cc | 63 + src/cpu/softfloat3e/isSignalingNaN.cc | 63 + src/cpu/softfloat3e/opts-GCC.h | 110 + .../softfloat_poly.cc => softfloat3e/poly.cc} | 22 +- src/cpu/softfloat3e/poly.h | 43 + src/cpu/softfloat3e/primitiveTypes.h | 54 + src/cpu/softfloat3e/primitives.h | 535 +++ src/cpu/softfloat3e/s_add128.cc | 51 + src/cpu/softfloat3e/s_add256M.c | 60 + src/cpu/softfloat3e/s_addMagsExtF80.cc | 146 + src/cpu/softfloat3e/s_addMagsF128.cc | 138 + src/cpu/softfloat3e/s_addMagsF16.c | 192 + src/cpu/softfloat3e/s_addMagsF32.c | 147 + src/cpu/softfloat3e/s_addMagsF64.c | 149 + src/cpu/softfloat3e/s_approxRecipSqrt32_1.c | 63 + src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c | 46 + src/cpu/softfloat3e/s_approxRecip_1Ks.c | 46 + src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc | 69 + src/cpu/softfloat3e/s_commonNaNToF128UI.cc | 72 + src/cpu/softfloat3e/s_commonNaNToF16UI.c | 62 + src/cpu/softfloat3e/s_commonNaNToF32UI.c | 62 + src/cpu/softfloat3e/s_commonNaNToF64UI.c | 62 + src/cpu/softfloat3e/s_countLeadingZeros16.c | 56 + src/cpu/softfloat3e/s_countLeadingZeros32.c | 61 + src/cpu/softfloat3e/s_countLeadingZeros64.c | 70 + src/cpu/softfloat3e/s_countLeadingZeros8.c | 57 + src/cpu/softfloat3e/s_eq128.c | 46 + src/cpu/softfloat3e/s_le128.c | 46 + src/cpu/softfloat3e/s_lt128.c | 46 + src/cpu/softfloat3e/s_mul128By32.cc | 54 + src/cpu/softfloat3e/s_mul128To256M.cc | 62 + .../softfloat3e/s_mul64ByShifted32To128.cc | 52 + src/cpu/softfloat3e/s_mul64To128.cc | 63 + .../softfloat3e/s_normRoundPackToExtF80.cc | 62 + src/cpu/softfloat3e/s_normRoundPackToF128.cc | 75 + src/cpu/softfloat3e/s_normRoundPackToF16.c | 49 + src/cpu/softfloat3e/s_normRoundPackToF32.c | 49 + src/cpu/softfloat3e/s_normRoundPackToF64.c | 49 + .../softfloat3e/s_normSubnormalExtF80Sig.cc | 50 + src/cpu/softfloat3e/s_normSubnormalF128Sig.cc | 61 + src/cpu/softfloat3e/s_normSubnormalF16Sig.c | 50 + src/cpu/softfloat3e/s_normSubnormalF32Sig.c | 51 + src/cpu/softfloat3e/s_normSubnormalF64Sig.c | 49 + src/cpu/softfloat3e/s_packToExtF80.cc | 54 + src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc | 96 + src/cpu/softfloat3e/s_propagateNaNF128UI.cc | 78 + src/cpu/softfloat3e/s_propagateNaNF16UI.c | 57 + src/cpu/softfloat3e/s_propagateNaNF32UI.c | 57 + src/cpu/softfloat3e/s_propagateNaNF64UI.c | 57 + src/cpu/softfloat3e/s_roundPackToExtF80.cc | 224 + src/cpu/softfloat3e/s_roundPackToF128.cc | 102 + src/cpu/softfloat3e/s_roundPackToF16.c | 104 + src/cpu/softfloat3e/s_roundPackToF32.c | 108 + src/cpu/softfloat3e/s_roundPackToF64.c | 108 + src/cpu/softfloat3e/s_roundToI32.c | 79 + src/cpu/softfloat3e/s_roundToI64.c | 77 + src/cpu/softfloat3e/s_roundToUI32.c | 79 + src/cpu/softfloat3e/s_roundToUI64.c | 76 + src/cpu/softfloat3e/s_shiftRightJam128.cc | 65 + .../softfloat3e/s_shiftRightJam128Extra.cc | 73 + src/cpu/softfloat3e/s_shiftRightJam256M.c | 113 + src/cpu/softfloat3e/s_shiftRightJam32.c | 45 + src/cpu/softfloat3e/s_shiftRightJam64.c | 46 + src/cpu/softfloat3e/s_shiftRightJam64Extra.c | 57 + src/cpu/softfloat3e/s_shortShiftLeft128.cc | 51 + src/cpu/softfloat3e/s_shortShiftRight128.cc | 51 + src/cpu/softfloat3e/s_shortShiftRightJam64.c | 46 + .../softfloat3e/s_shortShiftRightJam64Extra.c | 51 + src/cpu/softfloat3e/s_sub128.cc | 50 + src/cpu/softfloat3e/s_sub256M.c | 59 + src/cpu/softfloat3e/s_subMagsExtF80.cc | 154 + src/cpu/softfloat3e/s_subMagsF128.cc | 131 + src/cpu/softfloat3e/s_subMagsF16.c | 190 + src/cpu/softfloat3e/s_subMagsF32.c | 151 + src/cpu/softfloat3e/s_subMagsF64.c | 150 + src/cpu/softfloat3e/softfloat-compare.h | 725 +++ src/cpu/softfloat3e/softfloat-extra.h | 141 + src/cpu/softfloat3e/softfloat-helpers.h | 158 + src/cpu/softfloat3e/softfloat-specialize.h | 224 + src/cpu/softfloat3e/softfloat.h | 702 +++ src/cpu/softfloat3e/softfloat_types.h | 87 + src/cpu/softfloat3e/specialize.h | 280 ++ src/cpu/softfloat3e/ui32_to_extF80.cc | 56 + src/cpu/softfloat3e/ui32_to_f128.cc | 55 + src/cpu/softfloat3e/ui32_to_f16.c | 57 + src/cpu/softfloat3e/ui32_to_f32.c | 50 + src/cpu/softfloat3e/ui32_to_f64.c | 49 + src/cpu/softfloat3e/ui64_to_extF80.cc | 56 + src/cpu/softfloat3e/ui64_to_f128.cc | 65 + src/cpu/softfloat3e/ui64_to_f16.c | 55 + src/cpu/softfloat3e/ui64_to_f32.c | 55 + src/cpu/softfloat3e/ui64_to_f64.c | 51 + src/cpu/x86_ops.h | 8 +- src/cpu/x86_ops_fpu.h | 8 + src/cpu/x86_ops_i686.h | 8 +- src/cpu/x86_ops_mmx.c | 6 +- src/cpu/x87.c | 164 +- src/cpu/x87.h | 128 +- src/cpu/x87_ops.h | 369 +- src/cpu/x87_ops_arith.h | 36 +- src/cpu/x87_ops_misc.h | 42 +- src/cpu/x87_ops_sf.h | 24 +- src/cpu/x87_ops_sf_arith.h | 205 +- src/cpu/x87_ops_sf_compare.h | 263 +- src/cpu/x87_ops_sf_const.h | 15 +- src/cpu/x87_ops_sf_load_store.h | 394 +- src/cpu/x87_ops_sf_misc.h | 1 + src/cpu/x87_ops_sf_trans.h | 153 +- 271 files changed, 25882 insertions(+), 10441 deletions(-) delete mode 100644 src/cpu/softfloat/CMakeLists.txt delete mode 100644 src/cpu/softfloat/config.h delete mode 100644 src/cpu/softfloat/softfloat-compare.h delete mode 100644 src/cpu/softfloat/softfloat-macros.h delete mode 100644 src/cpu/softfloat/softfloat-muladd.cc delete mode 100644 src/cpu/softfloat/softfloat-round-pack.cc delete mode 100644 src/cpu/softfloat/softfloat-round-pack.h delete mode 100644 src/cpu/softfloat/softfloat-specialize.cc delete mode 100644 src/cpu/softfloat/softfloat-specialize.h delete mode 100644 src/cpu/softfloat/softfloat.cc delete mode 100644 src/cpu/softfloat/softfloat.h delete mode 100644 src/cpu/softfloat/softfloat16.cc delete mode 100644 src/cpu/softfloat/softfloatx80.cc delete mode 100644 src/cpu/softfloat/softfloatx80.h create mode 100644 src/cpu/softfloat3e/CMakeLists.txt create mode 100644 src/cpu/softfloat3e/COPYING.txt create mode 100644 src/cpu/softfloat3e/README.html create mode 100644 src/cpu/softfloat3e/README.txt create mode 100644 src/cpu/softfloat3e/config.h create mode 100644 src/cpu/softfloat3e/consts.cc create mode 100644 src/cpu/softfloat3e/doc/SoftFloat-history.html create mode 100644 src/cpu/softfloat3e/doc/SoftFloat-source.html create mode 100644 src/cpu/softfloat3e/doc/SoftFloat.html create mode 100644 src/cpu/softfloat3e/extF80_addsub.cc create mode 100644 src/cpu/softfloat3e/extF80_class.cc create mode 100644 src/cpu/softfloat3e/extF80_compare.cc create mode 100644 src/cpu/softfloat3e/extF80_div.cc create mode 100644 src/cpu/softfloat3e/extF80_extract.cc create mode 100644 src/cpu/softfloat3e/extF80_mul.cc create mode 100644 src/cpu/softfloat3e/extF80_rem.cc create mode 100644 src/cpu/softfloat3e/extF80_roundToInt.cc create mode 100644 src/cpu/softfloat3e/extF80_scale.cc create mode 100644 src/cpu/softfloat3e/extF80_sqrt.cc create mode 100644 src/cpu/softfloat3e/extF80_to_f128.cc create mode 100644 src/cpu/softfloat3e/extF80_to_f16.cc create mode 100644 src/cpu/softfloat3e/extF80_to_f32.cc create mode 100644 src/cpu/softfloat3e/extF80_to_f64.cc create mode 100644 src/cpu/softfloat3e/extF80_to_i32.cc create mode 100644 src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc create mode 100644 src/cpu/softfloat3e/extF80_to_i64.cc create mode 100644 src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc create mode 100644 src/cpu/softfloat3e/extF80_to_ui32.cc create mode 100644 src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc create mode 100644 src/cpu/softfloat3e/extF80_to_ui64.cc create mode 100644 src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc create mode 100644 src/cpu/softfloat3e/f128_addsub.cc create mode 100644 src/cpu/softfloat3e/f128_div.cc create mode 100644 src/cpu/softfloat3e/f128_mul.cc create mode 100644 src/cpu/softfloat3e/f128_mulAdd.cc create mode 100644 src/cpu/softfloat3e/f128_roundToInt.cc create mode 100644 src/cpu/softfloat3e/f128_to_extF80.cc create mode 100644 src/cpu/softfloat3e/f128_to_f32.cc create mode 100644 src/cpu/softfloat3e/f128_to_f64.cc create mode 100644 src/cpu/softfloat3e/f128_to_i32.cc create mode 100644 src/cpu/softfloat3e/f128_to_i32_r_minMag.cc create mode 100644 src/cpu/softfloat3e/f128_to_i64.cc create mode 100644 src/cpu/softfloat3e/f128_to_i64_r_minMag.cc create mode 100644 src/cpu/softfloat3e/f128_to_ui32.cc create mode 100644 src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc create mode 100644 src/cpu/softfloat3e/f128_to_ui64.cc create mode 100644 src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc create mode 100644 src/cpu/softfloat3e/f16_addsub.c create mode 100644 src/cpu/softfloat3e/f16_class.c create mode 100644 src/cpu/softfloat3e/f16_compare.c create mode 100644 src/cpu/softfloat3e/f16_div.c create mode 100644 src/cpu/softfloat3e/f16_getExp.c create mode 100644 src/cpu/softfloat3e/f16_getMant.c create mode 100644 src/cpu/softfloat3e/f16_minmax.c create mode 100644 src/cpu/softfloat3e/f16_mul.c create mode 100644 src/cpu/softfloat3e/f16_mulAdd.c create mode 100644 src/cpu/softfloat3e/f16_range.c create mode 100644 src/cpu/softfloat3e/f16_roundToInt.c create mode 100644 src/cpu/softfloat3e/f16_sqrt.c create mode 100644 src/cpu/softfloat3e/f16_to_extF80.cc create mode 100644 src/cpu/softfloat3e/f16_to_f32.c create mode 100644 src/cpu/softfloat3e/f16_to_f64.c create mode 100644 src/cpu/softfloat3e/f16_to_i32.c create mode 100644 src/cpu/softfloat3e/f16_to_i32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f16_to_i64.c create mode 100644 src/cpu/softfloat3e/f16_to_i64_r_minMag.c create mode 100644 src/cpu/softfloat3e/f16_to_ui32.c create mode 100644 src/cpu/softfloat3e/f16_to_ui32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f16_to_ui64.c create mode 100644 src/cpu/softfloat3e/f16_to_ui64_r_minMag.c rename src/cpu/{softfloat => softfloat3e}/f2xm1.cc (77%) create mode 100644 src/cpu/softfloat3e/f32_addsub.c create mode 100644 src/cpu/softfloat3e/f32_class.c create mode 100644 src/cpu/softfloat3e/f32_compare.c create mode 100644 src/cpu/softfloat3e/f32_div.c create mode 100644 src/cpu/softfloat3e/f32_frc.c create mode 100644 src/cpu/softfloat3e/f32_getExp.c create mode 100644 src/cpu/softfloat3e/f32_getMant.c create mode 100644 src/cpu/softfloat3e/f32_minmax.c create mode 100644 src/cpu/softfloat3e/f32_mul.c create mode 100644 src/cpu/softfloat3e/f32_mulAdd.c create mode 100644 src/cpu/softfloat3e/f32_range.c create mode 100644 src/cpu/softfloat3e/f32_roundToInt.c create mode 100644 src/cpu/softfloat3e/f32_scalef.c create mode 100644 src/cpu/softfloat3e/f32_sqrt.c create mode 100644 src/cpu/softfloat3e/f32_to_extF80.cc create mode 100644 src/cpu/softfloat3e/f32_to_f128.cc create mode 100644 src/cpu/softfloat3e/f32_to_f16.c create mode 100644 src/cpu/softfloat3e/f32_to_f64.c create mode 100644 src/cpu/softfloat3e/f32_to_i32.c create mode 100644 src/cpu/softfloat3e/f32_to_i32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f32_to_i64.c create mode 100644 src/cpu/softfloat3e/f32_to_i64_r_minMag.c create mode 100644 src/cpu/softfloat3e/f32_to_ui32.c create mode 100644 src/cpu/softfloat3e/f32_to_ui32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f32_to_ui64.c create mode 100644 src/cpu/softfloat3e/f32_to_ui64_r_minMag.c create mode 100644 src/cpu/softfloat3e/f64_addsub.c create mode 100644 src/cpu/softfloat3e/f64_class.c create mode 100644 src/cpu/softfloat3e/f64_compare.c create mode 100644 src/cpu/softfloat3e/f64_div.c create mode 100644 src/cpu/softfloat3e/f64_frc.c create mode 100644 src/cpu/softfloat3e/f64_getExp.c create mode 100644 src/cpu/softfloat3e/f64_getMant.c create mode 100644 src/cpu/softfloat3e/f64_minmax.c create mode 100644 src/cpu/softfloat3e/f64_mul.c create mode 100644 src/cpu/softfloat3e/f64_mulAdd.c create mode 100644 src/cpu/softfloat3e/f64_range.c create mode 100644 src/cpu/softfloat3e/f64_roundToInt.c create mode 100644 src/cpu/softfloat3e/f64_scalef.c create mode 100644 src/cpu/softfloat3e/f64_sqrt.c create mode 100644 src/cpu/softfloat3e/f64_to_extF80.cc create mode 100644 src/cpu/softfloat3e/f64_to_f128.cc create mode 100644 src/cpu/softfloat3e/f64_to_f16.c create mode 100644 src/cpu/softfloat3e/f64_to_f32.c create mode 100644 src/cpu/softfloat3e/f64_to_i32.c create mode 100644 src/cpu/softfloat3e/f64_to_i32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f64_to_i64.c create mode 100644 src/cpu/softfloat3e/f64_to_i64_r_minMag.c create mode 100644 src/cpu/softfloat3e/f64_to_ui32.c create mode 100644 src/cpu/softfloat3e/f64_to_ui32_r_minMag.c create mode 100644 src/cpu/softfloat3e/f64_to_ui64.c create mode 100644 src/cpu/softfloat3e/f64_to_ui64_r_minMag.c rename src/cpu/{softfloat => softfloat3e}/fpatan.cc (59%) rename src/cpu/{softfloat => softfloat3e}/fprem.cc (53%) rename src/cpu/{softfloat => softfloat3e}/fpu_constant.h (98%) create mode 100644 src/cpu/softfloat3e/fpu_trans.h rename src/cpu/{softfloat => softfloat3e}/fsincos.cc (68%) rename src/cpu/{softfloat => softfloat3e}/fyl2x.cc (61%) create mode 100644 src/cpu/softfloat3e/i32_to_extF80.cc create mode 100644 src/cpu/softfloat3e/i32_to_f128.cc create mode 100644 src/cpu/softfloat3e/i32_to_f16.c create mode 100644 src/cpu/softfloat3e/i32_to_f32.c create mode 100644 src/cpu/softfloat3e/i32_to_f64.c create mode 100644 src/cpu/softfloat3e/i64_to_extF80.cc create mode 100644 src/cpu/softfloat3e/i64_to_f128.cc create mode 100644 src/cpu/softfloat3e/i64_to_f16.c create mode 100644 src/cpu/softfloat3e/i64_to_f32.c create mode 100644 src/cpu/softfloat3e/i64_to_f64.c create mode 100644 src/cpu/softfloat3e/internals.h create mode 100644 src/cpu/softfloat3e/isNaN.cc create mode 100644 src/cpu/softfloat3e/isSignalingNaN.cc create mode 100644 src/cpu/softfloat3e/opts-GCC.h rename src/cpu/{softfloat/softfloat_poly.cc => softfloat3e/poly.cc} (84%) create mode 100644 src/cpu/softfloat3e/poly.h create mode 100644 src/cpu/softfloat3e/primitiveTypes.h create mode 100644 src/cpu/softfloat3e/primitives.h create mode 100644 src/cpu/softfloat3e/s_add128.cc create mode 100644 src/cpu/softfloat3e/s_add256M.c create mode 100644 src/cpu/softfloat3e/s_addMagsExtF80.cc create mode 100644 src/cpu/softfloat3e/s_addMagsF128.cc create mode 100644 src/cpu/softfloat3e/s_addMagsF16.c create mode 100644 src/cpu/softfloat3e/s_addMagsF32.c create mode 100644 src/cpu/softfloat3e/s_addMagsF64.c create mode 100644 src/cpu/softfloat3e/s_approxRecipSqrt32_1.c create mode 100644 src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c create mode 100644 src/cpu/softfloat3e/s_approxRecip_1Ks.c create mode 100644 src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc create mode 100644 src/cpu/softfloat3e/s_commonNaNToF128UI.cc create mode 100644 src/cpu/softfloat3e/s_commonNaNToF16UI.c create mode 100644 src/cpu/softfloat3e/s_commonNaNToF32UI.c create mode 100644 src/cpu/softfloat3e/s_commonNaNToF64UI.c create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros16.c create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros32.c create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros64.c create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros8.c create mode 100644 src/cpu/softfloat3e/s_eq128.c create mode 100644 src/cpu/softfloat3e/s_le128.c create mode 100644 src/cpu/softfloat3e/s_lt128.c create mode 100644 src/cpu/softfloat3e/s_mul128By32.cc create mode 100644 src/cpu/softfloat3e/s_mul128To256M.cc create mode 100644 src/cpu/softfloat3e/s_mul64ByShifted32To128.cc create mode 100644 src/cpu/softfloat3e/s_mul64To128.cc create mode 100644 src/cpu/softfloat3e/s_normRoundPackToExtF80.cc create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF128.cc create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF16.c create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF32.c create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF64.c create mode 100644 src/cpu/softfloat3e/s_normSubnormalExtF80Sig.cc create mode 100644 src/cpu/softfloat3e/s_normSubnormalF128Sig.cc create mode 100644 src/cpu/softfloat3e/s_normSubnormalF16Sig.c create mode 100644 src/cpu/softfloat3e/s_normSubnormalF32Sig.c create mode 100644 src/cpu/softfloat3e/s_normSubnormalF64Sig.c create mode 100644 src/cpu/softfloat3e/s_packToExtF80.cc create mode 100644 src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc create mode 100644 src/cpu/softfloat3e/s_propagateNaNF128UI.cc create mode 100644 src/cpu/softfloat3e/s_propagateNaNF16UI.c create mode 100644 src/cpu/softfloat3e/s_propagateNaNF32UI.c create mode 100644 src/cpu/softfloat3e/s_propagateNaNF64UI.c create mode 100644 src/cpu/softfloat3e/s_roundPackToExtF80.cc create mode 100644 src/cpu/softfloat3e/s_roundPackToF128.cc create mode 100644 src/cpu/softfloat3e/s_roundPackToF16.c create mode 100644 src/cpu/softfloat3e/s_roundPackToF32.c create mode 100644 src/cpu/softfloat3e/s_roundPackToF64.c create mode 100644 src/cpu/softfloat3e/s_roundToI32.c create mode 100644 src/cpu/softfloat3e/s_roundToI64.c create mode 100644 src/cpu/softfloat3e/s_roundToUI32.c create mode 100644 src/cpu/softfloat3e/s_roundToUI64.c create mode 100644 src/cpu/softfloat3e/s_shiftRightJam128.cc create mode 100644 src/cpu/softfloat3e/s_shiftRightJam128Extra.cc create mode 100644 src/cpu/softfloat3e/s_shiftRightJam256M.c create mode 100644 src/cpu/softfloat3e/s_shiftRightJam32.c create mode 100644 src/cpu/softfloat3e/s_shiftRightJam64.c create mode 100644 src/cpu/softfloat3e/s_shiftRightJam64Extra.c create mode 100644 src/cpu/softfloat3e/s_shortShiftLeft128.cc create mode 100644 src/cpu/softfloat3e/s_shortShiftRight128.cc create mode 100644 src/cpu/softfloat3e/s_shortShiftRightJam64.c create mode 100644 src/cpu/softfloat3e/s_shortShiftRightJam64Extra.c create mode 100644 src/cpu/softfloat3e/s_sub128.cc create mode 100644 src/cpu/softfloat3e/s_sub256M.c create mode 100644 src/cpu/softfloat3e/s_subMagsExtF80.cc create mode 100644 src/cpu/softfloat3e/s_subMagsF128.cc create mode 100644 src/cpu/softfloat3e/s_subMagsF16.c create mode 100644 src/cpu/softfloat3e/s_subMagsF32.c create mode 100644 src/cpu/softfloat3e/s_subMagsF64.c create mode 100644 src/cpu/softfloat3e/softfloat-compare.h create mode 100644 src/cpu/softfloat3e/softfloat-extra.h create mode 100644 src/cpu/softfloat3e/softfloat-helpers.h create mode 100644 src/cpu/softfloat3e/softfloat-specialize.h create mode 100644 src/cpu/softfloat3e/softfloat.h create mode 100644 src/cpu/softfloat3e/softfloat_types.h create mode 100644 src/cpu/softfloat3e/specialize.h create mode 100644 src/cpu/softfloat3e/ui32_to_extF80.cc create mode 100644 src/cpu/softfloat3e/ui32_to_f128.cc create mode 100644 src/cpu/softfloat3e/ui32_to_f16.c create mode 100644 src/cpu/softfloat3e/ui32_to_f32.c create mode 100644 src/cpu/softfloat3e/ui32_to_f64.c create mode 100644 src/cpu/softfloat3e/ui64_to_extF80.cc create mode 100644 src/cpu/softfloat3e/ui64_to_f128.cc create mode 100644 src/cpu/softfloat3e/ui64_to_f16.c create mode 100644 src/cpu/softfloat3e/ui64_to_f32.c create mode 100644 src/cpu/softfloat3e/ui64_to_f64.c diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index bc6293c0b..08b9ee5f2 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -4434,7 +4434,7 @@ FP_COMPARE_REG(int dst, int src) addbyte((uint8_t) cpu_state_offset(npxs) + 1); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); if (src) { addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ @@ -4467,7 +4467,7 @@ FP_COMPARE_REG(int dst, int src) addbyte(0x9f); /*LAHF*/ addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR CL, AH*/ addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ @@ -4493,7 +4493,7 @@ FP_COMPARE_MEM(void) addbyte((uint8_t) cpu_state_offset(ST)); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0x66); /*COMISD XMM0, XMM1*/ addbyte(0x0f); addbyte(0x2f); @@ -4501,7 +4501,7 @@ FP_COMPARE_MEM(void) addbyte(0x9f); /*LAHF*/ addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR CL, AH*/ addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 410ce8e17..c48324c2a 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -2911,7 +2911,7 @@ FP_COMPARE_S(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xd8); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -2919,7 +2919,7 @@ FP_COMPARE_S(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -2943,7 +2943,7 @@ FP_COMPARE_S(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xd8); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -2951,7 +2951,7 @@ FP_COMPARE_S(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -2980,7 +2980,7 @@ FP_COMPARE_D(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xdc); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -2988,7 +2988,7 @@ FP_COMPARE_D(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3016,7 +3016,7 @@ FP_COMPARE_D(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xdc); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -3024,7 +3024,7 @@ FP_COMPARE_D(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3050,7 +3050,7 @@ FP_COMPARE_IW(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xde); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -3058,7 +3058,7 @@ FP_COMPARE_IW(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3082,7 +3082,7 @@ FP_COMPARE_IW(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xde); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -3090,7 +3090,7 @@ FP_COMPARE_IW(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3115,7 +3115,7 @@ FP_COMPARE_IL(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xda); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -3123,7 +3123,7 @@ FP_COMPARE_IL(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3147,7 +3147,7 @@ FP_COMPARE_IL(void) addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ addbyte(0xe3); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xda); /*FCOMP [ESP]*/ addbyte(0x04 | 0x18); addbyte(0x24); @@ -3155,7 +3155,7 @@ FP_COMPARE_IL(void) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR BL, AH*/ addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ @@ -3250,7 +3250,7 @@ FP_COMPARE_REG(int dst, int src) addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); addbyte(0xdc); /*FCOMP ST[src][EBP]*/ addbyte(0x5d); addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); @@ -3258,7 +3258,7 @@ FP_COMPARE_REG(int dst, int src) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR CL, AH*/ addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ @@ -3286,7 +3286,7 @@ FP_COMPARE_REG(int dst, int src) addbyte(0xe2); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); - addbyte((~(C0 | C2 | C3)) >> 8); + addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8); if (src) { addbyte(0xdd); /*FLD ST[EBX*8]*/ @@ -3312,7 +3312,7 @@ FP_COMPARE_REG(int dst, int src) addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ addbyte(0xe4); - addbyte((C0 | C2 | C3) >> 8); + addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8); addbyte(0x08); /*OR CL, AH*/ addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 7514e1f0c..421292c7e 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -648,10 +648,10 @@ codegen_FTST(codeblock_t *block, uop_t *uop) host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); host_arm64_MOVZ_IMM(block, dest_reg, 0); host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0); host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); } else @@ -690,10 +690,10 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_MOVZ_IMM(block, dest_reg, 0); host_arm64_FCMP_D(block, src_reg_a, src_reg_b); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0); host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); } else diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index 338d3dd54..04b61255b 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -718,9 +718,9 @@ codegen_FTST(codeblock_t *block, uop_t *uop) host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); host_arm_MOV_IMM(block, dest_reg, 0); host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); } else fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -758,9 +758,9 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) host_arm_VCMP_D(block, src_reg_a, src_reg_b); host_arm_MOV_IMM(block, dest_reg, 0); host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); } else fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index fcab0f3ce..1b82f9fca 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -672,7 +672,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); @@ -720,7 +720,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 5ef2d97b8..91f2c7ec3 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -677,7 +677,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); @@ -725,7 +725,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 3ab7be8ac..15a6399e6 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -59,7 +59,7 @@ ropFCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3 uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); return op_pc; @@ -71,7 +71,7 @@ ropFCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); fpu_POP(block, ir); @@ -82,7 +82,7 @@ ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); fpu_POP2(block, ir); @@ -269,7 +269,7 @@ ropFUCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); return op_pc; @@ -281,7 +281,7 @@ ropFUCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); fpu_POP(block, ir); @@ -292,7 +292,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); fpu_POP2(block, ir); @@ -328,7 +328,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f codegen_check_seg_read(block, ir, target_seg); \ load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ \ return op_pc + 1; \ @@ -344,7 +344,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f codegen_check_seg_read(block, ir, target_seg); \ load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ fpu_POP(block, ir); \ \ @@ -460,7 +460,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ \ return op_pc + 1; \ @@ -477,7 +477,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ fpu_POP(block, ir); \ \ @@ -600,7 +600,7 @@ ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3 { uop_FP_ENTER(ir); uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); return op_pc; diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index bd03a5558..fc5ba975f 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -34,5 +34,5 @@ if(DYNAREC) codegen_timing_winchip.c codegen_timing_winchip2.c) endif() -add_subdirectory(softfloat) -target_link_libraries(86Box softfloat) +add_subdirectory(softfloat3e) +target_link_libraries(86Box softfloat3e) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 900d3d7e1..ae5b4692a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,7 +21,7 @@ #ifndef EMU_CPU_H #define EMU_CPU_H -#include "softfloat/softfloat.h" +#include "softfloat3e/softfloat.h" enum { FPU_NONE, @@ -592,8 +592,6 @@ extern uint32_t eip_msr; extern uint64_t amd_efer; extern uint64_t star; -#define FPU_CW_Reserved_Bits (0xe0c0) - #define cr0 cpu_state.CR0.l #define msw cpu_state.CR0.w extern uint32_t cr2; diff --git a/src/cpu/softfloat/CMakeLists.txt b/src/cpu/softfloat/CMakeLists.txt deleted file mode 100644 index 936157185..000000000 --- a/src/cpu/softfloat/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# -# 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. -# -# CMake build script. -# -# Authors: David Hrdlička, -# -# Copyright 2020-2021 David Hrdlička. -# - -add_library(softfloat OBJECT f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc softfloat_poly.cc softfloat.cc softfloat16.cc - softfloat-muladd.cc softfloat-round-pack.cc softfloat-specialize.cc softfloatx80.cc) diff --git a/src/cpu/softfloat/config.h b/src/cpu/softfloat/config.h deleted file mode 100644 index 9e39c2d29..000000000 --- a/src/cpu/softfloat/config.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef EMU_SF_CONFIG_H -#define EMU_SF_CONFIG_H - -#include - -typedef int8_t flag; -typedef uint8_t uint8; -typedef int8_t int8; -typedef uint16_t uint16; -typedef int16_t int16; -typedef uint32_t uint32; -typedef int32_t int32; -typedef uint64_t uint64; -typedef int64_t int64; - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines a type that holds integers -| of _exactly_ the number of bits specified. For instance, for most -| implementation of C, `bits16' and `sbits16' should be `typedef'ed to -| `unsigned short int' and `signed short int' (or `short int'), respectively. -*----------------------------------------------------------------------------*/ -typedef uint8_t bits8; -typedef int8_t sbits8; -typedef uint16_t bits16; -typedef int16_t sbits16; -typedef uint32_t bits32; -typedef int32_t sbits32; -typedef uint64_t bits64; -typedef int64_t sbits64; - -typedef uint8_t Bit8u; -typedef int8_t Bit8s; -typedef uint16_t Bit16u; -typedef int16_t Bit16s; -typedef uint32_t Bit32u; -typedef int32_t Bit32s; -typedef uint64_t Bit64u; -typedef int64_t Bit64s; - -/*---------------------------------------------------------------------------- -| The `LIT64' macro takes as its argument a textual integer literal and -| if necessary ``marks'' the literal as having a 64-bit integer type. -| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be -| appended with the letters `LL' standing for `long long', which is `gcc's -| name for the 64-bit integer type. Some compilers may allow `LIT64' to be -| defined as the identity macro: `#define LIT64( a ) a'. -*----------------------------------------------------------------------------*/ -#define BX_CONST64(a) a##LL -#define BX_CPP_INLINE static __inline - -#endif /*EMU_SF_CONFIG_H*/ diff --git a/src/cpu/softfloat/softfloat-compare.h b/src/cpu/softfloat/softfloat-compare.h deleted file mode 100644 index 8b9821460..000000000 --- a/src/cpu/softfloat/softfloat-compare.h +++ /dev/null @@ -1,496 +0,0 @@ -/*============================================================================ -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#ifndef _SOFTFLOAT_COMPARE_H_ -#define _SOFTFLOAT_COMPARE_H_ - -#include "softfloat.h" - -// ======= float32 ======= // - -typedef int (*float32_compare_method)(float32, float32, struct float_status_t *status); - -// 0x00 -BX_CPP_INLINE int float32_eq_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_equal); -} - -// 0x01 -BX_CPP_INLINE int float32_lt_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_less); -} - -// 0x02 -BX_CPP_INLINE int float32_le_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_equal); -} - -// 0x03 -BX_CPP_INLINE int float32_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_unordered); -} - -// 0x04 -BX_CPP_INLINE int float32_neq_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_equal); -} - -// 0x05 -BX_CPP_INLINE int float32_nlt_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_less); -} - -// 0x06 -BX_CPP_INLINE int float32_nle_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_less) && (relation != float_relation_equal); -} - -// 0x07 -BX_CPP_INLINE int float32_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_unordered); -} - -// 0x08 -BX_CPP_INLINE int float32_eq_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_equal) || (relation == float_relation_unordered); -} - -// 0x09 -BX_CPP_INLINE int float32_nge_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_unordered); -} - -// 0x0a -BX_CPP_INLINE int float32_ngt_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_greater); -} - -// 0x0b -BX_CPP_INLINE int float32_false_quiet(float32 a, float32 b, struct float_status_t *status) -{ - float32_compare_quiet(a, b, status); - return 0; -} - -// 0x0c -BX_CPP_INLINE int float32_neq_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_equal) && (relation != float_relation_unordered); -} - -// 0x0d -BX_CPP_INLINE int float32_ge_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_greater) || (relation == float_relation_equal); -} - -// 0x0e -BX_CPP_INLINE int float32_gt_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_greater); -} - -// 0x0f -BX_CPP_INLINE int float32_true_quiet(float32 a, float32 b, struct float_status_t *status) -{ - float32_compare_quiet(a, b, status); - return 1; -} - -// 0x10 -BX_CPP_INLINE int float32_eq_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_equal); -} - -// 0x11 -BX_CPP_INLINE int float32_lt_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_less); -} - -// 0x12 -BX_CPP_INLINE int float32_le_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_equal); -} - -// 0x13 -BX_CPP_INLINE int float32_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_unordered); -} - -// 0x14 -BX_CPP_INLINE int float32_neq_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_equal); -} - -// 0x15 -BX_CPP_INLINE int float32_nlt_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_less); -} - -// 0x16 -BX_CPP_INLINE int float32_nle_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_less) && (relation != float_relation_equal); -} - -// 0x17 -BX_CPP_INLINE int float32_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_unordered); -} - -// 0x18 -BX_CPP_INLINE int float32_eq_unordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation == float_relation_equal) || (relation == float_relation_unordered); -} - -// 0x19 -BX_CPP_INLINE int float32_nge_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_unordered); -} - -// 0x1a -BX_CPP_INLINE int float32_ngt_unordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation != float_relation_greater); -} - -// 0x1b -BX_CPP_INLINE int float32_false_signalling(float32 a, float32 b, struct float_status_t *status) -{ - float32_compare_two(a, b, status); - return 0; -} - -// 0x1c -BX_CPP_INLINE int float32_neq_ordered_signalling(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_two(a, b, status); - return (relation != float_relation_equal) && (relation != float_relation_unordered); -} - -// 0x1d -BX_CPP_INLINE int float32_ge_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_greater) || (relation == float_relation_equal); -} - -// 0x1e -BX_CPP_INLINE int float32_gt_ordered_quiet(float32 a, float32 b, struct float_status_t *status) -{ - int relation = float32_compare_quiet(a, b, status); - return (relation == float_relation_greater); -} - -// 0x1f -BX_CPP_INLINE int float32_true_signalling(float32 a, float32 b, struct float_status_t *status) -{ - float32_compare_two(a, b, status); - return 1; -} - -// ======= float64 ======= // - -typedef int (*float64_compare_method)(float64, float64, struct float_status_t *status); - -// 0x00 -BX_CPP_INLINE int float64_eq_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_equal); -} - -// 0x01 -BX_CPP_INLINE int float64_lt_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_less); -} - -// 0x02 -BX_CPP_INLINE int float64_le_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_equal); -} - -// 0x03 -BX_CPP_INLINE int float64_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_unordered); -} - -// 0x04 -BX_CPP_INLINE int float64_neq_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_equal); -} - -// 0x05 -BX_CPP_INLINE int float64_nlt_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_less); -} - -// 0x06 -BX_CPP_INLINE int float64_nle_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_less) && (relation != float_relation_equal); -} - -// 0x07 -BX_CPP_INLINE int float64_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_unordered); -} - -// 0x08 -BX_CPP_INLINE int float64_eq_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_equal) || (relation == float_relation_unordered); -} - -// 0x09 -BX_CPP_INLINE int float64_nge_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_unordered); -} - -// 0x0a -BX_CPP_INLINE int float64_ngt_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_greater); -} - -// 0x0b -BX_CPP_INLINE int float64_false_quiet(float64 a, float64 b, struct float_status_t *status) -{ - float64_compare_quiet(a, b, status); - return 0; -} - -// 0x0c -BX_CPP_INLINE int float64_neq_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_equal) && (relation != float_relation_unordered); -} - -// 0x0d -BX_CPP_INLINE int float64_ge_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_greater) || (relation == float_relation_equal); -} - -// 0x0e -BX_CPP_INLINE int float64_gt_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_greater); -} - -// 0x0f -BX_CPP_INLINE int float64_true_quiet(float64 a, float64 b, struct float_status_t *status) -{ - float64_compare_quiet(a, b, status); - return 1; -} - -// 0x10 -BX_CPP_INLINE int float64_eq_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_equal); -} - -// 0x11 -BX_CPP_INLINE int float64_lt_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_less); -} - -// 0x12 -BX_CPP_INLINE int float64_le_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_equal); -} - -// 0x13 -BX_CPP_INLINE int float64_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_unordered); -} - -// 0x14 -BX_CPP_INLINE int float64_neq_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_equal); -} - -// 0x15 -BX_CPP_INLINE int float64_nlt_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_less); -} - -// 0x16 -BX_CPP_INLINE int float64_nle_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_less) && (relation != float_relation_equal); -} - -// 0x17 -BX_CPP_INLINE int float64_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_unordered); -} - -// 0x18 -BX_CPP_INLINE int float64_eq_unordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation == float_relation_equal) || (relation == float_relation_unordered); -} - -// 0x19 -BX_CPP_INLINE int float64_nge_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_less) || (relation == float_relation_unordered); -} - -// 0x1a -BX_CPP_INLINE int float64_ngt_unordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation != float_relation_greater); -} - -// 0x1b -BX_CPP_INLINE int float64_false_signalling(float64 a, float64 b, struct float_status_t *status) -{ - float64_compare_two(a, b, status); - return 0; -} - -// 0x1c -BX_CPP_INLINE int float64_neq_ordered_signalling(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_two(a, b, status); - return (relation != float_relation_equal) && (relation != float_relation_unordered); -} - -// 0x1d -BX_CPP_INLINE int float64_ge_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_greater) || (relation == float_relation_equal); -} - -// 0x1e -BX_CPP_INLINE int float64_gt_ordered_quiet(float64 a, float64 b, struct float_status_t *status) -{ - int relation = float64_compare_quiet(a, b, status); - return (relation == float_relation_greater); -} - -// 0x1f -BX_CPP_INLINE int float64_true_signalling(float64 a, float64 b, struct float_status_t *status) -{ - float64_compare_two(a, b, status); - return 1; -} - -#endif diff --git a/src/cpu/softfloat/softfloat-macros.h b/src/cpu/softfloat/softfloat-macros.h deleted file mode 100644 index cb867bf5d..000000000 --- a/src/cpu/softfloat/softfloat-macros.h +++ /dev/null @@ -1,686 +0,0 @@ -/*============================================================================ -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#ifndef _SOFTFLOAT_MACROS_H_ -#define _SOFTFLOAT_MACROS_H_ - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 16, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit16u shift16RightJamming(Bit16u a, int count) -{ - Bit16u z; - - if (count == 0) { - z = a; - } - else if (count < 16) { - z = (a>>count) | ((a<<((-count) & 15)) != 0); - } - else { - z = (a != 0); - } - - return z; -} - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 32, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit32u shift32RightJamming(Bit32u a, int count) -{ - Bit32u z; - - if (count == 0) { - z = a; - } - else if (count < 32) { - z = (a>>count) | ((a<<((-count) & 31)) != 0); - } - else { - z = (a != 0); - } - - return z; -} - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 64, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit64u shift64RightJamming(Bit64u a, int count) -{ - Bit64u z; - - if (count == 0) { - z = a; - } - else if (count < 64) { - z = (a>>count) | ((a << ((-count) & 63)) != 0); - } - else { - z = (a != 0); - } - - return z; -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 -| _plus_ the number of bits given in `count'. The shifted result is at most -| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The -| bits shifted off form a second 64-bit result as follows: The _last_ bit -| shifted off is the most-significant bit of the extra result, and the other -| 63 bits of the extra result are all zero if and only if _all_but_the_last_ -| bits shifted off were all zero. This extra result is stored in the location -| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. -| (This routine makes more sense if `a0' and `a1' are considered to form -| a fixed-point value with binary point between `a0' and `a1'. This fixed- -| point value is shifted right by the number of bits given in `count', and -| the integer part of the result is returned at the location pointed to by -| `z0Ptr'. The fractional part of the result may be slightly corrupted as -| described above, and is returned at the location pointed to by `z1Ptr'.) -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void shift64ExtraRightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit64u z0, z1; - int negCount = (-count) & 63; - - if (count == 0) { - z1 = a1; - z0 = a0; - } - else if (count < 64) { - z1 = (a0<>count; - } - else { - if (count == 64) { - z1 = a0 | (a1 != 0); - } - else { - z1 = ((a0 | a1) != 0); - } - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit -| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so -| any carry out is lost. The result is broken into two 64-bit pieces which -| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void add128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit64u z1 = a1 + b1; - *z1Ptr = z1; - *z0Ptr = a0 + b0 + (z1 < a1); -} - -/*---------------------------------------------------------------------------- -| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the -| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo -| 2^128, so any borrow out (carry out) is lost. The result is broken into two -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and -| `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void - sub128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - *z1Ptr = a1 - b1; - *z0Ptr = a0 - b0 - (a1 < b1); -} - -/*---------------------------------------------------------------------------- -| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken -| into two 64-bit pieces which are stored at the locations pointed to by -| `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void mul64To128(Bit64u a, Bit64u b, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit32u aHigh, aLow, bHigh, bLow; - Bit64u z0, zMiddleA, zMiddleB, z1; - - aLow = (Bit32u) a; - aHigh = (Bit32u)(a>>32); - bLow = (Bit32u) b; - bHigh = (Bit32u)(b>>32); - z1 = ((Bit64u) aLow) * bLow; - zMiddleA = ((Bit64u) aLow) * bHigh; - zMiddleB = ((Bit64u) aHigh) * bLow; - z0 = ((Bit64u) aHigh) * bHigh; - zMiddleA += zMiddleB; - z0 += (((Bit64u) (zMiddleA < zMiddleB))<<32) + (zMiddleA>>32); - zMiddleA <<= 32; - z1 += zMiddleA; - z0 += (z1 < zMiddleA); - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the 64-bit integer quotient obtained by dividing -| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The -| divisor `b' must be at least 2^63. If q is the exact quotient truncated -| toward zero, the approximation returned lies between q and q + 2 inclusive. -| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit -| unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -#ifdef USE_estimateDiv128To64 -static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b) -{ - Bit64u b0, b1; - Bit64u rem0, rem1, term0, term1; - Bit64u z; - - if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF); - b0 = b>>32; - z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32; - mul64To128(b, z, &term0, &term1); - sub128(a0, a1, term0, term1, &rem0, &rem1); - while (((Bit64s) rem0) < 0) { - z -= BX_CONST64(0x100000000); - b1 = b<<32; - add128(rem0, rem1, b0, b1, &rem0, &rem1); - } - rem0 = (rem0<<32) | (rem1>>32); - z |= (b0<<32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; - return z; -} -#endif - -/*---------------------------------------------------------------------------- -| Returns an approximation to the square root of the 32-bit significand given -| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of -| `aExp' (the least significant bit) is 1, the integer returned approximates -| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' -| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either -| case, the approximation returned lies strictly within +/-2 of the exact -| value. -*----------------------------------------------------------------------------*/ - -#ifdef USE_estimateSqrt32 -static Bit32u estimateSqrt32(Bit16s aExp, Bit32u a) -{ - static const Bit16u sqrtOddAdjustments[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; - static const Bit16u sqrtEvenAdjustments[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - Bit32u z; - - int index = (a>>27) & 15; - if (aExp & 1) { - z = 0x4000 + (a>>17) - sqrtOddAdjustments[index]; - z = ((a / z)<<14) + (z<<15); - a >>= 1; - } - else { - z = 0x8000 + (a>>17) - sqrtEvenAdjustments[index]; - z = a / z + z; - z = (0x20000 <= z) ? 0xFFFF8000 : (z<<15); - if (z <= a) return (Bit32u) (((Bit32s) a)>>1); - } - return ((Bit32u) ((((Bit64u) a)<<31) / z)) + (z>>1); -} -#endif - -static const int countLeadingZeros8[] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#ifdef FLOAT16 - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 16 is returned. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int countLeadingZeros16(Bit16u a) -{ - int shiftCount = 0; - if (a < 0x100) { - shiftCount += 8; - a <<= 8; - } - shiftCount += countLeadingZeros8[a>>8]; - return shiftCount; -} - -#endif - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int countLeadingZeros32(Bit32u a) -{ - int shiftCount = 0; - if (a < 0x10000) { - shiftCount += 16; - a <<= 16; - } - if (a < 0x1000000) { - shiftCount += 8; - a <<= 8; - } - shiftCount += countLeadingZeros8[a>>24]; - return shiftCount; -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int countLeadingZeros64(Bit64u a) -{ - int shiftCount = 0; - if (a < BX_CONST64(0x100000000)) { - shiftCount += 32; - } - else { - a >>= 32; - } - shiftCount += countLeadingZeros32((Bit32u)(a)); - return shiftCount; -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' can be arbitrarily large; in particular, if `count' is greater -| than 128, the result will be 0. The result is broken into two 64-bit pieces -| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void shift128Right(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit64u z0, z1; - int negCount = (-count) & 63; - - if (count == 0) { - z1 = a1; - z0 = a0; - } - else if (count < 64) { - z1 = (a0<>count); - z0 = a0>>count; - } - else { - z1 = (count < 128) ? (a0>>(count & 63)) : 0; - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. If any nonzero bits are shifted off, they -| are ``jammed'' into the least significant bit of the result by setting the -| least significant bit to 1. The value of `count' can be arbitrarily large; -| in particular, if `count' is greater than 128, the result will be either -| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or -| nonzero. The result is broken into two 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void shift128RightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit64u z0, z1; - int negCount = (-count) & 63; - - if (count == 0) { - z1 = a1; - z0 = a0; - } - else if (count < 64) { - z1 = (a0<>count) | ((a1<>count; - } - else { - if (count == 64) { - z1 = a0 | (a1 != 0); - } - else if (count < 128) { - z1 = (a0>>(count & 63)) | (((a0<>((-count) & 63)); -} - -/*---------------------------------------------------------------------------- -| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the -| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is -| modulo 2^192, so any carry out is lost. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void add192( - Bit64u a0, - Bit64u a1, - Bit64u a2, - Bit64u b0, - Bit64u b1, - Bit64u b2, - Bit64u *z0Ptr, - Bit64u *z1Ptr, - Bit64u *z2Ptr -) -{ - Bit64u z0, z1, z2; - unsigned carry0, carry1; - - z2 = a2 + b2; - carry1 = (z2 < a2); - z1 = a1 + b1; - carry0 = (z1 < a1); - z0 = a0 + b0; - z1 += carry1; - z0 += (z1 < carry1); - z0 += carry0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' -| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. -| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The -| result is broken into three 64-bit pieces which are stored at the locations -| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void sub192( - Bit64u a0, - Bit64u a1, - Bit64u a2, - Bit64u b0, - Bit64u b1, - Bit64u b2, - Bit64u *z0Ptr, - Bit64u *z1Ptr, - Bit64u *z2Ptr -) -{ - Bit64u z0, z1, z2; - unsigned borrow0, borrow1; - - z2 = a2 - b2; - borrow1 = (a2 < b2); - z1 = a1 - b1; - borrow0 = (a1 < b1); - z0 = a0 - b0; - z0 -= (z1 < borrow1); - z1 -= borrow1; - z0 -= borrow0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' -| is equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int eq128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1) -{ - return (a0 == b0) && (a1 == b1); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than or equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int le128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1) -{ - return (a0 < b0) || ((a0 == b0) && (a1 <= b1)); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, -| returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int lt128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1) -{ - return (a0 < b0) || ((a0 == b0) && (a1 < b1)); -} - -#endif /* FLOATX80 */ - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by -| `b' to obtain a 192-bit product. The product is broken into three 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and -| `z2Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void mul128By64To192( - Bit64u a0, - Bit64u a1, - Bit64u b, - Bit64u *z0Ptr, - Bit64u *z1Ptr, - Bit64u *z2Ptr -) -{ - Bit64u z0, z1, z2, more1; - - mul64To128(a1, b, &z1, &z2); - mul64To128(a0, b, &z0, &more1); - add128(z0, more1, 0, z1, &z0, &z1); - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; -} - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the -| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit -| product. The product is broken into four 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void mul128To256( - Bit64u a0, - Bit64u a1, - Bit64u b0, - Bit64u b1, - Bit64u *z0Ptr, - Bit64u *z1Ptr, - Bit64u *z2Ptr, - Bit64u *z3Ptr -) -{ - Bit64u z0, z1, z2, z3; - Bit64u more1, more2; - - mul64To128(a1, b1, &z2, &z3); - mul64To128(a1, b0, &z1, &more2); - add128(z1, more2, 0, z2, &z1, &z2); - mul64To128(a0, b0, &z0, &more1); - add128(z0, more1, 0, z1, &z0, &z1); - mul64To128(a0, b1, &more1, &more2); - add128(more1, more2, 0, z2, &more1, &z2); - add128(z0, z1, 0, more1, &z0, &z1); - *z3Ptr = z3; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; -} - - -/*---------------------------------------------------------------------------- -| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right -| by 64 _plus_ the number of bits given in `count'. The shifted result is -| at most 128 nonzero bits; these are broken into two 64-bit pieces which are -| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted -| off form a third 64-bit result as follows: The _last_ bit shifted off is -| the most-significant bit of the extra result, and the other 63 bits of the -| extra result are all zero if and only if _all_but_the_last_ bits shifted off -| were all zero. This extra result is stored in the location pointed to by -| `z2Ptr'. The value of `count' can be arbitrarily large. -| (This routine makes more sense if `a0', `a1', and `a2' are considered -| to form a fixed-point value with binary point between `a1' and `a2'. This -| fixed-point value is shifted right by the number of bits given in `count', -| and the integer part of the result is returned at the locations pointed to -| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly -| corrupted as described above, and is returned at the location pointed to by -| `z2Ptr'.) -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void shift128ExtraRightJamming( - Bit64u a0, - Bit64u a1, - Bit64u a2, - int count, - Bit64u *z0Ptr, - Bit64u *z1Ptr, - Bit64u *z2Ptr -) -{ - Bit64u z0, z1, z2; - int negCount = (-count) & 63; - - if (count == 0) { - z2 = a2; - z1 = a1; - z0 = a0; - } - else { - if (count < 64) { - z2 = a1<>count); - z0 = a0>>count; - } - else { - if (count == 64) { - z2 = a1; - z1 = a0; - } - else { - a2 |= a1; - if (count < 128) { - z2 = a0<>(count & 63); - } - else { - z2 = (count == 128) ? a0 : (a0 != 0); - z1 = 0; - } - } - z0 = 0; - } - z2 |= (a2 != 0); - } - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; -} - -#endif /* FLOAT128 */ - -#endif diff --git a/src/cpu/softfloat/softfloat-muladd.cc b/src/cpu/softfloat/softfloat-muladd.cc deleted file mode 100644 index 7c9fec70e..000000000 --- a/src/cpu/softfloat/softfloat-muladd.cc +++ /dev/null @@ -1,558 +0,0 @@ -/*============================================================================ -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * This code is based on QEMU patch by Peter Maydell - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "softfloat.h" -#include "softfloat-round-pack.h" - -/*---------------------------------------------------------------------------- -| Primitive arithmetic functions, including multi-word arithmetic, and -| division and square root approximations. (Can be specialized to target -| if desired). -*----------------------------------------------------------------------------*/ -#include "softfloat-macros.h" - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Takes three single-precision floating-point values `a', `b' and `c', one of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*----------------------------------------------------------------------------*/ - -static float32 propagateFloat32MulAddNaN(float32 a, float32 b, float32 c, struct float_status_t *status) -{ - int aIsNaN = float32_is_nan(a); - int bIsNaN = float32_is_nan(b); - - int aIsSignalingNaN = float32_is_signaling_nan(a); - int bIsSignalingNaN = float32_is_signaling_nan(b); - int cIsSignalingNaN = float32_is_signaling_nan(c); - - a |= 0x00400000; - b |= 0x00400000; - c |= 0x00400000; - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) - float_raise(status, float_flag_invalid); - - // operate according to float_first_operand_nan mode - if (aIsSignalingNaN | aIsNaN) { - return a; - } - else { - return (bIsSignalingNaN | bIsNaN) ? b : c; - } -} - -/*---------------------------------------------------------------------------- -| Takes three double-precision floating-point values `a', `b' and `c', one of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64MulAddNaN(float64 a, float64 b, float64 c, struct float_status_t *status) -{ - int aIsNaN = float64_is_nan(a); - int bIsNaN = float64_is_nan(b); - - int aIsSignalingNaN = float64_is_signaling_nan(a); - int bIsSignalingNaN = float64_is_signaling_nan(b); - int cIsSignalingNaN = float64_is_signaling_nan(c); - - a |= BX_CONST64(0x0008000000000000); - b |= BX_CONST64(0x0008000000000000); - c |= BX_CONST64(0x0008000000000000); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) - float_raise(status, float_flag_invalid); - - // operate according to float_first_operand_nan mode - if (aIsSignalingNaN | aIsNaN) { - return a; - } - else { - return (bIsSignalingNaN | bIsNaN) ? b : c; - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negating -| externally will flip the sign bit on NaNs.) -*----------------------------------------------------------------------------*/ - -float32 float32_muladd(float32 a, float32 b, float32 c, int flags, struct float_status_t *status) -{ - int aSign, bSign, cSign, zSign; - Bit16s aExp, bExp, cExp, pExp, zExp; - Bit32u aSig, bSig, cSig; - int pInf, pZero, pSign; - Bit64u pSig64, cSig64, zSig64; - Bit32u pSig; - int shiftcount; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - bSign = extractFloat32Sign(b); - cSig = extractFloat32Frac(c); - cExp = extractFloat32Exp(c); - cSign = extractFloat32Sign(c); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp == 0xff) && aSig) || - ((bExp == 0xff) && bSig) || - ((cExp == 0xff) && cSig)) { - return propagateFloat32MulAddNaN(a, b, c, status); - } - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - if (cExp == 0) cSig = 0; - } - - int infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) || - (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0)); - - if (infzero) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - - if (flags & float_muladd_negate_c) { - cSign ^= 1; - } - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0xff) || (bExp == 0xff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0xff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - /* Otherwise generate an infinity of the same sign */ - if ((aSig && aExp == 0) || (bSig && bExp == 0)) { - float_raise(status, float_flag_denormal); - } - return packFloat32(cSign, 0xff, 0); - } - - if (pInf) { - if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) { - float_raise(status, float_flag_denormal); - } - return packFloat32(pSign, 0xff, 0); - } - - if (pZero) { - if (cExp == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (get_float_rounding_mode(status) == float_round_down) { - zSign = 1; - } else { - zSign = 0; - } - return packFloat32(zSign, 0, 0); - } - /* Exact zero plus a denormal */ - float_raise(status, float_flag_denormal); - if (get_flush_underflow_to_zero(status)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat32(cSign, 0, 0); - } - } - /* Zero plus something non-zero */ - return packFloat32(cSign, cExp, cSig); - } - - if (aExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat32() takes. - */ - pExp = aExp + bExp - 0x7e; - aSig = (aSig | 0x00800000) << 7; - bSig = (bSig | 0x00800000) << 8; - pSig64 = (Bit64u)aSig * bSig; - if ((Bit64s)(pSig64 << 1) >= 0) { - pSig64 <<= 1; - pExp--; - } - - zSign = pSign; - - /* Now pSig64 is the significand of the multiply, with the explicit bit in - * position 62. - */ - if (cExp == 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - pSig = (Bit32u) shift64RightJamming(pSig64, 32); - return roundAndPackFloat32(zSign, pExp - 1, pSig, status); - } - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - - cSig64 = (Bit64u)cSig << 39; - cSig64 |= BX_CONST64(0x4000000000000000); - int expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - cSig64 = shift64RightJamming(cSig64, expDiff); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - pSig64 = shift64RightJamming(pSig64, -expDiff); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = cExp; - } - /* Add significands and make sure explicit bit ends up in posn 62 */ - zSig64 = pSig64 + cSig64; - if ((Bit64s)zSig64 < 0) { - zSig64 = shift64RightJamming(zSig64, 1); - } else { - zExp--; - } - zSig64 = shift64RightJamming(zSig64, 32); - return roundAndPackFloat32(zSign, zExp, zSig64, status); - } else { - /* Subtraction */ - if (expDiff > 0) { - cSig64 = shift64RightJamming(cSig64, expDiff); - zSig64 = pSig64 - cSig64; - zExp = pExp; - } else if (expDiff < 0) { - pSig64 = shift64RightJamming(pSig64, -expDiff); - zSig64 = cSig64 - pSig64; - zExp = cExp; - zSign ^= 1; - } else { - zExp = pExp; - if (cSig64 < pSig64) { - zSig64 = pSig64 - cSig64; - } else if (pSig64 < cSig64) { - zSig64 = cSig64 - pSig64; - zSign ^= 1; - } else { - /* Exact zero */ - return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0); - } - } - --zExp; - /* Do the equivalent of normalizeRoundAndPackFloat32() but - * starting with the significand in a Bit64u. - */ - shiftcount = countLeadingZeros64(zSig64) - 1; - zSig64 <<= shiftcount; - zExp -= shiftcount; - zSig64 = shift64RightJamming(zSig64, 32); - return roundAndPackFloat32(zSign, zExp, zSig64, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negating -| externally will flip the sign bit on NaNs.) -*----------------------------------------------------------------------------*/ - -float64 float64_muladd(float64 a, float64 b, float64 c, int flags, struct float_status_t *status) -{ - int aSign, bSign, cSign, zSign; - Bit16s aExp, bExp, cExp, pExp, zExp; - Bit64u aSig, bSig, cSig; - int pInf, pZero, pSign; - Bit64u pSig0, pSig1, cSig0, cSig1, zSig0, zSig1; - int shiftcount; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - bSign = extractFloat64Sign(b); - cSig = extractFloat64Frac(c); - cExp = extractFloat64Exp(c); - cSign = extractFloat64Sign(c); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp == 0x7ff) && aSig) || - ((bExp == 0x7ff) && bSig) || - ((cExp == 0x7ff) && cSig)) { - return propagateFloat64MulAddNaN(a, b, c, status); - } - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - if (cExp == 0) cSig = 0; - } - - int infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) || - (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0)); - - if (infzero) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - - if (flags & float_muladd_negate_c) { - cSign ^= 1; - } - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0x7ff) || (bExp == 0x7ff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0x7ff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - /* Otherwise generate an infinity of the same sign */ - if ((aSig && aExp == 0) || (bSig && bExp == 0)) { - float_raise(status, float_flag_denormal); - } - return packFloat64(cSign, 0x7ff, 0); - } - - if (pInf) { - if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) { - float_raise(status, float_flag_denormal); - } - return packFloat64(pSign, 0x7ff, 0); - } - - if (pZero) { - if (cExp == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (get_float_rounding_mode(status) == float_round_down) { - zSign = 1; - } else { - zSign = 0; - } - return packFloat64(zSign, 0, 0); - } - /* Exact zero plus a denormal */ - float_raise(status, float_flag_denormal); - if (get_flush_underflow_to_zero(status)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat64(cSign, 0, 0); - } - } - /* Zero plus something non-zero */ - return packFloat64(cSign, cExp, cSig); - } - - if (aExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat64() takes. - */ - pExp = aExp + bExp - 0x3fe; - aSig = (aSig | BX_CONST64(0x0010000000000000))<<10; - bSig = (bSig | BX_CONST64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &pSig0, &pSig1); - if ((Bit64s)(pSig0 << 1) >= 0) { - shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); - pExp--; - } - - zSign = pSign; - - /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit - * bit in position 126. - */ - if (cExp == 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); - return roundAndPackFloat64(zSign, pExp - 1, pSig1, status); - } - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - - cSig0 = cSig << 10; - cSig1 = 0; - cSig0 |= BX_CONST64(0x4000000000000000); - int expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = cExp; - } - /* Add significands and make sure explicit bit ends up in posn 126 */ - add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - if ((Bit64s)zSig0 < 0) { - shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); - } else { - zExp--; - } - shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); - return roundAndPackFloat64(zSign, zExp, zSig1, status); - } else { - /* Subtraction */ - if (expDiff > 0) { - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - zExp = pExp; - } else if (expDiff < 0) { - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zExp = cExp; - zSign ^= 1; - } else { - zExp = pExp; - if (lt128(cSig0, cSig1, pSig0, pSig1)) { - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - } else if (lt128(pSig0, pSig1, cSig0, cSig1)) { - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zSign ^= 1; - } else { - /* Exact zero */ - return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0); - } - } - --zExp; - /* Do the equivalent of normalizeRoundAndPackFloat64() but - * starting with the significand in a pair of Bit64u. - */ - if (zSig0) { - shiftcount = countLeadingZeros64(zSig0) - 1; - shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); - if (zSig1) { - zSig0 |= 1; - } - zExp -= shiftcount; - } else { - shiftcount = countLeadingZeros64(zSig1) - 1; - zSig0 = zSig1 << shiftcount; - zExp -= (shiftcount + 64); - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - } -} diff --git a/src/cpu/softfloat/softfloat-round-pack.cc b/src/cpu/softfloat/softfloat-round-pack.cc deleted file mode 100644 index 2b3965840..000000000 --- a/src/cpu/softfloat/softfloat-round-pack.cc +++ /dev/null @@ -1,896 +0,0 @@ -/*============================================================================ -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -#define FLOAT128 - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "softfloat.h" -#include "softfloat-round-pack.h" - -/*---------------------------------------------------------------------------- -| Primitive arithmetic functions, including multi-word arithmetic, and -| division and square root approximations. (Can be specialized to target -| if desired). -*----------------------------------------------------------------------------*/ -#include "softfloat-macros.h" - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the integer -| indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s roundAndPackInt32(int zSign, Bit64u exactAbsZ, struct float_status_t *status) -{ - int roundingMode = get_float_rounding_mode(status); - int roundNearestEven = (roundingMode == float_round_nearest_even); - int roundIncrement = 0x40; - if (! roundNearestEven) { - if (roundingMode == float_round_to_zero) roundIncrement = 0; - else { - roundIncrement = 0x7F; - if (zSign) { - if (roundingMode == float_round_up) roundIncrement = 0; - } - else { - if (roundingMode == float_round_down) roundIncrement = 0; - } - } - } - int roundBits = (int)(exactAbsZ & 0x7F); - Bit64u absZ = (exactAbsZ + roundIncrement)>>7; - absZ &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven); - Bit32s z = (Bit32s) absZ; - if (zSign) z = -z; - if ((absZ>>32) || (z && ((z < 0) ^ zSign))) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if (roundBits) { - float_raise(status, float_flag_inexact); - if ((absZ << 7) > exactAbsZ) - set_float_rounding_up(status); - } - return z; -} - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status) -{ - Bit64s z; - int roundingMode = get_float_rounding_mode(status); - int roundNearestEven = (roundingMode == float_round_nearest_even); - int increment = ((Bit64s) absZ1 < 0); - if (! roundNearestEven) { - if (roundingMode == float_round_to_zero) increment = 0; - else { - if (zSign) { - increment = (roundingMode == float_round_down) && absZ1; - } - else { - increment = (roundingMode == float_round_up) && absZ1; - } - } - } - Bit64u exactAbsZ0 = absZ0; - if (increment) { - ++absZ0; - if (absZ0 == 0) goto overflow; - absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven); - } - z = absZ0; - if (zSign) z = -z; - if (z && ((z < 0) ^ zSign)) { - overflow: - float_raise(status, float_flag_invalid); - return (Bit64s)(int64_indefinite); - } - if (absZ1) { - float_raise(status, float_flag_inexact); - if (absZ0 > exactAbsZ0) - set_float_rounding_up(status); - } - return z; -} - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit unsigned integer corresponding to the -| input. Ordinarily, the fixed-point input is simply rounded to an integer, -| with the inexact exception raised if the input cannot be represented exactly -| as an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status) -{ - int roundingMode = get_float_rounding_mode(status); - int roundNearestEven = (roundingMode == float_round_nearest_even); - int increment = ((Bit64s) absZ1 < 0); - if (!roundNearestEven) { - if (roundingMode == float_round_to_zero) { - increment = 0; - } else if (absZ1) { - if (zSign) { - increment = (roundingMode == float_round_down) && absZ1; - } else { - increment = (roundingMode == float_round_up) && absZ1; - } - } - } - if (increment) { - ++absZ0; - if (absZ0 == 0) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven); - } - - if (zSign && absZ0) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - if (absZ1) { - float_raise(status, float_flag_inexact); - } - return absZ0; -} - -#ifdef FLOAT16 - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal half-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr) -{ - int shiftCount = countLeadingZeros16(aSig) - 5; - *zSigPtr = aSig<> 4; - zSigRound &= ~(((roundBits ^ 0x10) == 0) & roundNearestEven); - if (zSigRound == 0) zExp = 0; - return packFloat16(zSign, zExp, zSigRound); -} - -#endif - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr) -{ - int shiftCount = countLeadingZeros32(aSig) - 8; - *zSigPtr = aSig<> 7; - zSigRound &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven); - if (zSigRound == 0) zExp = 0; - if (roundBits) { - float_raise(status, float_flag_inexact); - if ((zSigRound << 7) > zSig) set_float_rounding_up(status); - } - return packFloat32(zSign, zExp, zSigRound); -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status) -{ - int shiftCount = countLeadingZeros32(zSig) - 1; - return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<>10; - zSigRound &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven); - if (zSigRound == 0) zExp = 0; - if (roundBits) { - float_raise(status, float_flag_inexact); - if ((zSigRound << 10) > zSig) set_float_rounding_up(status); - } - return packFloat64(zSign, zExp, zSigRound); -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status) -{ - int shiftCount = countLeadingZeros64(zSig) - 1; - return roundAndPackFloat64(zSign, zExp - shiftCount, zSig< zSigExact) set_float_rounding_up(status); - } - return packFloatx80(zSign, zExp, zSig0); - } - } - if (roundBits) float_raise(status, float_flag_inexact); - zSigExact = zSig0; - zSig0 += roundIncrement; - if (zSig0 < roundIncrement) { - // Basically scale by shifting right and keep overflow - ++zExp; - zSig0 = BX_CONST64(0x8000000000000000); - zSigExact >>= 1; // must scale also, or else later tests will fail - } - roundIncrement = roundMask + 1; - if (roundNearestEven && (roundBits<<1 == roundIncrement)) - roundMask |= roundIncrement; - zSig0 &= ~roundMask; - if (zSig0 > zSigExact) set_float_rounding_up(status); - if (zSig0 == 0) zExp = 0; - return packFloatx80(zSign, zExp, zSig0); - precision80: - increment = ((Bit64s) zSig1 < 0); - if (! roundNearestEven) { - if (roundingMode == float_round_to_zero) increment = 0; - else { - if (zSign) { - increment = (roundingMode == float_round_down) && zSig1; - } - else { - increment = (roundingMode == float_round_up) && zSig1; - } - } - } - if (0x7FFD <= (Bit32u) (zExp - 1)) { - if ((0x7FFE < zExp) - || ((zExp == 0x7FFE) - && (zSig0 == BX_CONST64(0xFFFFFFFFFFFFFFFF)) - && increment)) - { - roundMask = 0; - overflow: - float_raise(status, float_flag_overflow | float_flag_inexact); - if ((roundingMode == float_round_to_zero) - || (zSign && (roundingMode == float_round_up)) - || (! zSign && (roundingMode == float_round_down))) - { - return packFloatx80(zSign, 0x7FFE, ~roundMask); - } - set_float_rounding_up(status); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (zExp <= 0) { - int isTiny = (zExp < 0) || (! increment) - || (zSig0 < BX_CONST64(0xFFFFFFFFFFFFFFFF)); - shift64ExtraRightJamming(zSig0, zSig1, 1 - zExp, &zSig0, &zSig1); - zExp = 0; - if (isTiny) { - if (zSig1 || (zSig0 && !float_exception_masked(status, float_flag_underflow))) - float_raise(status, float_flag_underflow); - } - if (zSig1) float_raise(status, float_flag_inexact); - if (roundNearestEven) increment = ((Bit64s) zSig1 < 0); - else { - if (zSign) { - increment = (roundingMode == float_round_down) && zSig1; - } else { - increment = (roundingMode == float_round_up) && zSig1; - } - } - if (increment) { - zSigExact = zSig0++; - zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven); - if (zSig0 > zSigExact) set_float_rounding_up(status); - if ((Bit64s) zSig0 < 0) zExp = 1; - } - return packFloatx80(zSign, zExp, zSig0); - } - } - if (zSig1) float_raise(status, float_flag_inexact); - if (increment) { - zSigExact = zSig0++; - if (zSig0 == 0) { - zExp++; - zSig0 = BX_CONST64(0x8000000000000000); - zSigExact >>= 1; // must scale also, or else later tests will fail - } - else { - zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven); - } - if (zSig0 > zSigExact) set_float_rounding_up(status); - } - else { - if (zSig0 == 0) zExp = 0; - } - return packFloatx80(zSign, zExp, zSig0); -} - -floatx80 roundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status) -{ - struct float_status_t *round_status = status; - floatx80 result = SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status); - - // bias unmasked undeflow - if (status->float_exception_flags & ~status->float_exception_masks & float_flag_underflow) { - float_raise(round_status, float_flag_underflow); - return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp + 0x6000, zSig0, zSig1, status = round_status); - } - - // bias unmasked overflow - if (status->float_exception_flags & ~status->float_exception_masks & float_flag_overflow) { - float_raise(round_status, float_flag_overflow); - return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp - 0x6000, zSig0, zSig1, status = round_status); - } - - return result; -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent -| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1', -| and returns the proper extended double-precision floating-point value -| corresponding to the abstract input. This routine is just like -| `roundAndPackFloatx80' except that the input significand does not have to be -| normalized. -*----------------------------------------------------------------------------*/ - -floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status) -{ - if (zSig0 == 0) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - int shiftCount = countLeadingZeros64(zSig0); - shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1); - zExp -= shiftCount; - return - roundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status); -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*----------------------------------------------------------------------------*/ - -void normalizeFloat128Subnormal( - Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr) -{ - int shiftCount; - - if (aSig0 == 0) { - shiftCount = countLeadingZeros64(aSig1) - 15; - if (shiftCount < 0) { - *zSig0Ptr = aSig1 >>(-shiftCount); - *zSig1Ptr = aSig1 << (shiftCount & 63); - } - else { - *zSig0Ptr = aSig1 << shiftCount; - *zSig1Ptr = 0; - } - *zExpPtr = - shiftCount - 63; - } - else { - shiftCount = countLeadingZeros64(aSig0) - 15; - shortShift128Left(aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr); - *zExpPtr = 1 - shiftCount; - } -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and extended significand formed by the concatenation of `zSig0', `zSig1', -| and `zSig2', and returns the proper quadruple-precision floating-point value -| corresponding to the abstract input. Ordinarily, the abstract value is -| simply rounded and packed into the quadruple-precision format, with the -| inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal quadruple- -| precision floating-point number. -| The input significand must be normalized or smaller. If the input -| significand is not normalized, `zExp' must be 0; in that case, the result -| returned is a subnormal number, and it must not require rounding. In the -| usual case that the input significand is normalized, `zExp' must be 1 less -| than the ``true'' floating-point exponent. The handling of underflow and -| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 roundAndPackFloat128( - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status) -{ - int increment = ((Bit64s) zSig2 < 0); - if (0x7FFD <= (Bit32u) zExp) { - if ((0x7FFD < zExp) - || ((zExp == 0x7FFD) - && eq128(BX_CONST64(0x0001FFFFFFFFFFFF), - BX_CONST64(0xFFFFFFFFFFFFFFFF), zSig0, zSig1) - && increment)) - { - float_raise(status, float_flag_overflow | float_flag_inexact); - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - if (zExp < 0) { - int isTiny = (zExp < -1) - || ! increment - || lt128(zSig0, zSig1, - BX_CONST64(0x0001FFFFFFFFFFFF), - BX_CONST64(0xFFFFFFFFFFFFFFFF)); - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, -zExp, &zSig0, &zSig1, &zSig2); - zExp = 0; - if (isTiny && zSig2) float_raise(status, float_flag_underflow); - increment = ((Bit64s) zSig2 < 0); - } - } - if (zSig2) float_raise(status, float_flag_inexact); - if (increment) { - add128(zSig0, zSig1, 0, 1, &zSig0, &zSig1); - zSig1 &= ~((zSig2 + zSig2 == 0) & 1); - } - else { - if ((zSig0 | zSig1) == 0) zExp = 0; - } - return packFloat128Four(zSign, zExp, zSig0, zSig1); -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand formed by the concatenation of `zSig0' and `zSig1', and -| returns the proper quadruple-precision floating-point value corresponding -| to the abstract input. This routine is just like `roundAndPackFloat128' -| except that the input significand has fewer bits and does not have to be -| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- -| point exponent. -*----------------------------------------------------------------------------*/ - -float128 normalizeRoundAndPackFloat128( - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status) -{ - Bit64u zSig2; - - if (zSig0 == 0) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - int shiftCount = countLeadingZeros64(zSig0) - 15; - if (0 <= shiftCount) { - zSig2 = 0; - shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, -shiftCount, &zSig0, &zSig1, &zSig2); - } - zExp -= shiftCount; - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); -} - -#endif diff --git a/src/cpu/softfloat/softfloat-round-pack.h b/src/cpu/softfloat/softfloat-round-pack.h deleted file mode 100644 index 1422aaea6..000000000 --- a/src/cpu/softfloat/softfloat-round-pack.h +++ /dev/null @@ -1,309 +0,0 @@ -/*============================================================================ -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#ifndef _SOFTFLOAT_ROUND_PACK_H_ -#define _SOFTFLOAT_ROUND_PACK_H_ - -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the integer -| indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s roundAndPackInt32(int zSign, Bit64u absZ, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit unsigned integer corresponding to the -| input. Ordinarily, the fixed-point input is simply rounded to an integer, -| with the inexact exception raised if the input cannot be represented exactly -| as an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status); - -#ifdef FLOAT16 - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal half-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper half-precision floating- -| point value corresponding to the abstract input. Ordinarily, the abstract -| value is simply rounded and packed into the half-precision format, with -| the inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal single- -| precision floating-point number. -| The input significand `zSig' has its binary point between bits 14 -| and 13, which is 4 bits to the left of the usual location. This shifted -| significand must be normalized or smaller. If `zSig' is not normalized, -| `zExp' must be 0; in that case, the result returned is a subnormal number, -| and it must not require rounding. In the usual case that `zSig' is -| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. -| The handling of underflow and overflow follows the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float16 roundAndPackFloat16(int zSign, Bit16s zExp, Bit16u zSig, struct float_status_t *status); - -#endif - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. Ordinarily, the abstract -| value is simply rounded and packed into the single-precision format, with -| the inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal single- -| precision floating-point number. -| The input significand `zSig' has its binary point between bits 30 -| and 29, which is 7 bits to the left of the usual location. This shifted -| significand must be normalized or smaller. If `zSig' is not normalized, -| `zExp' must be 0; in that case, the result returned is a subnormal number, -| and it must not require rounding. In the usual case that `zSig' is -| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. -| The handling of underflow and overflow follows the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 roundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal double-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloat64Subnormal(Bit64u aSig, Bit16s *zExpPtr, Bit64u *zSigPtr); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. Ordinarily, the abstract -| value is simply rounded and packed into the double-precision format, with -| the inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded -| to a subnormal number, and the underflow and inexact exceptions are raised -| if the abstract input cannot be represented exactly as a subnormal double- -| precision floating-point number. -| The input significand `zSig' has its binary point between bits 62 -| and 61, which is 10 bits to the left of the usual location. This shifted -| significand must be normalized or smaller. If `zSig' is not normalized, -| `zExp' must be 0; in that case, the result returned is a subnormal number, -| and it must not require rounding. In the usual case that `zSig' is -| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. -| The handling of underflow and overflow follows the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 roundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status); - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal extended double-precision floating-point value -| represented by the denormalized significand `aSig'. The normalized exponent -| and significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloatx80Subnormal(Bit64u aSig, Bit32s *zExpPtr, Bit64u *zSigPtr); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and extended significand formed by the concatenation of `zSig0' and `zSig1', -| and returns the proper extended double-precision floating-point value -| corresponding to the abstract input. Ordinarily, the abstract value is -| rounded and packed into the extended double-precision format, with the -| inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal extended -| double-precision floating-point number. -| If `roundingPrecision' is 32 or 64, the result is rounded to the same -| number of bits as single or double precision, respectively. Otherwise, the -| result is rounded to the full precision of the extended double-precision -| format. -| The input significand must be normalized or smaller. If the input -| significand is not normalized, `zExp' must be 0; in that case, the result -| returned is a subnormal number, and it must not require rounding. The -| handling of underflow and overflow follows the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 roundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent -| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1', -| and returns the proper extended double-precision floating-point value -| corresponding to the abstract input. This routine is just like -| `roundAndPackFloatx80' except that the input significand does not have to be -| normalized. -*----------------------------------------------------------------------------*/ - -floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status); - -#endif // FLOATX80 - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*----------------------------------------------------------------------------*/ - -void normalizeFloat128Subnormal( - Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and extended significand formed by the concatenation of `zSig0', `zSig1', -| and `zSig2', and returns the proper quadruple-precision floating-point value -| corresponding to the abstract input. Ordinarily, the abstract value is -| simply rounded and packed into the quadruple-precision format, with the -| inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal quadruple- -| precision floating-point number. -| The input significand must be normalized or smaller. If the input -| significand is not normalized, `zExp' must be 0; in that case, the result -| returned is a subnormal number, and it must not require rounding. In the -| usual case that the input significand is normalized, `zExp' must be 1 less -| than the ``true'' floating-point exponent. The handling of underflow and -| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 roundAndPackFloat128( - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand formed by the concatenation of `zSig0' and `zSig1', and -| returns the proper quadruple-precision floating-point value corresponding -| to the abstract input. This routine is just like `roundAndPackFloat128' -| except that the input significand has fewer bits and does not have to be -| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- -| point exponent. -*----------------------------------------------------------------------------*/ - -float128 normalizeRoundAndPackFloat128( - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status); - -#endif // FLOAT128 - -#endif diff --git a/src/cpu/softfloat/softfloat-specialize.cc b/src/cpu/softfloat/softfloat-specialize.cc deleted file mode 100644 index bf0d11144..000000000 --- a/src/cpu/softfloat/softfloat-specialize.cc +++ /dev/null @@ -1,187 +0,0 @@ -/*============================================================================ -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -#define FLOAT128 - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "softfloat.h" -#include "softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status) -{ - int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float32_is_nan(a); - aIsSignalingNaN = float32_is_signaling_nan(a); - bIsNaN = float32_is_nan(b); - bIsSignalingNaN = float32_is_signaling_nan(b); - a |= 0x00400000; - b |= 0x00400000; - if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid); - if (get_float_nan_handling_mode(status) == float_larger_significand_nan) { - if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN | ! bIsNaN) return a; - returnLargerSignificand: - if ((Bit32u) (a<<1) < (Bit32u) (b<<1)) return b; - if ((Bit32u) (b<<1) < (Bit32u) (a<<1)) return a; - return (a < b) ? a : b; - } - else { - return b; - } - } else { - return (aIsSignalingNaN | aIsNaN) ? a : b; - } -} - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status) -{ - int aIsNaN = float64_is_nan(a); - int aIsSignalingNaN = float64_is_signaling_nan(a); - int bIsNaN = float64_is_nan(b); - int bIsSignalingNaN = float64_is_signaling_nan(b); - a |= BX_CONST64(0x0008000000000000); - b |= BX_CONST64(0x0008000000000000); - if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid); - if (get_float_nan_handling_mode(status) == float_larger_significand_nan) { - if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN | ! bIsNaN) return a; - returnLargerSignificand: - if ((Bit64u) (a<<1) < (Bit64u) (b<<1)) return b; - if ((Bit64u) (b<<1) < (Bit64u) (a<<1)) return a; - return (a < b) ? a : b; - } - else { - return b; - } - } else { - return (aIsSignalingNaN | aIsNaN) ? a : b; - } -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Takes two extended double-precision floating-point values `a' and `b', one -| of which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status) -{ - int aIsNaN = floatx80_is_nan(a); - int aIsSignalingNaN = floatx80_is_signaling_nan(a); - int bIsNaN = floatx80_is_nan(b); - int bIsSignalingNaN = floatx80_is_signaling_nan(b); - a.fraction |= BX_CONST64(0xC000000000000000); - b.fraction |= BX_CONST64(0xC000000000000000); - if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid); - if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN | ! bIsNaN) return a; - returnLargerSignificand: - if (a.fraction < b.fraction) return b; - if (b.fraction < a.fraction) return a; - return (a.exp < b.exp) ? a : b; - } - else { - return b; - } -} - -#endif /* FLOATX80 */ - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status) -{ - int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - aIsNaN = float128_is_nan(a); - aIsSignalingNaN = float128_is_signaling_nan(a); - bIsNaN = float128_is_nan(b); - bIsSignalingNaN = float128_is_signaling_nan(b); - a.hi |= BX_CONST64(0x0000800000000000); - b.hi |= BX_CONST64(0x0000800000000000); - if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid); - if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN | !bIsNaN) return a; - returnLargerSignificand: - if (lt128(a.hi<<1, a.lo, b.hi<<1, b.lo)) return b; - if (lt128(b.hi<<1, b.lo, a.hi<<1, a.lo)) return a; - return (a.hi < b.hi) ? a : b; - } - else { - return b; - } -} - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. -*----------------------------------------------------------------------------*/ -const float128 float128_default_nan = - packFloat128(float128_default_nan_hi, float128_default_nan_lo); - -#endif /* FLOAT128 */ diff --git a/src/cpu/softfloat/softfloat-specialize.h b/src/cpu/softfloat/softfloat-specialize.h deleted file mode 100644 index 302ce53e4..000000000 --- a/src/cpu/softfloat/softfloat-specialize.h +++ /dev/null @@ -1,789 +0,0 @@ -/*============================================================================ -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -#ifndef _SOFTFLOAT_SPECIALIZE_H_ -#define _SOFTFLOAT_SPECIALIZE_H_ - -#include "softfloat.h" - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#define int16_indefinite ((Bit16s)0x8000) -#define int32_indefinite ((Bit32s)0x80000000) -#define int64_indefinite BX_CONST64(0x8000000000000000) - -#define uint16_indefinite (0xffff) -#define uint32_indefinite (0xffffffff) -#define uint64_indefinite BX_CONST64(0xffffffffffffffff) - -/*---------------------------------------------------------------------------- -| Internal canonical NaN format. -*----------------------------------------------------------------------------*/ - -typedef struct { - int sign; - Bit64u hi, lo; -} commonNaNT; - -#ifdef FLOAT16 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated half-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float16 float16_default_nan; - -#define float16_fraction extractFloat16Frac -#define float16_exp extractFloat16Exp -#define float16_sign extractFloat16Sign - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the half-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit16u extractFloat16Frac(float16 a) -{ - return a & 0x3FF; -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the half-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit16s extractFloat16Exp(float16 a) -{ - return (a>>10) & 0x1F; -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the half-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int extractFloat16Sign(float16 a) -{ - return a>>15; -} - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a -| single-precision floating-point value, returning the result. After being -| shifted into the proper positions, the three fields are simply added -| together to form the result. This means that any integer portion of `zSig' -| will be added into the exponent. Since a properly normalized significand -| will have an integer portion equal to 1, the `zExp' input should be 1 less -| than the desired result exponent whenever `zSig' is a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float16 packFloat16(int zSign, int zExp, Bit16u zSig) -{ - return (((Bit16u) zSign)<<15) + (((Bit16u) zExp)<<10) + zSig; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the half-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float16_is_nan(float16 a) -{ - return (0xF800 < (Bit16u) (a<<1)); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the half-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float16_is_signaling_nan(float16 a) -{ - return (((a>>9) & 0x3F) == 0x3E) && (a & 0x1FF); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the half-precision floating-point value `a' is denormal; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float16_is_denormal(float16 a) -{ - return (extractFloat16Exp(a) == 0) && (extractFloat16Frac(a) != 0); -} - -/*---------------------------------------------------------------------------- -| Convert float16 denormals to zero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float16 float16_denormal_to_zero(float16 a) -{ - if (float16_is_denormal(a)) a &= 0x8000; - return a; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the half-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE commonNaNT float16ToCommonNaN(float16 a, struct float_status_t *status) -{ - commonNaNT z; - if (float16_is_signaling_nan(a)) float_raise(status, float_flag_invalid); - z.sign = a>>15; - z.lo = 0; - z.hi = ((Bit64u) a)<<54; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the half- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float16 commonNaNToFloat16(commonNaNT a) -{ - return (((Bit16u) a.sign)<<15) | 0x7E00 | (Bit16u)(a.hi>>54); -} - -#endif - -/*---------------------------------------------------------------------------- -| Commonly used single-precision floating point constants -*----------------------------------------------------------------------------*/ -extern const float32 float32_negative_inf; -extern const float32 float32_positive_inf; -extern const float32 float32_negative_zero; -extern const float32 float32_positive_zero; -extern const float32 float32_negative_one; -extern const float32 float32_positive_one; -extern const float32 float32_max_float; -extern const float32 float32_min_float; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float32 float32_default_nan; - -#define float32_fraction extractFloat32Frac -#define float32_exp extractFloat32Exp -#define float32_sign extractFloat32Sign - -#define FLOAT32_EXP_BIAS 0x7F - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit32u extractFloat32Frac(float32 a) -{ - return a & 0x007FFFFF; -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit16s extractFloat32Exp(float32 a) -{ - return (a>>23) & 0xFF; -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int extractFloat32Sign(float32 a) -{ - return a>>31; -} - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a -| single-precision floating-point value, returning the result. After being -| shifted into the proper positions, the three fields are simply added -| together to form the result. This means that any integer portion of `zSig' -| will be added into the exponent. Since a properly normalized significand -| will have an integer portion equal to 1, the `zExp' input should be 1 less -| than the desired result exponent whenever `zSig' is a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float32 packFloat32(int zSign, Bit16s zExp, Bit32u zSig) -{ - return (((Bit32u) zSign)<<31) + (((Bit32u) zExp)<<23) + zSig; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float32_is_nan(float32 a) -{ - return (0xFF000000 < (Bit32u) (a<<1)); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float32_is_signaling_nan(float32 a) -{ - return (((a>>22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is denormal; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float32_is_denormal(float32 a) -{ - return (extractFloat32Exp(a) == 0) && (extractFloat32Frac(a) != 0); -} - -/*---------------------------------------------------------------------------- -| Convert float32 denormals to zero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float32 float32_denormal_to_zero(float32 a) -{ - if (float32_is_denormal(a)) a &= 0x80000000; - return a; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE commonNaNT float32ToCommonNaN(float32 a, struct float_status_t *status) -{ - commonNaNT z; - if (float32_is_signaling_nan(a)) float_raise(status, float_flag_invalid); - z.sign = a>>31; - z.lo = 0; - z.hi = ((Bit64u) a)<<41; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float32 commonNaNToFloat32(commonNaNT a) -{ - return (((Bit32u) a.sign)<<31) | 0x7FC00000 | (Bit32u)(a.hi>>41); -} - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes single-precision floating-point NaN `a' and returns the appropriate -| NaN result. If `a' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float32 propagateFloat32NaNOne(float32 a, struct float_status_t *status) -{ - if (float32_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - return a | 0x00400000; -} - -/*---------------------------------------------------------------------------- -| Commonly used single-precision floating point constants -*----------------------------------------------------------------------------*/ -extern const float64 float64_negative_inf; -extern const float64 float64_positive_inf; -extern const float64 float64_negative_zero; -extern const float64 float64_positive_zero; -extern const float64 float64_negative_one; -extern const float64 float64_positive_one; -extern const float64 float64_max_float; -extern const float64 float64_min_float; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float64 float64_default_nan; - -#define float64_fraction extractFloat64Frac -#define float64_exp extractFloat64Exp -#define float64_sign extractFloat64Sign - -#define FLOAT64_EXP_BIAS 0x3FF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit64u extractFloat64Frac(float64 a) -{ - return a & BX_CONST64(0x000FFFFFFFFFFFFF); -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit16s extractFloat64Exp(float64 a) -{ - return (Bit16s)(a>>52) & 0x7FF; -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int extractFloat64Sign(float64 a) -{ - return (int)(a>>63); -} - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a -| double-precision floating-point value, returning the result. After being -| shifted into the proper positions, the three fields are simply added -| together to form the result. This means that any integer portion of `zSig' -| will be added into the exponent. Since a properly normalized significand -| will have an integer portion equal to 1, the `zExp' input should be 1 less -| than the desired result exponent whenever `zSig' is a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float64 packFloat64(int zSign, Bit16s zExp, Bit64u zSig) -{ - return (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<52) + zSig; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float64_is_nan(float64 a) -{ - return (BX_CONST64(0xFFE0000000000000) < (Bit64u) (a<<1)); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float64_is_signaling_nan(float64 a) -{ - return (((a>>51) & 0xFFF) == 0xFFE) && (a & BX_CONST64(0x0007FFFFFFFFFFFF)); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is denormal; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float64_is_denormal(float64 a) -{ - return (extractFloat64Exp(a) == 0) && (extractFloat64Frac(a) != 0); -} - -/*---------------------------------------------------------------------------- -| Convert float64 denormals to zero. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float64 float64_denormal_to_zero(float64 a) -{ - if (float64_is_denormal(a)) a &= ((Bit64u)(1) << 63); - return a; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE commonNaNT float64ToCommonNaN(float64 a, struct float_status_t *status) -{ - commonNaNT z; - if (float64_is_signaling_nan(a)) float_raise(status, float_flag_invalid); - z.sign = (int)(a>>63); - z.lo = 0; - z.hi = a<<12; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float64 commonNaNToFloat64(commonNaNT a) -{ - return (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FF8000000000000) | (a.hi>>12); -} - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes double-precision floating-point NaN `a' and returns the appropriate -| NaN result. If `a' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float64 propagateFloat64NaNOne(float64 a, struct float_status_t *status) -{ - if (float64_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - return a | BX_CONST64(0x0008000000000000); -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. The -| `high' and `low' values hold the most- and least-significant bits, -| respectively. -*----------------------------------------------------------------------------*/ -#define floatx80_default_nan_exp 0xFFFF -#define floatx80_default_nan_fraction BX_CONST64(0xC000000000000000) - -#define floatx80_fraction extractFloatx80Frac -#define floatx80_exp extractFloatx80Exp -#define floatx80_sign extractFloatx80Sign - -#define FLOATX80_EXP_BIAS 0x3FFF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit64u extractFloatx80Frac(floatx80 a) -{ - return a.fraction; -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit32s extractFloatx80Exp(floatx80 a) -{ - return a.exp & 0x7FFF; -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the extended double-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int extractFloatx80Sign(floatx80 a) -{ - return a.exp>>15; -} - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an -| extended double-precision floating-point value, returning the result. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE floatx80 packFloatx80(int zSign, Bit32s zExp, Bit64u zSig) -{ - floatx80 z; - z.fraction = zSig; - z.exp = (zSign << 15) + zExp; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int floatx80_is_nan(floatx80 a) -{ - // return ((a.exp & 0x7FFF) == 0x7FFF) && (Bit64s) (a.fraction<<1); - return ((a.exp & 0x7FFF) == 0x7FFF) && (((Bit64s) (a.fraction<<1)) != 0); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int floatx80_is_signaling_nan(floatx80 a) -{ - Bit64u aLow = a.fraction & ~BX_CONST64(0x4000000000000000); - return ((a.exp & 0x7FFF) == 0x7FFF) && - ((Bit64u) (aLow<<1)) && (a.fraction == aLow); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is an -| unsupported; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int floatx80_is_unsupported(floatx80 a) -{ - return ((a.exp & 0x7FFF) && !(a.fraction & BX_CONST64(0x8000000000000000))); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE commonNaNT floatx80ToCommonNaN(floatx80 a, struct float_status_t *status) -{ - commonNaNT z; - if (floatx80_is_signaling_nan(a)) float_raise(status, float_flag_invalid); - z.sign = a.exp >> 15; - z.lo = 0; - z.hi = a.fraction << 1; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the extended -| double-precision floating-point format. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE floatx80 commonNaNToFloatx80(commonNaNT a) -{ - floatx80 z; - z.fraction = BX_CONST64(0xC000000000000000) | (a.hi>>1); - z.exp = (((Bit16u) a.sign)<<15) | 0x7FFF; - return z; -} - -/*---------------------------------------------------------------------------- -| Takes two extended double-precision floating-point values `a' and `b', one -| of which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Takes extended double-precision floating-point NaN `a' and returns the -| appropriate NaN result. If `a' is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE floatx80 propagateFloatx80NaNOne(floatx80 a, struct float_status_t *status) -{ - if (floatx80_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - a.fraction |= BX_CONST64(0xC000000000000000); - - return a; -} - -#endif /* FLOATX80 */ - -#ifdef FLOAT128 - -#include "softfloat-macros.h" - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. -*----------------------------------------------------------------------------*/ -#define float128_default_nan_hi BX_CONST64(0xFFFF800000000000) -#define float128_default_nan_lo BX_CONST64(0x0000000000000000) - -#define float128_exp extractFloat128Exp - -/*---------------------------------------------------------------------------- -| Returns the least-significant 64 fraction bits of the quadruple-precision -| floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit64u extractFloat128Frac1(float128 a) -{ - return a.lo; -} - -/*---------------------------------------------------------------------------- -| Returns the most-significant 48 fraction bits of the quadruple-precision -| floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit64u extractFloat128Frac0(float128 a) -{ - return a.hi & BX_CONST64(0x0000FFFFFFFFFFFF); -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the quadruple-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE Bit32s extractFloat128Exp(float128 a) -{ - return ((Bit32s)(a.hi>>48)) & 0x7FFF; -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the quadruple-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int extractFloat128Sign(float128 a) -{ - return (int)(a.hi >> 63); -} - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', the exponent `zExp', and the significand formed -| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision -| floating-point value, returning the result. After being shifted into the -| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply -| added together to form the most significant 32 bits of the result. This -| means that any integer portion of `zSig0' will be added into the exponent. -| Since a properly normalized significand will have an integer portion equal -| to 1, the `zExp' input should be 1 less than the desired result exponent -| whenever `zSig0' and `zSig1' concatenated form a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float128 packFloat128Four(int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1) -{ - float128 z; - z.lo = zSig1; - z.hi = (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<48) + zSig0; - return z; -} - -/*---------------------------------------------------------------------------- -| Packs two 64-bit precision integers into into the quadruple-precision -| floating-point value, returning the result. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float128 packFloat128(Bit64u zHi, Bit64u zLo) -{ - float128 z; - z.lo = zLo; - z.hi = zHi; - return z; -} - -#ifdef _MSC_VER -#define PACK_FLOAT_128(hi,lo) { lo, hi } -#else -#define PACK_FLOAT_128(hi,lo) packFloat128(BX_CONST64(hi),BX_CONST64(lo)) -#endif - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float128_is_nan(float128 a) -{ - return (BX_CONST64(0xFFFE000000000000) <= (Bit64u) (a.hi<<1)) - && (a.lo || (a.hi & BX_CONST64(0x0000FFFFFFFFFFFF))); -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float128_is_signaling_nan(float128 a) -{ - return (((a.hi>>47) & 0xFFFF) == 0xFFFE) - && (a.lo || (a.hi & BX_CONST64(0x00007FFFFFFFFFFF))); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE commonNaNT float128ToCommonNaN(float128 a, struct float_status_t *status) -{ - commonNaNT z; - if (float128_is_signaling_nan(a)) float_raise(status, float_flag_invalid); - z.sign = (int)(a.hi>>63); - shortShift128Left(a.hi, a.lo, 16, &z.hi, &z.lo); - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the quadruple- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float128 commonNaNToFloat128(commonNaNT a) -{ - float128 z; - shift128Right(a.hi, a.lo, 16, &z.hi, &z.lo); - z.hi |= (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FFF800000000000); - return z; -} - -/*---------------------------------------------------------------------------- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float128 float128_default_nan; - -#endif /* FLOAT128 */ - -#endif diff --git a/src/cpu/softfloat/softfloat.cc b/src/cpu/softfloat/softfloat.cc deleted file mode 100644 index 0802089b9..000000000 --- a/src/cpu/softfloat/softfloat.cc +++ /dev/null @@ -1,4012 +0,0 @@ -/*============================================================================ -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -#define FLOAT128 - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "softfloat.h" -#include "softfloat-round-pack.h" - -/*---------------------------------------------------------------------------- -| Primitive arithmetic functions, including multi-word arithmetic, and -| division and square root approximations. (Can be specialized to target -| if desired). -*----------------------------------------------------------------------------*/ -#define USE_estimateDiv128To64 -#define USE_estimateSqrt32 -#include "softfloat-macros.h" - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -const unsigned float_all_exceptions_mask = 0x3f; - -float32 int32_to_float32(Bit32s a, struct float_status_t *status) -{ - if (a == 0) return 0; - if (a == (Bit32s) 0x80000000) return packFloat32(1, 0x9E, 0); - int zSign = (a < 0); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 int32_to_float64(Bit32s a) -{ - if (a == 0) return 0; - int zSign = (a < 0); - Bit32u absA = zSign ? -a : a; - int shiftCount = countLeadingZeros32(absA) + 21; - Bit64u zSig = absA; - return packFloat64(zSign, 0x432 - shiftCount, zSig<> 1, status); - return normalizeRoundAndPackFloat32(0, 0x9C, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit unsigned integer `a' to the -| double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 uint32_to_float64(Bit32u a) -{ - if (a == 0) return 0; - int shiftCount = countLeadingZeros32(a) + 21; - Bit64u zSig = a; - return packFloat64(0, 0x432 - shiftCount, zSig<> 1, status); - return normalizeRoundAndPackFloat64(0, 0x43C, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic - which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the -| conversion overflows the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s float32_to_int32(float32 a, struct float_status_t *status) -{ - Bit32u aSig = extractFloat32Frac(a); - Bit16s aExp = extractFloat32Exp(a); - int aSign = extractFloat32Sign(a); - if ((aExp == 0xFF) && aSig) aSign = 0; - if (aExp) aSig |= 0x00800000; - else { - if (get_denormals_are_zeros(status)) aSig = 0; - } - int shiftCount = 0xAF - aExp; - Bit64u aSig64 = Bit64u(aSig) << 32; - if (0 < shiftCount) aSig64 = shift64RightJamming(aSig64, shiftCount); - return roundAndPackInt32(aSign, aSig64, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN or the conversion overflows, the integer indefinite -| value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s float32_to_int32_round_to_zero(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit32u aSig; - Bit32s z; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - int shiftCount = aExp - 0x9E; - if (0 <= shiftCount) { - if (a != 0xCF000000) { - float_raise(status, float_flag_invalid); - } - return (Bit32s)(int32_indefinite); - } - else if (aExp <= 0x7E) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp | aSig) float_raise(status, float_flag_inexact); - return 0; - } - aSig = (aSig | 0x800000)<<8; - z = aSig>>(-shiftCount); - if ((Bit32u) (aSig<<(shiftCount & 31))) { - float_raise(status, float_flag_inexact); - } - if (aSign) z = -z; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit unsigned integer format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-point Arithmetic, -| except that the conversion is always rounded toward zero. If `a' is a NaN -| or conversion overflows, the largest positive integer is returned. -*----------------------------------------------------------------------------*/ - -Bit32u float32_to_uint32_round_to_zero(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit32u aSig; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - int shiftCount = aExp - 0x9E; - - if (aExp <= 0x7E) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp | aSig) float_raise(status, float_flag_inexact); - return 0; - } - else if (0 < shiftCount || aSign) { - float_raise(status, float_flag_invalid); - return uint32_indefinite; - } - - aSig = (aSig | 0x800000)<<8; - Bit32u z = aSig >> (-shiftCount); - if (aSig << (shiftCount & 31)) { - float_raise(status, float_flag_inexact); - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic - which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the -| conversion overflows, the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit64s float32_to_int64(float32 a, struct float_status_t *status) -{ - Bit64u aSig64, aSigExtra; - - Bit32u aSig = extractFloat32Frac(a); - Bit16s aExp = extractFloat32Exp(a); - int aSign = extractFloat32Sign(a); - - int shiftCount = 0xBE - aExp; - if (shiftCount < 0) { - float_raise(status, float_flag_invalid); - return (Bit64s)(int64_indefinite); - } - if (aExp) aSig |= 0x00800000; - else { - if (get_denormals_are_zeros(status)) aSig = 0; - } - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN or the conversion overflows, the integer indefinite -| value is returned. -*----------------------------------------------------------------------------*/ - -Bit64s float32_to_int64_round_to_zero(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit32u aSig; - Bit64u aSig64; - Bit64s z; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - int shiftCount = aExp - 0xBE; - if (0 <= shiftCount) { - if (a != 0xDF000000) { - float_raise(status, float_flag_invalid); - } - return (Bit64s)(int64_indefinite); - } - else if (aExp <= 0x7E) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp | aSig) float_raise(status, float_flag_inexact); - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>(-shiftCount); - if ((Bit64u) (aSig64<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - if (aSign) z = -z; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic, -| except that the conversion is always rounded toward zero. If `a' is a NaN -| or the conversion overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u float32_to_uint64_round_to_zero(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit32u aSig; - Bit64u aSig64; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - int shiftCount = aExp - 0xBE; - - if (aExp <= 0x7E) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp | aSig) float_raise(status, float_flag_inexact); - return 0; - } - else if (0 < shiftCount || aSign) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - Bit64u z = aSig64>>(-shiftCount); - if ((Bit64u) (aSig64<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the conversion -| overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u float32_to_uint64(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp, shiftCount; - Bit32u aSig; - Bit64u aSig64, aSigExtra; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - } - - if ((aSign) && (aExp > 0x7E)) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - shiftCount = 0xBE - aExp; - if (aExp) aSig |= 0x00800000; - - if (shiftCount < 0) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the conversion -| overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit32u float32_to_uint32(float32 a, struct float_status_t *status) -{ - Bit64u val_64 = float32_to_uint64(a, status); - - if (val_64 > 0xffffffff) { - status->float_exception_flags = float_flag_invalid; // throw away other flags - return uint32_indefinite; - } - - return (Bit32u) val_64; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float32_to_float64(float32 a, struct float_status_t *status) -{ - Bit32u aSig = extractFloat32Frac(a); - Bit16s aExp = extractFloat32Exp(a); - int aSign = extractFloat32Sign(a); - - if (aExp == 0xFF) { - if (aSig) return commonNaNToFloat64(float32ToCommonNaN(a, status)); - return packFloat64(aSign, 0x7FF, 0); - } - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return packFloat64(aSign, 0, 0); - - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - --aExp; - } - return packFloat64(aSign, aExp + 0x380, ((Bit64u) aSig)<<29); -} - -/*---------------------------------------------------------------------------- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_round_to_int(float32 a, Bit8u scale, struct float_status_t *status) -{ - Bit32u lastBitMask, roundBitsMask; - int roundingMode = get_float_rounding_mode(status); - Bit16s aExp = extractFloat32Exp(a); - scale &= 0xf; - - if ((aExp == 0xFF) && extractFloat32Frac(a)) { - return propagateFloat32NaNOne(a, status); - } - - aExp += scale; // scale the exponent - - if (0x96 <= aExp) { - return a; - } - - if (get_denormals_are_zeros(status)) { - a = float32_denormal_to_zero(a); - } - - if (aExp <= 0x7E) { - if ((Bit32u) (a<<1) == 0) return a; - float_raise(status, float_flag_inexact); - int aSign = extractFloat32Sign(a); - switch (roundingMode) { - case float_round_nearest_even: - if ((aExp == 0x7E) && extractFloat32Frac(a)) { - return packFloat32(aSign, 0x7F - scale, 0); - } - break; - case float_round_down: - return aSign ? packFloat32(1, 0x7F - scale, 0) : float32_positive_zero; - case float_round_up: - return aSign ? float32_negative_zero : packFloat32(0, 0x7F - scale, 0); - } - return packFloat32(aSign, 0, 0); - } - - lastBitMask = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - float32 z = a; - if (roundingMode == float_round_nearest_even) { - z += lastBitMask>>1; - if ((z & roundBitsMask) == 0) z &= ~lastBitMask; - } - else if (roundingMode != float_round_to_zero) { - if (extractFloat32Sign(z) ^ (roundingMode == float_round_up)) { - z += roundBitsMask; - } - } - z &= ~roundBitsMask; - if (z != a) float_raise(status, float_flag_inexact); - return z; -} - -/*---------------------------------------------------------------------------- -| Extracts the fractional portion of single-precision floating-point value `a', -| and returns the result as a single-precision floating-point value. The -| fractional results are precise. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_frc(float32 a, struct float_status_t *status) -{ - int roundingMode = get_float_rounding_mode(status); - - Bit16s aExp = extractFloat32Exp(a); - Bit32u aSig = extractFloat32Frac(a); - int aSign = extractFloat32Sign(a); - - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaNOne(a, status); - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - - if (aExp >= 0x96) { - return packFloat32(roundingMode == float_round_down, 0, 0); - } - - if (aExp < 0x7F) { - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return packFloat32(roundingMode == float_round_down, 0, 0); - - float_raise(status, float_flag_denormal); - if (! float_exception_masked(status, float_flag_underflow)) - float_raise(status, float_flag_underflow); - - if(get_flush_underflow_to_zero(status)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat32(aSign, 0, 0); - } - } - return a; - } - - Bit32u lastBitMask = 1 << (0x96 - aExp); - Bit32u roundBitsMask = lastBitMask - 1; - - aSig &= roundBitsMask; - aSig <<= 7; - aExp--; - - if (aSig == 0) - return packFloat32(roundingMode == float_round_down, 0, 0); - - return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status); -} - -/*---------------------------------------------------------------------------- -| Extracts the exponent portion of single-precision floating-point value 'a', -| and returns the result as a single-precision floating-point value -| representing unbiased integer exponent. The operation is performed according -| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_getexp(float32 a, struct float_status_t *status) -{ - Bit16s aExp = extractFloat32Exp(a); - Bit32u aSig = extractFloat32Frac(a); - - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaNOne(a, status); - return float32_positive_inf; - } - - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return float32_negative_inf; - - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - - return int32_to_float32(aExp - 0x7F, status); -} - -/*---------------------------------------------------------------------------- -| Extracts the mantissa of single-precision floating-point value 'a' and -| returns the result as a single-precision floating-point after applying -| the mantissa interval normalization and sign control. The operation is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv) -{ - Bit16s aExp = extractFloat32Exp(a); - Bit32u aSig = extractFloat32Frac(a); - int aSign = extractFloat32Sign(a); - - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaNOne(a, status); - if (aSign) { - if (sign_ctrl & 0x2) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - } - return packFloat32(~sign_ctrl & aSign, 0x7F, 0); - } - - if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) { - return packFloat32(~sign_ctrl & aSign, 0x7F, 0); - } - - if (aSign) { - if (sign_ctrl & 0x2) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - } - - if (aExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); -// aExp += 0x7E; - aSig &= 0x7FFFFF; - } - - switch(interv) { - case 0x0: // interval [1,2) - aExp = 0x7F; - break; - case 0x1: // interval [1/2,2) - aExp -= 0x7F; - aExp = 0x7F - (aExp & 0x1); - break; - case 0x2: // interval [1/2,1) - aExp = 0x7E; - break; - case 0x3: // interval [3/4,3/2) - aExp = 0x7F - ((aSig >> 22) & 0x1); - break; - } - - return packFloat32(~sign_ctrl & aSign, aExp, aSig); -} - -/*---------------------------------------------------------------------------- -| Return the result of a floating point scale of the single-precision floating -| point value `a' by multiplying it by 2 power of the single-precision -| floating point value 'b' converted to integral value. If the result cannot -| be represented in single precision, then the proper overflow response (for -| positive scaling operand), or the proper underflow response (for negative -| scaling operand) is issued. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_scalef(float32 a, float32 b, struct float_status_t *status) -{ - Bit32u aSig = extractFloat32Frac(a); - Bit16s aExp = extractFloat32Exp(a); - int aSign = extractFloat32Sign(a); - Bit32u bSig = extractFloat32Frac(b); - Bit16s bExp = extractFloat32Exp(b); - int bSign = extractFloat32Sign(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - } - - if (aExp == 0xFF) { - if (aSig) { - int aIsSignalingNaN = (aSig & 0x00400000) == 0; - if (aIsSignalingNaN || bExp != 0xFF || bSig) - return propagateFloat32NaN(a, b, status); - - return bSign ? 0 : float32_positive_inf; - } - - if (bExp == 0xFF && bSign) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - return a; - } - - if (aExp == 0) { - if (aSig == 0) { - if (bExp == 0xFF && ! bSign) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - return a; - } - float_raise(status, float_flag_denormal); - } - - if ((bExp | bSig) == 0) return a; - - if (bExp == 0xFF) { - if (bSign) return packFloat32(aSign, 0, 0); - return packFloat32(aSign, 0xFF, 0); - } - - if (bExp >= 0x8E) { - // handle obvious overflow/underflow result - return roundAndPackFloat32(aSign, bSign ? -0x7F : 0xFF, aSig, status); - } - - int scale = 0; - - if (bExp <= 0x7E) { - if (bExp == 0) - float_raise(status, float_flag_denormal); - scale = -bSign; - } - else { - int shiftCount = bExp - 0x9E; - bSig = (bSig | 0x800000)<<8; - scale = bSig>>(-shiftCount); - - if (bSign) { - if ((Bit32u) (bSig<<(shiftCount & 31))) scale++; - scale = -scale; - } - - if (scale > 0x200) scale = 0x200; - if (scale < -0x200) scale = -0x200; - } - - if (aExp != 0) { - aSig |= 0x00800000; - } else { - aExp++; - } - - aExp += scale - 1; - aSig <<= 7; - return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 addFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status) -{ - Bit16s aExp, bExp, zExp; - Bit32u aSig, bSig, zSig; - Bit16s expDiff; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - - if (0 < expDiff) { - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaN(a, b, status); - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if ((aExp == 0) && aSig) - float_raise(status, float_flag_denormal); - - if (bExp == 0) { - if (bSig) float_raise(status, float_flag_denormal); - --expDiff; - } - else bSig |= 0x20000000; - - bSig = shift32RightJamming(bSig, expDiff); - zExp = aExp; - } - else if (expDiff < 0) { - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0xFF, 0); - } - if ((bExp == 0) && bSig) - float_raise(status, float_flag_denormal); - - if (aExp == 0) { - if (aSig) float_raise(status, float_flag_denormal); - ++expDiff; - } - else aSig |= 0x20000000; - - aSig = shift32RightJamming(aSig, -expDiff); - zExp = bExp; - } - else { - if (aExp == 0xFF) { - if (aSig | bSig) return propagateFloat32NaN(a, b, status); - return a; - } - if (aExp == 0) { - zSig = (aSig + bSig) >> 6; - if (aSig | bSig) { - float_raise(status, float_flag_denormal); - if (get_flush_underflow_to_zero(status) && (extractFloat32Frac(zSig) == zSig)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat32(zSign, 0, 0); - } - if (! float_exception_masked(status, float_flag_underflow)) { - if (extractFloat32Frac(zSig) == zSig) - float_raise(status, float_flag_underflow); - } - } - return packFloat32(zSign, 0, zSig); - } - zSig = 0x40000000 + aSig + bSig; - return roundAndPackFloat32(zSign, aExp, zSig, status); - } - aSig |= 0x20000000; - zSig = (aSig + bSig)<<1; - --zExp; - if ((Bit32s) zSig < 0) { - zSig = aSig + bSig; - ++zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 subFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status) -{ - Bit16s aExp, bExp, zExp; - Bit32u aSig, bSig, zSig; - Bit16s expDiff; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if (0 < expDiff) goto aExpBigger; - if (expDiff < 0) goto bExpBigger; - if (aExp == 0xFF) { - if (aSig | bSig) return propagateFloat32NaN(a, b, status); - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - if (aExp == 0) { - if (aSig | bSig) float_raise(status, float_flag_denormal); - aExp = 1; - bExp = 1; - } - if (bSig < aSig) goto aBigger; - if (aSig < bSig) goto bBigger; - return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0); - bExpBigger: - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign ^ 1, 0xFF, 0); - } - if ((bExp == 0) && bSig) - float_raise(status, float_flag_denormal); - - if (aExp == 0) { - if (aSig) float_raise(status, float_flag_denormal); - ++expDiff; - } - else aSig |= 0x40000000; - - aSig = shift32RightJamming(aSig, -expDiff); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaN(a, b, status); - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if ((aExp == 0) && aSig) - float_raise(status, float_flag_denormal); - - if (bExp == 0) { - if (bSig) float_raise(status, float_flag_denormal); - --expDiff; - } - else bSig |= 0x40000000; - - bSig = shift32RightJamming(bSig, expDiff); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the single-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_add(float32 a, float32 b, struct float_status_t *status) -{ - int aSign = extractFloat32Sign(a); - int bSign = extractFloat32Sign(b); - - if (aSign == bSign) { - return addFloat32Sigs(a, b, aSign, status); - } - else { - return subFloat32Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sub(float32 a, float32 b, struct float_status_t *status) -{ - int aSign = extractFloat32Sign(a); - int bSign = extractFloat32Sign(b); - - if (aSign == bSign) { - return subFloat32Sigs(a, b, aSign, status); - } - else { - return addFloat32Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_mul(float32 a, float32 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit16s aExp, bExp, zExp; - Bit32u aSig, bSig; - Bit64u zSig64; - Bit32u zSig; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - bSign = extractFloat32Sign(b); - zSign = aSign ^ bSign; - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (aExp == 0xFF) { - if (aSig || ((bExp == 0xFF) && bSig)) - return propagateFloat32NaN(a, b, status); - - if ((bExp | bSig) == 0) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0xFF, 0); - } - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0xFF, 0); - } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return packFloat32(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - zExp = aExp + bExp - 0x7F; - aSig = (aSig | 0x00800000)<<7; - bSig = (bSig | 0x00800000)<<8; - zSig64 = shift64RightJamming(((Bit64u) aSig) * bSig, 32); - zSig = (Bit32u) zSig64; - if (0 <= (Bit32s) (zSig<<1)) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the single-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_div(float32 a, float32 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit16s aExp, bExp, zExp; - Bit32u aSig, bSig, zSig; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - bSign = extractFloat32Sign(b); - zSign = aSign ^ bSign; - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaN(a, b, status); - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0xFF, 0); - } - if (bExp == 0xFF) { - if (bSig) return propagateFloat32NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat32(zSign, 0, 0); - } - if (bExp == 0) { - if (bSig == 0) { - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - float_raise(status, float_flag_divbyzero); - return packFloat32(zSign, 0xFF, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0) { - if (aSig == 0) return packFloat32(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - zExp = aExp - bExp + 0x7D; - aSig = (aSig | 0x00800000)<<7; - bSig = (bSig | 0x00800000)<<8; - if (bSig <= (aSig + aSig)) { - aSig >>= 1; - ++zExp; - } - zSig = (((Bit64u) aSig)<<32) / bSig; - if ((zSig & 0x3F) == 0) { - zSig |= ((Bit64u) bSig * zSig != ((Bit64u) aSig)<<32); - } - return roundAndPackFloat32(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sqrt(float32 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp, zExp; - Bit32u aSig, zSig; - Bit64u rem, term; - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - - if (aExp == 0xFF) { - if (aSig) return propagateFloat32NaNOne(a, status); - if (! aSign) return a; - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - } - - if (aSign) { - if ((aExp | aSig) == 0) return packFloat32(aSign, 0, 0); - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - if (aExp == 0) { - if (aSig == 0) return 0; - float_raise(status, float_flag_denormal); - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - zExp = ((aExp - 0x7F)>>1) + 0x7E; - aSig = (aSig | 0x00800000)<<8; - zSig = estimateSqrt32(aExp, aSig) + 2; - if ((zSig & 0x7F) <= 5) { - if (zSig < 2) { - zSig = 0x7FFFFFFF; - goto roundAndPack; - } - aSig >>= aExp & 1; - term = ((Bit64u) zSig) * zSig; - rem = (((Bit64u) aSig)<<32) - term; - while ((Bit64s) rem < 0) { - --zSig; - rem += (((Bit64u) zSig)<<1) | 1; - } - zSig |= (rem != 0); - } - zSig = shift32RightJamming(zSig, 1); - roundAndPack: - return roundAndPackFloat32(0, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Determine single-precision floating-point number class. -*----------------------------------------------------------------------------*/ - -float_class_t float32_class(float32 a) -{ - Bit16s aExp = extractFloat32Exp(a); - Bit32u aSig = extractFloat32Frac(a); - int aSign = extractFloat32Sign(a); - - if(aExp == 0xFF) { - if (aSig == 0) - return (aSign) ? float_negative_inf : float_positive_inf; - - return (aSig & 0x00400000) ? float_QNaN : float_SNaN; - } - - if(aExp == 0) { - if (aSig == 0) return float_zero; - return float_denormal; - } - - return float_normalized; -} - -/*---------------------------------------------------------------------------- -| Compare between two single precision floating point numbers. Returns -| 'float_relation_equal' if the operands are equal, 'float_relation_less' if -| the value 'a' is less than the corresponding value `b', -| 'float_relation_greater' if the value 'a' is greater than the corresponding -| value `b', or 'float_relation_unordered' otherwise. -*----------------------------------------------------------------------------*/ - -int float32_compare(float32 a, float32 b, int quiet, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float32_denormal_to_zero(a); - b = float32_denormal_to_zero(b); - } - - float_class_t aClass = float32_class(a); - float_class_t bClass = float32_class(b); - - if (aClass == float_SNaN || bClass == float_SNaN) { - float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_QNaN || bClass == float_QNaN) { - if (! quiet) float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_denormal || bClass == float_denormal) { - float_raise(status, float_flag_denormal); - } - - if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal; - - int aSign = extractFloat32Sign(a); - int bSign = extractFloat32Sign(b); - if (aSign != bSign) - return (aSign) ? float_relation_less : float_relation_greater; - - if (aSign ^ (a < b)) return float_relation_less; - return float_relation_greater; -} - -/*---------------------------------------------------------------------------- -| Compare between two single precision floating point numbers and return the -| smaller of them. -*----------------------------------------------------------------------------*/ - -float32 float32_min(float32 a, float32 b, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float32_denormal_to_zero(a); - b = float32_denormal_to_zero(b); - } - - return (float32_compare_two(a, b, status) == float_relation_less) ? a : b; -} - -/*---------------------------------------------------------------------------- -| Compare between two single precision floating point numbers and return the -| larger of them. -*----------------------------------------------------------------------------*/ - -float32 float32_max(float32 a, float32 b, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float32_denormal_to_zero(a); - b = float32_denormal_to_zero(b); - } - - return (float32_compare_two(a, b, status) == float_relation_greater) ? a : b; -} - -/*---------------------------------------------------------------------------- -| Compare between two single precision floating point numbers and return the -| smaller/larger of them. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float32_denormal_to_zero(a); - b = float32_denormal_to_zero(b); - } - - if (float32_is_nan(a) || float32_is_nan(b)) { - if (float32_is_signaling_nan(a)) { - return propagateFloat32NaNOne(a, status); - } - if (float32_is_signaling_nan(b) ) { - return propagateFloat32NaNOne(b, status); - } - if (! float32_is_nan(b)) { - if (float32_is_denormal(b)) - float_raise(status, float_flag_denormal); - return b; - } - if (! float32_is_nan(a)) { - if (float32_is_denormal(a)) - float_raise(status, float_flag_denormal); - return a; - } - return propagateFloat32NaN(a, b, status); - } - - float32 tmp_a = a, tmp_b = b; - if (is_abs) { - tmp_a &= ~0x80000000; // clear the sign bit - tmp_b &= ~0x80000000; - } - - int aSign = extractFloat32Sign(tmp_a); - int bSign = extractFloat32Sign(tmp_b); - - if (float32_is_denormal(a) || float32_is_denormal(b)) - float_raise(status, float_flag_denormal); - - if (aSign != bSign) { - if (! is_max) { - return aSign ? a : b; - } else { - return aSign ? b : a; - } - } else { - if (! is_max) { - return (aSign ^ (tmp_a < tmp_b)) ? a : b; - } else { - return (aSign ^ (tmp_a < tmp_b)) ? b : a; - } - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic - which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the -| conversion overflows, the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s float64_to_int32(float64 a, struct float_status_t *status) -{ - Bit64u aSig = extractFloat64Frac(a); - Bit16s aExp = extractFloat64Exp(a); - int aSign = extractFloat64Sign(a); - if ((aExp == 0x7FF) && aSig) aSign = 0; - if (aExp) aSig |= BX_CONST64(0x0010000000000000); - else { - if (get_denormals_are_zeros(status)) aSig = 0; - } - int shiftCount = 0x42C - aExp; - if (0 < shiftCount) aSig = shift64RightJamming(aSig, shiftCount); - return roundAndPackInt32(aSign, aSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN or the conversion overflows, the integer indefinite -| value is returned. -*----------------------------------------------------------------------------*/ - -Bit32s float64_to_int32_round_to_zero(float64 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit64u aSig, savedASig; - Bit32s z; - int shiftCount; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - if (0x41E < aExp) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - else if (aExp < 0x3FF) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp || aSig) float_raise(status, float_flag_inexact); - return 0; - } - aSig |= BX_CONST64(0x0010000000000000); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = (Bit32s) aSig; - if (aSign) z = -z; - if ((z < 0) ^ aSign) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if ((aSig<>= shiftCount; - if ((aSig<>(-shiftCount); - if ((Bit64u) (aSig<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - } - if (aSign) z = -z; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic, -| except that the conversion is always rounded toward zero. If `a' is a NaN -| or the conversion overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u float64_to_uint64_round_to_zero(float64 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit64u aSig, z; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - - if (aExp < 0x3FE) { - if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0; - if (aExp | aSig) float_raise(status, float_flag_inexact); - return 0; - } - - if (0x43E <= aExp || aSign) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - if (aExp) aSig |= BX_CONST64(0x0010000000000000); - int shiftCount = aExp - 0x433; - - if (0 <= shiftCount) { - z = aSig<>(-shiftCount); - if ((Bit64u) (aSig<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the conversion -| overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit32u float64_to_uint32(float64 a, struct float_status_t *status) -{ - Bit64u val_64 = float64_to_uint64(a, status); - - if (val_64 > 0xffffffff) { - status->float_exception_flags = float_flag_invalid; // throw away other flags - return uint32_indefinite; - } - - return (Bit32u) val_64; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN or the conversion -| overflows, the largest unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -Bit64u float64_to_uint64(float64 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp, shiftCount; - Bit64u aSig, aSigExtra; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - } - - if (aSign && (aExp > 0x3FE)) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - - if (aExp) { - aSig |= BX_CONST64(0x0010000000000000); - } - shiftCount = 0x433 - aExp; - if (shiftCount <= 0) { - if (0x43E < aExp) { - float_raise(status, float_flag_invalid); - return uint64_indefinite; - } - aSigExtra = 0; - aSig <<= -shiftCount; - } else { - shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra); - } - - return roundAndPackUint64(aSign, aSig, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the single-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float64_to_float32(float64 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp; - Bit64u aSig; - Bit32u zSig; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - if (aExp == 0x7FF) { - if (aSig) return commonNaNToFloat32(float64ToCommonNaN(a, status)); - return packFloat32(aSign, 0xFF, 0); - } - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return packFloat32(aSign, 0, 0); - float_raise(status, float_flag_denormal); - } - aSig = shift64RightJamming(aSig, 22); - zSig = (Bit32u) aSig; - if (aExp || zSig) { - zSig |= 0x40000000; - aExp -= 0x381; - } - return roundAndPackFloat32(aSign, aExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_round_to_int(float64 a, Bit8u scale, struct float_status_t *status) -{ - Bit64u lastBitMask, roundBitsMask; - int roundingMode = get_float_rounding_mode(status); - Bit16s aExp = extractFloat64Exp(a); - scale &= 0xf; - - if ((aExp == 0x7FF) && extractFloat64Frac(a)) { - return propagateFloat64NaNOne(a, status); - } - - aExp += scale; // scale the exponent - - if (0x433 <= aExp) { - return a; - } - - if (get_denormals_are_zeros(status)) { - a = float64_denormal_to_zero(a); - } - - if (aExp < 0x3FF) { - if ((Bit64u) (a<<1) == 0) return a; - float_raise(status, float_flag_inexact); - int aSign = extractFloat64Sign(a); - switch (roundingMode) { - case float_round_nearest_even: - if ((aExp == 0x3FE) && extractFloat64Frac(a)) { - return packFloat64(aSign, 0x3FF - scale, 0); - } - break; - case float_round_down: - return aSign ? packFloat64(1, 0x3FF - scale, 0) : float64_positive_zero; - case float_round_up: - return aSign ? float64_negative_zero : packFloat64(0, 0x3FF - scale, 0); - } - return packFloat64(aSign, 0, 0); - } - - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - float64 z = a; - if (roundingMode == float_round_nearest_even) { - z += lastBitMask>>1; - if ((z & roundBitsMask) == 0) z &= ~lastBitMask; - } - else if (roundingMode != float_round_to_zero) { - if (extractFloat64Sign(z) ^ (roundingMode == float_round_up)) { - z += roundBitsMask; - } - } - z &= ~roundBitsMask; - if (z != a) float_raise(status, float_flag_inexact); - return z; -} - -/*---------------------------------------------------------------------------- -| Extracts the fractional portion of double-precision floating-point value `a', -| and returns the result as a double-precision floating-point value. The -| fractional results are precise. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_frc(float64 a, struct float_status_t *status) -{ - int roundingMode = get_float_rounding_mode(status); - - Bit64u aSig = extractFloat64Frac(a); - Bit16s aExp = extractFloat64Exp(a); - int aSign = extractFloat64Sign(a); - - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaNOne(a, status); - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - - if (aExp >= 0x433) { - return packFloat64(roundingMode == float_round_down, 0, 0); - } - - if (aExp < 0x3FF) { - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return packFloat64(roundingMode == float_round_down, 0, 0); - - float_raise(status, float_flag_denormal); - if (! float_exception_masked(status, float_flag_underflow)) - float_raise(status, float_flag_underflow); - - if(get_flush_underflow_to_zero(status)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat64(aSign, 0, 0); - } - } - return a; - } - - Bit64u lastBitMask = BX_CONST64(1) << (0x433 - aExp); - Bit64u roundBitsMask = lastBitMask - 1; - - aSig &= roundBitsMask; - aSig <<= 10; - aExp--; - - if (aSig == 0) - return packFloat64(roundingMode == float_round_down, 0, 0); - - return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status); -} - -/*---------------------------------------------------------------------------- -| Extracts the exponent portion of double-precision floating-point value 'a', -| and returns the result as a double-precision floating-point value -| representing unbiased integer exponent. The operation is performed according -| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_getexp(float64 a, struct float_status_t *status) -{ - Bit16s aExp = extractFloat64Exp(a); - Bit64u aSig = extractFloat64Frac(a); - - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaNOne(a, status); - return float64_positive_inf; - } - - if (aExp == 0) { - if (aSig == 0 || get_denormals_are_zeros(status)) - return float64_negative_inf; - - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - - return int32_to_float64(aExp - 0x3FF); -} - -/*---------------------------------------------------------------------------- -| Extracts the mantissa of double-precision floating-point value 'a' and -| returns the result as a double-precision floating-point after applying -| the mantissa interval normalization and sign control. The operation is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv) -{ - Bit16s aExp = extractFloat64Exp(a); - Bit64u aSig = extractFloat64Frac(a); - int aSign = extractFloat64Sign(a); - - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaNOne(a, status); - if (aSign) { - if (sign_ctrl & 0x2) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - } - return packFloat64(~sign_ctrl & aSign, 0x3FF, 0); - } - - if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) { - return packFloat64(~sign_ctrl & aSign, 0x3FF, 0); - } - - if (aSign) { - if (sign_ctrl & 0x2) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - } - - if (aExp == 0) { - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); -// aExp += 0x3FE; - aSig &= BX_CONST64(0xFFFFFFFFFFFFFFFF); - } - - switch(interv) { - case 0x0: // interval [1,2) - aExp = 0x3FF; - break; - case 0x1: // interval [1/2,2) - aExp -= 0x3FF; - aExp = 0x3FF - (aExp & 0x1); - break; - case 0x2: // interval [1/2,1) - aExp = 0x3FE; - break; - case 0x3: // interval [3/4,3/2) - aExp = 0x3FF - ((aSig >> 51) & 0x1); - break; - } - - return packFloat64(~sign_ctrl & aSign, aExp, aSig); -} - -/*---------------------------------------------------------------------------- -| Return the result of a floating point scale of the double-precision floating -| point value `a' by multiplying it by 2 power of the double-precision -| floating point value 'b' converted to integral value. If the result cannot -| be represented in double precision, then the proper overflow response (for -| positive scaling operand), or the proper underflow response (for negative -| scaling operand) is issued. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_scalef(float64 a, float64 b, struct float_status_t *status) -{ - Bit64u aSig = extractFloat64Frac(a); - Bit16s aExp = extractFloat64Exp(a); - int aSign = extractFloat64Sign(a); - Bit64u bSig = extractFloat64Frac(b); - Bit16s bExp = extractFloat64Exp(b); - int bSign = extractFloat64Sign(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - } - - if (aExp == 0x7FF) { - if (aSig) { - int aIsSignalingNaN = (aSig & BX_CONST64(0x0008000000000000)) == 0; - if (aIsSignalingNaN || bExp != 0x7FF || bSig) - return propagateFloat64NaN(a, b, status); - - return bSign ? 0 : float64_positive_inf; - } - - if (bExp == 0x7FF && bSign) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - return a; - } - - if (aExp == 0) { - if (aSig == 0) { - if (bExp == 0x7FF && ! bSign) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - return a; - } - float_raise(status, float_flag_denormal); - } - - if ((bExp | bSig) == 0) return a; - - if (bExp == 0x7FF) { - if (bSign) return packFloat64(aSign, 0, 0); - return packFloat64(aSign, 0x7FF, 0); - } - - if (0x40F <= bExp) { - // handle obvious overflow/underflow result - return roundAndPackFloat64(aSign, bSign ? -0x3FF : 0x7FF, aSig, status); - } - - int scale = 0; - - if (bExp < 0x3FF) { - if (bExp == 0) - float_raise(status, float_flag_denormal); - scale = -bSign; - } - else { - bSig |= BX_CONST64(0x0010000000000000); - int shiftCount = 0x433 - bExp; - Bit64u savedBSig = bSig; - bSig >>= shiftCount; - scale = (Bit32s) bSig; - if (bSign) { - if ((bSig< 0x1000) scale = 0x1000; - if (scale < -0x1000) scale = -0x1000; - } - - if (aExp != 0) { - aSig |= BX_CONST64(0x0010000000000000); - } else { - aExp++; - } - - aExp += scale - 1; - aSig <<= 10; - return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 addFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status) -{ - Bit16s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig; - Bit16s expDiff; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if (0 < expDiff) { - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaN(a, b, status); - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if ((aExp == 0) && aSig) - float_raise(status, float_flag_denormal); - - if (bExp == 0) { - if (bSig) float_raise(status, float_flag_denormal); - --expDiff; - } - else bSig |= BX_CONST64(0x2000000000000000); - - bSig = shift64RightJamming(bSig, expDiff); - zExp = aExp; - } - else if (expDiff < 0) { - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0x7FF, 0); - } - if ((bExp == 0) && bSig) - float_raise(status, float_flag_denormal); - - if (aExp == 0) { - if (aSig) float_raise(status, float_flag_denormal); - ++expDiff; - } - else aSig |= BX_CONST64(0x2000000000000000); - - aSig = shift64RightJamming(aSig, -expDiff); - zExp = bExp; - } - else { - if (aExp == 0x7FF) { - if (aSig | bSig) return propagateFloat64NaN(a, b, status); - return a; - } - if (aExp == 0) { - zSig = (aSig + bSig) >> 9; - if (aSig | bSig) { - float_raise(status, float_flag_denormal); - if (get_flush_underflow_to_zero(status) && (extractFloat64Frac(zSig) == zSig)) { - float_raise(status, float_flag_underflow | float_flag_inexact); - return packFloat64(zSign, 0, 0); - } - if (! float_exception_masked(status, float_flag_underflow)) { - if (extractFloat64Frac(zSig) == zSig) - float_raise(status, float_flag_underflow); - } - } - return packFloat64(zSign, 0, zSig); - } - zSig = BX_CONST64(0x4000000000000000) + aSig + bSig; - return roundAndPackFloat64(zSign, aExp, zSig, status); - } - aSig |= BX_CONST64(0x2000000000000000); - zSig = (aSig + bSig)<<1; - --zExp; - if ((Bit64s) zSig < 0) { - zSig = aSig + bSig; - ++zExp; - } - return roundAndPackFloat64(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 subFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status) -{ - Bit16s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig; - Bit16s expDiff; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if (0 < expDiff) goto aExpBigger; - if (expDiff < 0) goto bExpBigger; - if (aExp == 0x7FF) { - if (aSig | bSig) return propagateFloat64NaN(a, b, status); - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - if (aExp == 0) { - if (aSig | bSig) float_raise(status, float_flag_denormal); - aExp = 1; - bExp = 1; - } - if (bSig < aSig) goto aBigger; - if (aSig < bSig) goto bBigger; - return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0); - bExpBigger: - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign ^ 1, 0x7FF, 0); - } - if ((bExp == 0) && bSig) - float_raise(status, float_flag_denormal); - - if (aExp == 0) { - if (aSig) float_raise(status, float_flag_denormal); - ++expDiff; - } - else aSig |= BX_CONST64(0x4000000000000000); - - aSig = shift64RightJamming(aSig, -expDiff); - bSig |= BX_CONST64(0x4000000000000000); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaN(a, b, status); - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if ((aExp == 0) && aSig) - float_raise(status, float_flag_denormal); - - if (bExp == 0) { - if (bSig) float_raise(status, float_flag_denormal); - --expDiff; - } - else bSig |= BX_CONST64(0x4000000000000000); - - bSig = shift64RightJamming(bSig, expDiff); - aSig |= BX_CONST64(0x4000000000000000); - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the double-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_add(float64 a, float64 b, struct float_status_t *status) -{ - int aSign = extractFloat64Sign(a); - int bSign = extractFloat64Sign(b); - - if (aSign == bSign) { - return addFloat64Sigs(a, b, aSign, status); - } - else { - return subFloat64Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sub(float64 a, float64 b, struct float_status_t *status) -{ - int aSign = extractFloat64Sign(a); - int bSign = extractFloat64Sign(b); - - if (aSign == bSign) { - return subFloat64Sigs(a, b, aSign, status); - } - else { - return addFloat64Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_mul(float64 a, float64 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit16s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - bSign = extractFloat64Sign(b); - zSign = aSign ^ bSign; - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (aExp == 0x7FF) { - if (aSig || ((bExp == 0x7FF) && bSig)) { - return propagateFloat64NaN(a, b, status); - } - if ((bExp | bSig) == 0) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0x7FF, 0); - } - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0x7FF, 0); - } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return packFloat64(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - zExp = aExp + bExp - 0x3FF; - aSig = (aSig | BX_CONST64(0x0010000000000000))<<10; - bSig = (bSig | BX_CONST64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &zSig0, &zSig1); - zSig0 |= (zSig1 != 0); - if (0 <= (Bit64s) (zSig0<<1)) { - zSig0 <<= 1; - --zExp; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the double-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_div(float64 a, float64 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit16s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig; - Bit64u rem0, rem1; - Bit64u term0, term1; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - bSign = extractFloat64Sign(b); - zSign = aSign ^ bSign; - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - if (bExp == 0) bSig = 0; - } - - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaN(a, b, status); - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0x7FF, 0); - } - if (bExp == 0x7FF) { - if (bSig) return propagateFloat64NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloat64(zSign, 0, 0); - } - if (bExp == 0) { - if (bSig == 0) { - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - float_raise(status, float_flag_divbyzero); - return packFloat64(zSign, 0x7FF, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0) { - if (aSig == 0) return packFloat64(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - zExp = aExp - bExp + 0x3FD; - aSig = (aSig | BX_CONST64(0x0010000000000000))<<10; - bSig = (bSig | BX_CONST64(0x0010000000000000))<<11; - if (bSig <= (aSig + aSig)) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64(aSig, 0, bSig); - if ((zSig & 0x1FF) <= 2) { - mul64To128(bSig, zSig, &term0, &term1); - sub128(aSig, 0, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig; - add128(rem0, rem1, 0, bSig, &rem0, &rem1); - } - zSig |= (rem1 != 0); - } - return roundAndPackFloat64(zSign, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sqrt(float64 a, struct float_status_t *status) -{ - int aSign; - Bit16s aExp, zExp; - Bit64u aSig, zSig, doubleZSig; - Bit64u rem0, rem1, term0, term1; - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - - if (aExp == 0x7FF) { - if (aSig) return propagateFloat64NaNOne(a, status); - if (! aSign) return a; - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - - if (get_denormals_are_zeros(status)) { - if (aExp == 0) aSig = 0; - } - - if (aSign) { - if ((aExp | aSig) == 0) return packFloat64(aSign, 0, 0); - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - if (aExp == 0) { - if (aSig == 0) return 0; - float_raise(status, float_flag_denormal); - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - zExp = ((aExp - 0x3FF)>>1) + 0x3FE; - aSig |= BX_CONST64(0x0010000000000000); - zSig = estimateSqrt32(aExp, (Bit32u)(aSig>>21)); - aSig <<= 9 - (aExp & 1); - zSig = estimateDiv128To64(aSig, 0, zSig<<32) + (zSig<<30); - if ((zSig & 0x1FF) <= 5) { - doubleZSig = zSig<<1; - mul64To128(zSig, zSig, &term0, &term1); - sub128(aSig, 0, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig; - doubleZSig -= 2; - add128(rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1); - } - zSig |= ((rem0 | rem1) != 0); - } - return roundAndPackFloat64(0, zExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Determine double-precision floating-point number class -*----------------------------------------------------------------------------*/ - -float_class_t float64_class(float64 a) -{ - Bit16s aExp = extractFloat64Exp(a); - Bit64u aSig = extractFloat64Frac(a); - int aSign = extractFloat64Sign(a); - - if(aExp == 0x7FF) { - if (aSig == 0) - return (aSign) ? float_negative_inf : float_positive_inf; - - return (aSig & BX_CONST64(0x0008000000000000)) ? float_QNaN : float_SNaN; - } - - if(aExp == 0) { - if (aSig == 0) - return float_zero; - return float_denormal; - } - - return float_normalized; -} - -/*---------------------------------------------------------------------------- -| Compare between two double precision floating point numbers. Returns -| 'float_relation_equal' if the operands are equal, 'float_relation_less' if -| the value 'a' is less than the corresponding value `b', -| 'float_relation_greater' if the value 'a' is greater than the corresponding -| value `b', or 'float_relation_unordered' otherwise. -*----------------------------------------------------------------------------*/ - -int float64_compare(float64 a, float64 b, int quiet, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float64_denormal_to_zero(a); - b = float64_denormal_to_zero(b); - } - - float_class_t aClass = float64_class(a); - float_class_t bClass = float64_class(b); - - if (aClass == float_SNaN || bClass == float_SNaN) { - float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_QNaN || bClass == float_QNaN) { - if (! quiet) float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_denormal || bClass == float_denormal) { - float_raise(status, float_flag_denormal); - } - - if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal; - - int aSign = extractFloat64Sign(a); - int bSign = extractFloat64Sign(b); - if (aSign != bSign) - return (aSign) ? float_relation_less : float_relation_greater; - - if (aSign ^ (a < b)) return float_relation_less; - return float_relation_greater; -} - -/*---------------------------------------------------------------------------- -| Compare between two double precision floating point numbers and return the -| smaller of them. -*----------------------------------------------------------------------------*/ - -float64 float64_min(float64 a, float64 b, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float64_denormal_to_zero(a); - b = float64_denormal_to_zero(b); - } - - return (float64_compare_two(a, b, status) == float_relation_less) ? a : b; -} - -/*---------------------------------------------------------------------------- -| Compare between two double precision floating point numbers and return the -| larger of them. -*----------------------------------------------------------------------------*/ - -float64 float64_max(float64 a, float64 b, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float64_denormal_to_zero(a); - b = float64_denormal_to_zero(b); - } - - return (float64_compare_two(a, b, status) == float_relation_greater) ? a : b; -} - -/*---------------------------------------------------------------------------- -| Compare between two double precision floating point numbers and return the -| smaller/larger of them. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status) -{ - if (get_denormals_are_zeros(status)) { - a = float64_denormal_to_zero(a); - b = float64_denormal_to_zero(b); - } - - if (float64_is_nan(a) || float64_is_nan(b)) { - if (float64_is_signaling_nan(a)) { - return propagateFloat64NaNOne(a, status); - } - if (float64_is_signaling_nan(b)) { - return propagateFloat64NaNOne(b, status); - } - if (! float64_is_nan(b)) { - if (float64_is_denormal(b)) - float_raise(status, float_flag_denormal); - return b; - } - if (! float64_is_nan(a)) { - if (float64_is_denormal(a)) - float_raise(status, float_flag_denormal); - return a; - } - return propagateFloat64NaN(a, b, status); - } - - float64 tmp_a = a, tmp_b = b; - if (is_abs) { - tmp_a &= ~BX_CONST64(0x8000000000000000); // clear the sign bit - tmp_b &= ~BX_CONST64(0x8000000000000000); - } - - int aSign = extractFloat64Sign(tmp_a); - int bSign = extractFloat64Sign(tmp_b); - - if (float64_is_denormal(a) || float64_is_denormal(b)) - float_raise(status, float_flag_denormal); - - if (aSign != bSign) { - if (! is_max) { - return aSign ? a : b; - } else { - return aSign ? b : a; - } - } else { - if (! is_max) { - return (aSign ^ (tmp_a < tmp_b)) ? a : b; - } else { - return (aSign ^ (tmp_a < tmp_b)) ? b : a; - } - } -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 int32_to_floatx80(Bit32s a) -{ - if (a == 0) return packFloatx80(0, 0, 0); - int zSign = (a < 0); - Bit32u absA = zSign ? -a : a; - int shiftCount = countLeadingZeros32(absA) + 32; - Bit64u zSig = absA; - return packFloatx80(zSign, 0x403E - shiftCount, zSig< 0x401E) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if (aExp < 0x3FFF) { - if (aExp || aSig) float_raise(status, float_flag_inexact); - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = (Bit32s) aSig; - if (aSign) z = -z; - if ((z < 0) ^ aSign) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if ((aSig<>(-shiftCount); - if ((Bit64u) (aSig<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - if (aSign) z = -z; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 floatx80_to_float32(floatx80 a, struct float_status_t *status) -{ - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - return commonNaNToFloat32(floatx80ToCommonNaN(a, status)); - - return packFloat32(aSign, 0xFF, 0); - } - aSig = shift64RightJamming(aSig, 33); - if (aExp || aSig) aExp -= 0x3F81; - return roundAndPackFloat32(aSign, aExp, (Bit32u) aSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 floatx80_to_float64(floatx80 a, struct float_status_t *status) -{ - Bit32s aExp; - Bit64u aSig, zSig; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) { - return commonNaNToFloat64(floatx80ToCommonNaN(a, status)); - } - return packFloat64(aSign, 0x7FF, 0); - } - zSig = shift64RightJamming(aSig, 1); - if (aExp || aSig) aExp -= 0x3C01; - return roundAndPackFloat64(aSign, aExp, zSig, status); -} - -/*---------------------------------------------------------------------------- -| Rounds the extended double-precision floating-point value `a' to an integer, -| and returns the result as an extended double-precision floating-point -| value. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_round_to_int(floatx80 a, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - int aSign; - Bit64u lastBitMask, roundBitsMask; - int roundingMode = get_float_rounding_mode(status); - floatx80 z; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - Bit32s aExp = extractFloatx80Exp(a); - Bit64u aSig = extractFloatx80Frac(a); - if (0x403E <= aExp) { - if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1)) { - return propagateFloatx80NaNOne(a, status); - } - return a; - } - if (aExp < 0x3FFF) { - if (aExp == 0) { - if ((aSig<<1) == 0) return a; - float_raise(status, float_flag_denormal); - } - float_raise(status, float_flag_inexact); - aSign = extractFloatx80Sign(a); - switch (roundingMode) { - case float_round_nearest_even: - if ((aExp == 0x3FFE) && (Bit64u) (aSig<<1)) { - set_float_rounding_up(status); - return packFloatx80(aSign, 0x3FFF, BX_CONST64(0x8000000000000000)); - } - break; - case float_round_down: - if (aSign) { - set_float_rounding_up(status); - return packFloatx80(1, 0x3FFF, BX_CONST64(0x8000000000000000)); - } - else { - return packFloatx80(0, 0, 0); - } - case float_round_up: - if (aSign) { - return packFloatx80(1, 0, 0); - } - else { - set_float_rounding_up(status); - return packFloatx80(0, 0x3FFF, BX_CONST64(0x8000000000000000)); - } - } - return packFloatx80(aSign, 0, 0); - } - lastBitMask = 1; - lastBitMask <<= 0x403E - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - if (roundingMode == float_round_nearest_even) { - z.fraction += lastBitMask>>1; - if ((z.fraction & roundBitsMask) == 0) z.fraction &= ~lastBitMask; - } - else if (roundingMode != float_round_to_zero) { - if (extractFloatx80Sign(z) ^ (roundingMode == float_round_up)) - z.fraction += roundBitsMask; - } - z.fraction &= ~roundBitsMask; - if (z.fraction == 0) { - z.exp++; - z.fraction = BX_CONST64(0x8000000000000000); - } - if (z.fraction != a.fraction) { - float_raise(status, float_flag_inexact); - if (z.fraction > a.fraction || z.exp > a.exp) - set_float_rounding_up(status); - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the extended double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is -| negated before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) - return propagateFloatx80NaN(a, b, status); - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if ((bExp == 0) && bSig) { - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - return roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, bExp, bSig, 0, status); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) - return roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, aExp, aSig, 0, status); - - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - Bit32s expDiff = aExp - bExp; - zExp = aExp; - if (0 < expDiff) { - shift64ExtraRightJamming(bSig, 0, expDiff, &bSig, &zSig1); - } - else if (expDiff < 0) { - shift64ExtraRightJamming(aSig, 0, -expDiff, &aSig, &zSig1); - zExp = bExp; - } - else { - zSig0 = aSig + bSig; - zSig1 = 0; - goto shiftRight1; - } - zSig0 = aSig + bSig; - if ((Bit64s) zSig0 < 0) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); - zSig0 |= BX_CONST64(0x8000000000000000); - zExp++; - roundAndPack: - return - roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the extended -| double-precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status); - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign ^ 1, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if (bExp == 0) { - if (bSig) { - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - return roundAndPackFloatx80(get_float_rounding_precision(status), - zSign ^ 1, bExp, bSig, 0, status); - } - return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0); - } - return roundAndPackFloatx80(get_float_rounding_precision(status), - zSign ^ 1, bExp, bSig, 0, status); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) - return roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, aExp, aSig, 0, status); - - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - Bit32s expDiff = aExp - bExp; - if (0 < expDiff) { - shift128RightJamming(bSig, 0, expDiff, &bSig, &zSig1); - goto aBigger; - } - if (expDiff < 0) { - shift128RightJamming(aSig, 0, -expDiff, &aSig, &zSig1); - goto bBigger; - } - zSig1 = 0; - if (bSig < aSig) goto aBigger; - if (aSig < bSig) goto bBigger; - return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0); - bBigger: - sub128(bSig, 0, aSig, zSig1, &zSig0, &zSig1); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aBigger: - sub128(aSig, 0, bSig, zSig1, &zSig0, &zSig1); - zExp = aExp; - normalizeRoundAndPack: - return - normalizeRoundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the extended double-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_add(floatx80 a, floatx80 b, struct float_status_t *status) -{ - int aSign = extractFloatx80Sign(a); - int bSign = extractFloatx80Sign(b); - - if (aSign == bSign) - return addFloatx80Sigs(a, b, aSign, status); - else - return subFloatx80Sigs(a, b, aSign, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sub(floatx80 a, floatx80 b, struct float_status_t *status) -{ - int aSign = extractFloatx80Sign(a); - int bSign = extractFloatx80Sign(b); - - if (aSign == bSign) - return subFloatx80Sigs(a, b, aSign, status); - else - return addFloatx80Sigs(a, b, aSign, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_mul(floatx80 a, floatx80 b, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - int aSign, bSign, zSign; - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - invalid: - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); - zSign = aSign ^ bSign; - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) { - return propagateFloatx80NaN(a, b, status); - } - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(status, float_flag_denormal); - } - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aExp == 0) { - if (aSig == 0) goto invalid; - float_raise(status, float_flag_denormal); - } - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - zExp = aExp + bExp - 0x3FFE; - mul64To128(aSig, bSig, &zSig0, &zSig1); - if (0 < (Bit64s) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } - return - roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_div(floatx80 a, floatx80 b, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - int aSign, bSign, zSign; - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - Bit64u rem0, rem1, rem2, term0, term1, term2; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); - - zSign = aSign ^ bSign; - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status); - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - if (bExp == 0) { - if (bSig == 0) { - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - float_raise(status, float_flag_divbyzero); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0) { - if (aSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if (bSig <= aSig) { - shift128Right(aSig, 0, 1, &aSig, &rem1); - ++zExp; - } - zSig0 = estimateDiv128To64(aSig, rem1, bSig); - mul64To128(bSig, zSig0, &term0, &term1); - sub128(aSig, rem1, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig0; - add128(rem0, rem1, 0, bSig, &rem0, &rem1); - } - zSig1 = estimateDiv128To64(rem1, 0, bSig); - if ((Bit64u) (zSig1<<1) <= 8) { - mul64To128(bSig, zSig1, &term1, &term2); - sub128(rem1, 0, term1, term2, &rem1, &rem2); - while ((Bit64s) rem1 < 0) { - --zSig1; - add128(rem1, rem2, 0, bSig, &rem1, &rem2); - } - zSig1 |= ((rem1 | rem2) != 0); - } - return - roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sqrt(floatx80 a, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - int aSign; - Bit32s aExp, zExp; - Bit64u aSig0, aSig1, zSig0, zSig1, doubleZSig0; - Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1)) return propagateFloatx80NaNOne(a, status); - if (! aSign) return a; - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (aSign) { - if ((aExp | aSig0) == 0) return a; - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (aExp == 0) { - if (aSig0 == 0) return packFloatx80(0, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - } - zExp = ((aExp - 0x3FFF)>>1) + 0x3FFF; - zSig0 = estimateSqrt32(aExp, aSig0>>32); - shift128Right(aSig0, 0, 2 + (aExp & 1), &aSig0, &aSig1); - zSig0 = estimateDiv128To64(aSig0, aSig1, zSig0<<32) + (zSig0<<30); - doubleZSig0 = zSig0<<1; - mul64To128(zSig0, zSig0, &term0, &term1); - sub128(aSig0, aSig1, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig0; - doubleZSig0 -= 2; - add128(rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1); - } - zSig1 = estimateDiv128To64(rem1, 0, doubleZSig0); - if ((zSig1 & BX_CONST64(0x3FFFFFFFFFFFFFFF)) <= 5) { - if (zSig1 == 0) zSig1 = 1; - mul64To128(doubleZSig0, zSig1, &term1, &term2); - sub128(rem1, 0, term1, term2, &rem1, &rem2); - mul64To128(zSig1, zSig1, &term2, &term3); - sub192(rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3); - while ((Bit64s) rem1 < 0) { - --zSig1; - shortShift128Left(0, zSig1, 1, &term2, &term3); - term3 |= 1; - term2 |= doubleZSig0; - add192(rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3); - } - zSig1 |= ((rem1 | rem2 | rem3) != 0); - } - shortShift128Left(0, zSig1, 1, &zSig0, &zSig1); - zSig0 |= doubleZSig0; - return - roundAndPackFloatx80(get_float_rounding_precision(status), - 0, zExp, zSig0, zSig1, status); -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the quadruple-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 floatx80_to_float128(floatx80 a, struct float_status_t *status) -{ - Bit64u zSig0, zSig1; - - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - - if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1)) - return commonNaNToFloat128(floatx80ToCommonNaN(a, status)); - - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - return packFloat128Four(aSign, aExp, zSig0, zSig1); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the extended double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float128_to_floatx80(float128 a, struct float_status_t *status) -{ - Bit32s aExp; - Bit64u aSig0, aSig1; - - aSig1 = extractFloat128Frac1(a); - aSig0 = extractFloat128Frac0(a); - aExp = extractFloat128Exp(a); - int aSign = extractFloat128Sign(a); - - if (aExp == 0x7FFF) { - if (aSig0 | aSig1) - return commonNaNToFloatx80(float128ToCommonNaN(a, status)); - - return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - - if (aExp == 0) { - if ((aSig0 | aSig1) == 0) return packFloatx80(aSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1); - } - else aSig0 |= BX_CONST64(0x0001000000000000); - - shortShift128Left(aSig0, aSig1, 15, &aSig0, &aSig1); - return roundAndPackFloatx80(80, aSign, aExp, aSig0, aSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the extended double-precision floating- -| point value `a' and quadruple-precision floating point value `b'. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig0, bSig1, zSig0, zSig1, zSig2; - int aSign, bSign, zSign; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - invalid: - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig0 = extractFloat128Frac0(b); - bSig1 = extractFloat128Frac1(b); - bExp = extractFloat128Exp(b); - bSign = extractFloat128Sign(b); - - zSign = aSign ^ bSign; - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) - || ((bExp == 0x7FFF) && (bSig0 | bSig1))) - { - floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status)); - return propagateFloatx80NaN(a, r, status); - } - if (bExp == 0) { - if ((bSig0 | bSig1) == 0) goto invalid; - float_raise(status, float_flag_denormal); - } - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) { - floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status)); - return propagateFloatx80NaN(a, r, status); - } - if (aExp == 0) { - if (aSig == 0) goto invalid; - float_raise(status, float_flag_denormal); - } - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if ((bExp == 0) && (bSig0 | bSig1)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if ((bSig0 | bSig1) == 0) return packFloatx80(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1); - } - else bSig0 |= BX_CONST64(0x0001000000000000); - - zExp = aExp + bExp - 0x3FFE; - shortShift128Left(bSig0, bSig1, 15, &bSig0, &bSig1); - mul128By64To192(bSig0, bSig1, aSig, &zSig0, &zSig1, &zSig2); - if (0 < (Bit64s) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } - return - roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the quadruple-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 addFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status) -{ - Bit32s aExp, bExp, zExp; - Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - Bit32s expDiff; - - aSig1 = extractFloat128Frac1(a); - aSig0 = extractFloat128Frac0(a); - aExp = extractFloat128Exp(a); - bSig1 = extractFloat128Frac1(b); - bSig0 = extractFloat128Frac0(b); - bExp = extractFloat128Exp(b); - expDiff = aExp - bExp; - - if (0 < expDiff) { - if (aExp == 0x7FFF) { - if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status); - return a; - } - if (bExp == 0) --expDiff; - else bSig0 |= BX_CONST64(0x0001000000000000); - shift128ExtraRightJamming(bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2); - zExp = aExp; - } - else if (expDiff < 0) { - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status); - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - if (aExp == 0) ++expDiff; - else aSig0 |= BX_CONST64(0x0001000000000000); - shift128ExtraRightJamming(aSig0, aSig1, 0, -expDiff, &aSig0, &aSig1, &zSig2); - zExp = bExp; - } - else { - if (aExp == 0x7FFF) { - if (aSig0 | aSig1 | bSig0 | bSig1) - return propagateFloat128NaN(a, b, status); - - return a; - } - add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1); - if (aExp == 0) return packFloat128Four(zSign, 0, zSig0, zSig1); - zSig2 = 0; - zSig0 |= BX_CONST64(0x0002000000000000); - zExp = aExp; - goto shiftRight1; - } - aSig0 |= BX_CONST64(0x0001000000000000); - add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1); - --zExp; - if (zSig0 < BX_CONST64(0x0002000000000000)) goto roundAndPack; - ++zExp; - shiftRight1: - shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2); - roundAndPack: - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the quadruple- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 subFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status) -{ - Bit32s aExp, bExp, zExp; - Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; - Bit32s expDiff; - - aSig1 = extractFloat128Frac1(a); - aSig0 = extractFloat128Frac0(a); - aExp = extractFloat128Exp(a); - bSig1 = extractFloat128Frac1(b); - bSig0 = extractFloat128Frac0(b); - bExp = extractFloat128Exp(b); - - expDiff = aExp - bExp; - shortShift128Left(aSig0, aSig1, 14, &aSig0, &aSig1); - shortShift128Left(bSig0, bSig1, 14, &bSig0, &bSig1); - if (0 < expDiff) goto aExpBigger; - if (expDiff < 0) goto bExpBigger; - if (aExp == 0x7FFF) { - if (aSig0 | aSig1 | bSig0 | bSig1) - return propagateFloat128NaN(a, b, status); - - float_raise(status, float_flag_invalid); - return float128_default_nan; - } - if (aExp == 0) { - aExp = 1; - bExp = 1; - } - if (bSig0 < aSig0) goto aBigger; - if (aSig0 < bSig0) goto bBigger; - if (bSig1 < aSig1) goto aBigger; - if (aSig1 < bSig1) goto bBigger; - return packFloat128(0, 0); - - bExpBigger: - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status); - return packFloat128Four(zSign ^ 1, 0x7FFF, 0, 0); - } - if (aExp == 0) ++expDiff; - else { - aSig0 |= BX_CONST64(0x4000000000000000); - } - shift128RightJamming(aSig0, aSig1, - expDiff, &aSig0, &aSig1); - bSig0 |= BX_CONST64(0x4000000000000000); - bBigger: - sub128(bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if (aExp == 0x7FFF) { - if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status); - return a; - } - if (bExp == 0) --expDiff; - else { - bSig0 |= BX_CONST64(0x4000000000000000); - } - shift128RightJamming(bSig0, bSig1, expDiff, &bSig0, &bSig1); - aSig0 |= BX_CONST64(0x4000000000000000); - aBigger: - sub128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1); - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat128(zSign, zExp - 14, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the quadruple-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_add(float128 a, float128 b, struct float_status_t *status) -{ - int aSign = extractFloat128Sign(a); - int bSign = extractFloat128Sign(b); - - if (aSign == bSign) { - return addFloat128Sigs(a, b, aSign, status); - } - else { - return subFloat128Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sub(float128 a, float128 b, struct float_status_t *status) -{ - int aSign = extractFloat128Sign(a); - int bSign = extractFloat128Sign(b); - - if (aSign == bSign) { - return subFloat128Sigs(a, b, aSign, status); - } - else { - return addFloat128Sigs(a, b, aSign, status); - } -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_mul(float128 a, float128 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit32s aExp, bExp, zExp; - Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; - - aSig1 = extractFloat128Frac1(a); - aSig0 = extractFloat128Frac0(a); - aExp = extractFloat128Exp(a); - aSign = extractFloat128Sign(a); - bSig1 = extractFloat128Frac1(b); - bSig0 = extractFloat128Frac0(b); - bExp = extractFloat128Exp(b); - bSign = extractFloat128Sign(b); - - zSign = aSign ^ bSign; - if (aExp == 0x7FFF) { - if ((aSig0 | aSig1) || ((bExp == 0x7FFF) && (bSig0 | bSig1))) { - return propagateFloat128NaN(a, b, status); - } - if ((bExp | bSig0 | bSig1) == 0) { - float_raise(status, float_flag_invalid); - return float128_default_nan; - } - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status); - if ((aExp | aSig0 | aSig1) == 0) { - float_raise(status, float_flag_invalid); - return float128_default_nan; - } - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - if (aExp == 0) { - if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1); - } - if (bExp == 0) { - if ((bSig0 | bSig1) == 0) return packFloat128Four(zSign, 0, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1); - } - zExp = aExp + bExp - 0x4000; - aSig0 |= BX_CONST64(0x0001000000000000); - shortShift128Left(bSig0, bSig1, 16, &bSig0, &bSig1); - mul128To256(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3); - add128(zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1); - zSig2 |= (zSig3 != 0); - if (BX_CONST64(0x0002000000000000) <= zSig0) { - shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2); - ++zExp; - } - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the quadruple-precision floating-point value -| `a' by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_div(float128 a, float128 b, struct float_status_t *status) -{ - int aSign, bSign, zSign; - Bit32s aExp, bExp, zExp; - Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3; - - aSig1 = extractFloat128Frac1(a); - aSig0 = extractFloat128Frac0(a); - aExp = extractFloat128Exp(a); - aSign = extractFloat128Sign(a); - bSig1 = extractFloat128Frac1(b); - bSig0 = extractFloat128Frac0(b); - bExp = extractFloat128Exp(b); - bSign = extractFloat128Sign(b); - - zSign = aSign ^ bSign; - if (aExp == 0x7FFF) { - if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status); - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status); - float_raise(status, float_flag_invalid); - return float128_default_nan; - } - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - if (bExp == 0x7FFF) { - if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status); - return packFloat128Four(zSign, 0, 0, 0); - } - if (bExp == 0) { - if ((bSig0 | bSig1) == 0) { - if ((aExp | aSig0 | aSig1) == 0) { - float_raise(status, float_flag_invalid); - return float128_default_nan; - } - float_raise(status, float_flag_divbyzero); - return packFloat128Four(zSign, 0x7FFF, 0, 0); - } - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1); - } - if (aExp == 0) { - if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1); - } - zExp = aExp - bExp + 0x3FFD; - shortShift128Left( - aSig0 | BX_CONST64(0x0001000000000000), aSig1, 15, &aSig0, &aSig1); - shortShift128Left( - bSig0 | BX_CONST64(0x0001000000000000), bSig1, 15, &bSig0, &bSig1); - if (le128(bSig0, bSig1, aSig0, aSig1)) { - shift128Right(aSig0, aSig1, 1, &aSig0, &aSig1); - ++zExp; - } - zSig0 = estimateDiv128To64(aSig0, aSig1, bSig0); - mul128By64To192(bSig0, bSig1, zSig0, &term0, &term1, &term2); - sub192(aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2); - while ((Bit64s) rem0 < 0) { - --zSig0; - add192(rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2); - } - zSig1 = estimateDiv128To64(rem1, rem2, bSig0); - if ((zSig1 & 0x3FFF) <= 4) { - mul128By64To192(bSig0, bSig1, zSig1, &term1, &term2, &term3); - sub192(rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3); - while ((Bit64s) rem1 < 0) { - --zSig1; - add192(rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3); - } - zSig1 |= ((rem1 | rem2 | rem3) != 0); - } - shift128ExtraRightJamming(zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2); - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit two's complement integer `a' to -| the quadruple-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 int64_to_float128(Bit64s a) -{ - Bit64u zSig0, zSig1; - - if (a == 0) return packFloat128Four(0, 0, 0, 0); - int zSign = (a < 0); - Bit64u absA = zSign ? - a : a; - Bit8u shiftCount = countLeadingZeros64(absA) + 49; - Bit32s zExp = 0x406E - shiftCount; - if (64 <= shiftCount) { - zSig1 = 0; - zSig0 = absA; - shiftCount -= 64; - } - else { - zSig1 = absA; - zSig0 = 0; - } - shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1); - return packFloat128Four(zSign, zExp, zSig0, zSig1); -} - -#endif diff --git a/src/cpu/softfloat/softfloat.h b/src/cpu/softfloat/softfloat.h deleted file mode 100644 index 1d1b0f08f..000000000 --- a/src/cpu/softfloat/softfloat.h +++ /dev/null @@ -1,488 +0,0 @@ -/*============================================================================ -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "config.h" /* generated by configure script from config.h.in */ - -#ifndef _SOFTFLOAT_H_ -#define _SOFTFLOAT_H_ - -#define FLOAT16 -#define FLOATX80 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ -#ifdef FLOAT16 -typedef Bit16u float16; -#endif -typedef Bit32u float32; -typedef Bit64u float64; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point class. -*----------------------------------------------------------------------------*/ -typedef enum { - float_zero, - float_SNaN, - float_QNaN, - float_negative_inf, - float_positive_inf, - float_denormal, - float_normalized -} float_class_t; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point NaN operands handling mode. -*----------------------------------------------------------------------------*/ -enum float_nan_handling_mode_t { - float_larger_significand_nan = 0, // this mode used by x87 FPU - float_first_operand_nan = 1 // this mode used by SSE -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -enum float_round_t { - float_round_nearest_even = 0, - float_round_down = 1, - float_round_up = 2, - float_round_to_zero = 3 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ -enum float_exception_flag_t { - float_flag_invalid = 0x01, - float_flag_denormal = 0x02, - float_flag_divbyzero = 0x04, - float_flag_overflow = 0x08, - float_flag_underflow = 0x10, - float_flag_inexact = 0x20 -}; - -extern const unsigned float_all_exceptions_mask; - -#ifdef FLOATX80 -#define RAISE_SW_C1 0x0200 -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point ordering relations -*----------------------------------------------------------------------------*/ -enum { - float_relation_less = -1, - float_relation_equal = 0, - float_relation_greater = 1, - float_relation_unordered = 2 -}; - -/*---------------------------------------------------------------------------- -| Options to indicate which negations to perform in float*_muladd() -| Using these differs from negating an input or output before calling -| the muladd function in that this means that a NaN doesn't have its -| sign bit inverted before it is propagated. -*----------------------------------------------------------------------------*/ -enum { - float_muladd_negate_c = 1, - float_muladd_negate_product = 2, - float_muladd_negate_result = float_muladd_negate_c | float_muladd_negate_product -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point status structure. -*----------------------------------------------------------------------------*/ -struct float_status_t -{ -#ifdef FLOATX80 - int float_rounding_precision; /* floatx80 only */ -#endif - int float_rounding_mode; - int float_exception_flags; - int float_exception_masks; - int float_suppress_exception; - int float_nan_handling_mode; /* flag register */ - int flush_underflow_to_zero; /* flag register */ - int denormals_are_zeros; /* flag register */ -}; - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software IEC/IEEE floating-point -| exception flags. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void float_raise(struct float_status_t *status, int flags) -{ - status->float_exception_flags |= flags; -} - -/*---------------------------------------------------------------------------- -| Returns raised IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_exception_flags(const struct float_status_t *status) -{ - return status->float_exception_flags & ~status->float_suppress_exception; -} - -/*---------------------------------------------------------------------------- -| Routine to check if any or all of the software IEC/IEEE floating-point -| exceptions are masked. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int float_exception_masked(const struct float_status_t *status, int flag) -{ - return status->float_exception_masks & flag; -} - -/*---------------------------------------------------------------------------- -| Returns current floating point rounding mode specified by status word. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_float_rounding_mode(const struct float_status_t *status) -{ - return status->float_rounding_mode; -} - -/*---------------------------------------------------------------------------- -| Returns current floating point precision (floatx80 only). -*----------------------------------------------------------------------------*/ - -#ifdef FLOATX80 -BX_CPP_INLINE int get_float_rounding_precision(const struct float_status_t *status) -{ - return status->float_rounding_precision; -} -#endif - -/*---------------------------------------------------------------------------- -| Returns current floating point NaN operands handling mode specified -| by status word. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_float_nan_handling_mode(const struct float_status_t *status) -{ - return status->float_nan_handling_mode; -} - -/*---------------------------------------------------------------------------- -| Raise floating point precision lost up flag (floatx80 only). -*----------------------------------------------------------------------------*/ - -#ifdef FLOATX80 -BX_CPP_INLINE void set_float_rounding_up(struct float_status_t *status) -{ - status->float_exception_flags |= RAISE_SW_C1; -} -#endif - -/*---------------------------------------------------------------------------- -| Returns 1 if the feature is supported; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_denormals_are_zeros(const struct float_status_t *status) -{ - return status->denormals_are_zeros; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the feature is supported; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_flush_underflow_to_zero(const struct float_status_t *status) -{ - return status->flush_underflow_to_zero; -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32(Bit32s, struct float_status_t *status); -float64 int32_to_float64(Bit32s); -float32 int64_to_float32(Bit64s, struct float_status_t *status); -float64 int64_to_float64(Bit64s, struct float_status_t *status); - -float32 uint32_to_float32(Bit32u, struct float_status_t *status); -float64 uint32_to_float64(Bit32u); -float32 uint64_to_float32(Bit64u, struct float_status_t *status); -float64 uint64_to_float64(Bit64u, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -Bit32s float32_to_int32(float32, struct float_status_t *status); -Bit32s float32_to_int32_round_to_zero(float32, struct float_status_t *status); -Bit64s float32_to_int64(float32, struct float_status_t *status); -Bit64s float32_to_int64_round_to_zero(float32, struct float_status_t *status); -Bit32u float32_to_uint32(float32, struct float_status_t *status); -Bit32u float32_to_uint32_round_to_zero(float32, struct float_status_t *status); -Bit64u float32_to_uint64(float32, struct float_status_t *status); -Bit64u float32_to_uint64_round_to_zero(float32, struct float_status_t *status); -float64 float32_to_float64(float32, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int(float32, Bit8u scale, struct float_status_t *status); -float32 float32_add(float32, float32, struct float_status_t *status); -float32 float32_sub(float32, float32, struct float_status_t *status); -float32 float32_mul(float32, float32, struct float_status_t *status); -float32 float32_div(float32, float32, struct float_status_t *status); -float32 float32_sqrt(float32, struct float_status_t *status); -float32 float32_frc(float32, struct float_status_t *status); -float32 float32_muladd(float32, float32, float32, int flags, struct float_status_t *status); -float32 float32_scalef(float32, float32, struct float_status_t *status); -int float32_compare(float32, float32, int quiet, struct float_status_t *status); - -BX_CPP_INLINE float32 float32_round_to_int_one(float32 a, struct float_status_t *status) -{ - return float32_round_to_int(a, 0, status); -} - -BX_CPP_INLINE float32 float32_fmadd(float32 a, float32 b, float32 c, struct float_status_t *status) -{ - return float32_muladd(a, b, c, 0, status); -} - -BX_CPP_INLINE float32 float32_fmsub(float32 a, float32 b, float32 c, struct float_status_t *status) -{ - return float32_muladd(a, b, c, float_muladd_negate_c, status); -} - -BX_CPP_INLINE float32 float32_fnmadd(float32 a, float32 b, float32 c, struct float_status_t *status) -{ - return float32_muladd(a, b, c, float_muladd_negate_product, status); -} - -BX_CPP_INLINE float32 float32_fnmsub(float32 a, float32 b, float32 c, struct float_status_t *status) -{ - return float32_muladd(a, b, c, float_muladd_negate_result, status); -} - -BX_CPP_INLINE int float32_compare_two(float32 a, float32 b, struct float_status_t *status) -{ - return float32_compare(a, b, 0, status); -} - -BX_CPP_INLINE int float32_compare_quiet(float32 a, float32 b, struct float_status_t *status) -{ - return float32_compare(a, b, 1, status); -} - -float_class_t float32_class(float32); - -float32 float32_min(float32 a, float32 b, struct float_status_t *status); -float32 float32_max(float32 a, float32 b, struct float_status_t *status); - -float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status); -float32 float32_getexp(float32 a, struct float_status_t *status); -float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -Bit32s float64_to_int32(float64, struct float_status_t *status); -Bit32s float64_to_int32_round_to_zero(float64, struct float_status_t *status); -Bit64s float64_to_int64(float64, struct float_status_t *status); -Bit64s float64_to_int64_round_to_zero(float64, struct float_status_t *status); -Bit32u float64_to_uint32(float64, struct float_status_t *status); -Bit32u float64_to_uint32_round_to_zero(float64, struct float_status_t *status); -Bit64u float64_to_uint64(float64, struct float_status_t *status); -Bit64u float64_to_uint64_round_to_zero(float64, struct float_status_t *status); -float32 float64_to_float32(float64, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -float64 float64_round_to_int(float64, Bit8u scale, struct float_status_t *status); -float64 float64_add(float64, float64, struct float_status_t *status); -float64 float64_sub(float64, float64, struct float_status_t *status); -float64 float64_mul(float64, float64, struct float_status_t *status); -float64 float64_div(float64, float64, struct float_status_t *status); -float64 float64_sqrt(float64, struct float_status_t *status); -float64 float64_frc(float64, struct float_status_t *status); -float64 float64_muladd(float64, float64, float64, int flags, struct float_status_t *status); -float64 float64_scalef(float64, float64, struct float_status_t *status); -int float64_compare(float64, float64, int quiet, struct float_status_t *status); - -BX_CPP_INLINE float64 float64_round_to_int_one(float64 a, struct float_status_t *status) -{ - return float64_round_to_int(a, 0, status); -} - -BX_CPP_INLINE float64 float64_fmadd(float64 a, float64 b, float64 c, struct float_status_t *status) -{ - return float64_muladd(a, b, c, 0, status); -} - -BX_CPP_INLINE float64 float64_fmsub(float64 a, float64 b, float64 c, struct float_status_t *status) -{ - return float64_muladd(a, b, c, float_muladd_negate_c, status); -} - -BX_CPP_INLINE float64 float64_fnmadd(float64 a, float64 b, float64 c, struct float_status_t *status) -{ - return float64_muladd(a, b, c, float_muladd_negate_product, status); -} - -BX_CPP_INLINE float64 float64_fnmsub(float64 a, float64 b, float64 c, struct float_status_t *status) -{ - return float64_muladd(a, b, c, float_muladd_negate_result, status); -} - -BX_CPP_INLINE int float64_compare_two(float64 a, float64 b, struct float_status_t *status) -{ - return float64_compare(a, b, 0, status); -} - -BX_CPP_INLINE int float64_compare_quiet(float64 a, float64 b, struct float_status_t *status) -{ - return float64_compare(a, b, 1, status); -} - -float_class_t float64_class(float64); - -float64 float64_min(float64 a, float64 b, struct float_status_t *status); -float64 float64_max(float64 a, float64 b, struct float_status_t *status); - -float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status); -float64 float64_getexp(float64 a, struct float_status_t *status); -float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv); - -#ifdef FLOAT16 -float32 float16_to_float32(float16, struct float_status_t *status); -float16 float32_to_float16(float32, struct float_status_t *status); - -float_class_t float16_class(float16); -#endif - -#ifdef FLOATX80 -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ - -#ifdef BX_BIG_ENDIAN -typedef struct floatx80 { // leave alignment to compiler - Bit16u exp; - Bit64u fraction; -}; floatx80 -#else -typedef struct floatx80 { - Bit64u fraction; - Bit16u exp; -} floatx80; -#endif - -#ifdef __cplusplus -extern "C" { -#endif -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -floatx80 int32_to_floatx80(Bit32s); -floatx80 int64_to_floatx80(Bit64s); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -floatx80 float32_to_floatx80(float32, struct float_status_t *status); -floatx80 float64_to_floatx80(float64, struct float_status_t *status); - -Bit32s floatx80_to_int32(floatx80, struct float_status_t *status); -Bit32s floatx80_to_int32_round_to_zero(floatx80, struct float_status_t *status); -Bit64s floatx80_to_int64(floatx80, struct float_status_t *status); -Bit64s floatx80_to_int64_round_to_zero(floatx80, struct float_status_t *status); - -float32 floatx80_to_float32(floatx80, struct float_status_t *status); -float64 floatx80_to_float64(floatx80, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int(floatx80, struct float_status_t *status); -floatx80 floatx80_add(floatx80, floatx80, struct float_status_t *status); -floatx80 floatx80_sub(floatx80, floatx80, struct float_status_t *status); -floatx80 floatx80_mul(floatx80, floatx80, struct float_status_t *status); -floatx80 floatx80_div(floatx80, floatx80, struct float_status_t *status); -floatx80 floatx80_sqrt(floatx80, struct float_status_t *status); - -float_class_t floatx80_class(floatx80); -#ifdef __cplusplus -} -#endif -#endif /* FLOATX80 */ - -#ifdef FLOAT128 - -#ifdef BX_BIG_ENDIAN -typedef struct float128 { - Bit64u hi, lo; -} float128; -#else -typedef struct float128 { - Bit64u lo, hi; -} float128; -#endif - -#ifdef __cplusplus -extern "C" { -#endif -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision conversion routines. -*----------------------------------------------------------------------------*/ -float128 floatx80_to_float128(floatx80 a, struct float_status_t *status); -floatx80 float128_to_floatx80(float128 a, struct float_status_t *status); - -float128 int64_to_float128(Bit64s a); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision operations. -*----------------------------------------------------------------------------*/ -float128 float128_add(float128 a, float128 b, struct float_status_t *status); -float128 float128_sub(float128 a, float128 b, struct float_status_t *status); -float128 float128_mul(float128 a, float128 b, struct float_status_t *status); -float128 float128_div(float128 a, float128 b, struct float_status_t *status); -#ifdef __cplusplus -} -#endif -#endif /* FLOAT128 */ - -#endif diff --git a/src/cpu/softfloat/softfloat16.cc b/src/cpu/softfloat/softfloat16.cc deleted file mode 100644 index 8c17d3a86..000000000 --- a/src/cpu/softfloat/softfloat16.cc +++ /dev/null @@ -1,129 +0,0 @@ -/*============================================================================ -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Adapted for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include "softfloat.h" - -#ifdef FLOAT16 - -#include "softfloat-round-pack.h" -#include "softfloat-specialize.h" -#include "softfloat-macros.h" - -/*---------------------------------------------------------------------------- -| Determine half-precision floating-point number class -*----------------------------------------------------------------------------*/ - -float_class_t float16_class(float16 a) -{ - Bit16s aExp = extractFloat16Exp(a); - Bit16u aSig = extractFloat16Frac(a); - int aSign = extractFloat16Sign(a); - - if(aExp == 0x1F) { - if (aSig == 0) - return (aSign) ? float_negative_inf : float_positive_inf; - - return (aSig & 0x200) ? float_QNaN : float_SNaN; - } - - if(aExp == 0) { - if (aSig == 0) return float_zero; - return float_denormal; - } - - return float_normalized; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the half-precision floating-point value -| `a' to the single-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float16_to_float32(float16 a, struct float_status_t *status) -{ - Bit16u aSig = extractFloat16Frac(a); - Bit16s aExp = extractFloat16Exp(a); - int aSign = extractFloat16Sign(a); - - if (aExp == 0x1F) { - if (aSig) return commonNaNToFloat32(float16ToCommonNaN(a, status)); - return packFloat32(aSign, 0xFF, 0); - } - if (aExp == 0) { - // ignore denormals_are_zeros flag - if (aSig == 0) return packFloat32(aSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloat16Subnormal(aSig, &aExp, &aSig); - --aExp; - } - - return packFloat32(aSign, aExp + 0x70, ((Bit32u) aSig)<<13); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the half-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float16 float32_to_float16(float32 a, struct float_status_t *status) -{ - Bit32u aSig = extractFloat32Frac(a); - Bit16s aExp = extractFloat32Exp(a); - int aSign = extractFloat32Sign(a); - - if (aExp == 0xFF) { - if (aSig) return commonNaNToFloat16(float32ToCommonNaN(a, status)); - return packFloat16(aSign, 0x1F, 0); - } - if (aExp == 0) { - if (get_denormals_are_zeros(status)) aSig = 0; - if (aSig == 0) return packFloat16(aSign, 0, 0); - float_raise(status, float_flag_denormal); - } - - aSig = shift32RightJamming(aSig, 9); - Bit16u zSig = (Bit16u) aSig; - if (aExp || zSig) { - zSig |= 0x4000; - aExp -= 0x71; - } - - return roundAndPackFloat16(aSign, aExp, zSig, status); -} - -#endif diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc deleted file mode 100644 index fc2409601..000000000 --- a/src/cpu/softfloat/softfloatx80.cc +++ /dev/null @@ -1,384 +0,0 @@ -/*============================================================================ -This source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator) -floating point emulation. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Written for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#include -#include -#include <86box/86box.h> -#include "../cpu.h" - -#include "softfloatx80.h" -#include "softfloat-round-pack.h" -#include "softfloat-macros.h" - -const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); -const floatx80 Const_Z = packFloatx80(0, 0x0000, 0); -const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000)); -const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe)); -const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc)); -const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235)); -const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799)); -const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac)); -const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000)); - -/*---------------------------------------------------------------------------- -| Commonly used single-precision floating point constants -*----------------------------------------------------------------------------*/ -const float32 float32_negative_inf = 0xff800000; -const float32 float32_positive_inf = 0x7f800000; -const float32 float32_negative_zero = 0x80000000; -const float32 float32_positive_zero = 0x00000000; -const float32 float32_negative_one = 0xbf800000; -const float32 float32_positive_one = 0x3f800000; -const float32 float32_max_float = 0x7f7fffff; -const float32 float32_min_float = 0xff7fffff; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -const float32 float32_default_nan = 0xffc00000; - -/*---------------------------------------------------------------------------- -| Commonly used single-precision floating point constants -*----------------------------------------------------------------------------*/ -const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000); -const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000); -const float64 float64_negative_zero = BX_CONST64(0x8000000000000000); -const float64 float64_positive_zero = BX_CONST64(0x0000000000000000); -const float64 float64_negative_one = BX_CONST64(0xbff0000000000000); -const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000); -const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff); -const float64 float64_min_float = BX_CONST64(0xffefffffffffffff); - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000); - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 16-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic - which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN or the -| conversion overflows, the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit16s floatx80_to_int16(floatx80 a, struct float_status_t *status) -{ - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); - return int16_indefinite; - } - - Bit32s v32 = floatx80_to_int32(a, status); - - if ((v32 > 32767) || (v32 < -32768)) { - status->float_exception_flags = float_flag_invalid; // throw away other flags - return int16_indefinite; - } - - return (Bit16s) v32; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 16-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN or the conversion overflows, the integer -| indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit16s floatx80_to_int16_round_to_zero(floatx80 a, struct float_status_t *status) -{ - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); - return int16_indefinite; - } - - Bit32s v32 = floatx80_to_int32_round_to_zero(a, status); - - if ((v32 > 32767) || (v32 < -32768)) { - status->float_exception_flags = float_flag_invalid; // throw away other flags - return int16_indefinite; - } - - return (Bit16s) v32; -} - -/*---------------------------------------------------------------------------- -| Separate the source extended double-precision floating point value `a' -| into its exponent and significand, store the significant back to the -| 'a' and return the exponent. The operation performed is a superset of -| the IEC/IEEE recommended logb(x) function. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - Bit64u aSig = extractFloatx80Frac(*a); - Bit32s aExp = extractFloatx80Exp(*a); - int aSign = extractFloatx80Sign(*a); - - if (floatx80_is_unsupported(*a)) - { - float_raise(status, float_flag_invalid); - *a = floatx80_default_nan; - return *a; - } - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - { - *a = propagateFloatx80NaNOne(*a, status); - return *a; - } - return packFloatx80(0, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) - { - if (aSig == 0) { - float_raise(status, float_flag_divbyzero); - *a = packFloatx80(aSign, 0, 0); - return packFloatx80(1, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - a->exp = (aSign << 15) + 0x3FFF; - a->fraction = aSig; - return int32_to_floatx80(aExp - 0x3FFF); -} - -/*---------------------------------------------------------------------------- -| Scales extended double-precision floating-point value in operand `a' by -| value `b'. The function truncates the value in the second operand 'b' to -| an integral value and adds that value to the exponent of the operand 'a'. -| The operation performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status) -{ -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - - Bit32s aExp, bExp; - Bit64u aSig, bSig; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) - { - return propagateFloatx80NaN(a, b, status); - } - if ((bExp == 0x7FFF) && bSign) { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return a; - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if ((aExp | aSig) == 0) { - if (! bSign) { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - return a; - } - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - if (bSign) return packFloatx80(aSign, 0, 0); - return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (aExp == 0) { - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - if (aSig == 0) return a; - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - if (bExp < 0x3FFF) - return normalizeRoundAndPackFloatx80(80, aSign, aExp, aSig, 0, status); - } - if (bExp == 0) { - if (bSig == 0) return a; - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - - if (bExp > 0x400E) { - /* generate appropriate overflow/underflow */ - return roundAndPackFloatx80(80, aSign, - bSign ? -0x3FFF : 0x7FFF, aSig, 0, status); - } - - if (bExp < 0x3FFF) return a; - - int shiftCount = 0x403E - bExp; - bSig >>= shiftCount; - Bit32s scale = (Bit32s) bSig; - if (bSign) scale = -scale; /* -32768..32767 */ - return - roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status); -} - -/*---------------------------------------------------------------------------- -| Determine extended-precision floating-point number class. -*----------------------------------------------------------------------------*/ - -float_class_t floatx80_class(floatx80 a) -{ - Bit32s aExp = extractFloatx80Exp(a); - Bit64u aSig = extractFloatx80Frac(a); - - if(aExp == 0) { - if (aSig == 0) - return float_zero; - - /* denormal or pseudo-denormal */ - return float_denormal; - } - - /* valid numbers have the MS bit set */ - if (!(aSig & BX_CONST64(0x8000000000000000))) - return float_SNaN; /* report unsupported as SNaNs */ - - if(aExp == 0x7fff) { - int aSign = extractFloatx80Sign(a); - - if (((Bit64u) (aSig<< 1)) == 0) - return (aSign) ? float_negative_inf : float_positive_inf; - - return (aSig & BX_CONST64(0x4000000000000000)) ? float_QNaN : float_SNaN; - } - - return float_normalized; -} - -/*---------------------------------------------------------------------------- -| Compare between two extended precision floating point numbers. Returns -| 'float_relation_equal' if the operands are equal, 'float_relation_less' if -| the value 'a' is less than the corresponding value `b', -| 'float_relation_greater' if the value 'a' is greater than the corresponding -| value `b', or 'float_relation_unordered' otherwise. -*----------------------------------------------------------------------------*/ - -int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *status) -{ - float_class_t aClass = floatx80_class(a); - float_class_t bClass = floatx80_class(b); - - if (fpu_type < FPU_287XL) { - if ((aClass == float_positive_inf) && (bClass == float_negative_inf)) - { - return float_relation_equal; - } - - if ((aClass == float_negative_inf) && (bClass == float_positive_inf)) - { - return float_relation_equal; - } - } - - if (aClass == float_SNaN || bClass == float_SNaN) - { - /* unsupported reported as SNaN */ - float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_QNaN || bClass == float_QNaN) { - if (! quiet) float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_denormal || bClass == float_denormal) { - float_raise(status, float_flag_denormal); - } - - int aSign = extractFloatx80Sign(a); - int bSign = extractFloatx80Sign(b); - - if (aClass == float_zero) { - if (bClass == float_zero) return float_relation_equal; - return bSign ? float_relation_greater : float_relation_less; - } - - if (bClass == float_zero || aSign != bSign) { - return aSign ? float_relation_less : float_relation_greater; - } - - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - Bit64u bSig = extractFloatx80Frac(b); - Bit32s bExp = extractFloatx80Exp(b); - - if (aClass == float_denormal) - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - - if (bClass == float_denormal) - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - - if (aExp == bExp && aSig == bSig) - return float_relation_equal; - - int less_than = - aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig))) - : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig))); - - if (less_than) return float_relation_less; - return float_relation_greater; -} - - -int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status) -{ - return floatx80_compare(a, b, 0, status); -} - -int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status) -{ - return floatx80_compare(a, b, 1, status); -} diff --git a/src/cpu/softfloat/softfloatx80.h b/src/cpu/softfloat/softfloatx80.h deleted file mode 100644 index 1f96141b4..000000000 --- a/src/cpu/softfloat/softfloatx80.h +++ /dev/null @@ -1,121 +0,0 @@ -/*============================================================================ -This source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator) -floating point emulation. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Written for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#ifndef _SOFTFLOATX80_EXTENSIONS_H_ -#define _SOFTFLOATX80_EXTENSIONS_H_ - -#include "softfloat.h" -#include "softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" { -#endif - -Bit16s floatx80_to_int16(floatx80, struct float_status_t *status); -Bit16s floatx80_to_int16_round_to_zero(floatx80, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status); -floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status); -int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status); -int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status); -floatx80 f2xm1(floatx80 a, struct float_status_t *status); -floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status); -floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status); -floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision trigonometric functions. -*----------------------------------------------------------------------------*/ - -int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status); -int fsin(floatx80 *a, struct float_status_t *status); -int fcos(floatx80 *a, struct float_status_t *status); -int ftan(floatx80 *a, struct float_status_t *status); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision compare. -*----------------------------------------------------------------------------*/ - -int floatx80_compare(floatx80, floatx80, int quiet, struct float_status_t *status); -int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status); -int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status); - -#ifdef __cplusplus -} -#endif - -/*----------------------------------------------------------------------------- -| Calculates the absolute value of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -BX_CPP_INLINE floatx80& floatx80_abs(floatx80 ®) -#else -BX_CPP_INLINE floatx80 floatx80_abs(floatx80 reg) -#endif -{ - reg.exp &= 0x7FFF; - return reg; -} - -/*----------------------------------------------------------------------------- -| Changes the sign of the extended double-precision floating-point value 'a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -BX_CPP_INLINE floatx80& floatx80_chs(floatx80 ®) -#else -BX_CPP_INLINE floatx80 floatx80_chs(floatx80 reg) -#endif -{ - reg.exp ^= 0x8000; - return reg; -} - -/*----------------------------------------------------------------------------- -| Commonly used extended double-precision floating-point constants. -*----------------------------------------------------------------------------*/ - -extern const floatx80 Const_Z; -extern const floatx80 Const_1; -extern const floatx80 Const_L2T; -extern const floatx80 Const_L2E; -extern const floatx80 Const_PI; -extern const floatx80 Const_LG2; -extern const floatx80 Const_LN2; -extern const floatx80 Const_INF; -#endif diff --git a/src/cpu/softfloat3e/CMakeLists.txt b/src/cpu/softfloat3e/CMakeLists.txt new file mode 100644 index 000000000..5565460c8 --- /dev/null +++ b/src/cpu/softfloat3e/CMakeLists.txt @@ -0,0 +1,56 @@ +# +# 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. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020-2021 David Hrdlička. +# + +add_library(softfloat3e OBJECT extF80_addsub.cc extF80_class.cc extF80_compare.cc + extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc + extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc + extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc + extF80_to_i64_r_minMag.cc extF80_to_ui32.cc extF80_to_ui32_r_minMag.cc extF80_to_ui64.cc + extF80_to_ui64_r_minMag.cc f16_addsub.c f16_class.c f16_compare.c f16_div.c f16_getExp.c + f16_getMant.c f16_minmax.c f16_mul.c f16_mulAdd.c f16_range.c f16_roundToInt.c + f16_sqrt.c f16_to_extF80.cc f16_to_f32.c f16_to_f64.c f16_to_i32.c f16_to_i32_r_minMag.c + f16_to_i64.c f16_to_i64_r_minMag.c f16_to_ui32.c f16_to_ui32_r_minMag.c f16_to_ui64.c + f16_to_ui64_r_minMag.c f32_addsub.c f32_class.c f32_compare.c f32_div.c f32_frc.c + f32_getExp.c f32_getMant.c f32_minmax.c f32_mul.c f32_mulAdd.c f32_range.c + f32_roundToInt.c f32_scalef.c f32_sqrt.c f32_to_extF80.cc f32_to_f16.c f32_to_f64.c + f32_to_f128.cc f32_to_i32.c f32_to_i32_r_minMag.c f32_to_i64.c f32_to_i64_r_minMag.c + f32_to_ui32.c f32_to_ui32_r_minMag.c f32_to_ui64.c f32_to_ui64_r_minMag.c f64_addsub.c + f64_class.c f64_compare.c f64_div.c f64_frc.c f64_getExp.c f64_getMant.c f64_minmax.c + f64_mul.c f64_mulAdd.c f64_range.c f64_roundToInt.c f64_scalef.c f64_sqrt.c f64_to_extF80.cc + f64_to_f16.c f64_to_f32.c f64_to_f128.cc f64_to_i32.c f64_to_i32_r_minMag.c f64_to_i64.c + f64_to_i64_r_minMag.c f64_to_ui32.c f64_to_ui32_r_minMag.c f64_to_ui64.c f64_to_ui64_r_minMag.c + f128_addsub.cc f128_div.cc f128_mul.cc f128_mulAdd.cc f128_roundToInt.cc f128_to_extF80.cc + f128_to_f32.cc f128_to_f64.cc f128_to_i32.cc f128_to_i32_r_minMag.cc f128_to_i64.cc + f128_to_i64_r_minMag.cc f128_to_ui32.cc f128_to_ui32_r_minMag.cc f128_to_ui64.cc + f128_to_ui64_r_minMag.cc i32_to_extF80.cc i32_to_f16.c i32_to_f32.c i32_to_f64.c + i32_to_f128.cc i64_to_extF80.cc i64_to_f16.c i64_to_f32.c i64_to_f64.c i64_to_f128.cc + isNaN.cc isSignalingNaN.cc s_add128.cc s_add256M.c s_addMagsExtF80.cc s_addMagsF16.c + s_addMagsF32.c s_addMagsF64.c s_addMagsF128.cc s_approxRecip_1Ks.c s_approxRecipSqrt_1Ks.c + s_approxRecipSqrt32_1.c s_commonNaNToExtF80UI.cc s_commonNaNToF16UI.c s_commonNaNToF32UI.c + s_commonNaNToF64UI.c s_commonNaNToF128UI.cc s_countLeadingZeros8.c s_countLeadingZeros16.c + s_countLeadingZeros32.c s_countLeadingZeros64.c s_eq128.c s_le128.c s_lt128.c + s_mul64ByShifted32To128.cc s_mul64To128.cc s_mul128By32.cc s_mul128To256M.cc + s_normRoundPackToExtF80.cc s_normRoundPackToF16.c s_normRoundPackToF32.c s_normRoundPackToF64.c + s_normRoundPackToF128.cc s_normSubnormalExtF80Sig.cc s_normSubnormalF16Sig.c + s_normSubnormalF32Sig.c s_normSubnormalF64Sig.c s_normSubnormalF128Sig.cc s_packToExtF80.cc + s_propagateNaNExtF80UI.cc s_propagateNaNF16UI.c s_propagateNaNF32UI.c s_propagateNaNF64UI.c + s_propagateNaNF128UI.cc s_roundPackToExtF80.cc s_roundPackToF16.c s_roundPackToF32.c + s_roundPackToF64.c s_roundPackToF128.cc s_roundToI32.c s_roundToI64.c s_roundToUI32.c + s_roundToUI64.c s_shiftRightJam32.c s_shiftRightJam64.c s_shiftRightJam64Extra.c + s_shiftRightJam256M.c s_shortShiftLeft128.cc s_shortShiftRight128.cc s_shortShiftRightJam64.c + s_shortShiftRightJam64Extra.c s_sub128.cc s_sub256M.c s_subMagsExtF80.cc s_subMagsF16.c + s_subMagsF32.c s_subMagsF64.c s_subMagsF128.cc ui32_to_extF80.cc ui32_to_f16.c ui32_to_f32.c + ui32_to_f64.c ui32_to_f128.cc ui64_to_extF80.cc ui64_to_f16.c ui64_to_f32.c ui64_to_f64.c + ui64_to_f128.cc f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc poly.cc consts.cc) \ No newline at end of file diff --git a/src/cpu/softfloat3e/COPYING.txt b/src/cpu/softfloat3e/COPYING.txt new file mode 100644 index 000000000..b5690face --- /dev/null +++ b/src/cpu/softfloat3e/COPYING.txt @@ -0,0 +1,37 @@ + +License for Berkeley SoftFloat Release 3e + +John R. Hauser +2018 January 20 + +The following applies to the whole of SoftFloat Release 3e as well as to +each source file individually. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/src/cpu/softfloat3e/README.html b/src/cpu/softfloat3e/README.html new file mode 100644 index 000000000..e695c2bd8 --- /dev/null +++ b/src/cpu/softfloat3e/README.html @@ -0,0 +1,49 @@ + + + + +Berkeley SoftFloat Package Overview + + + + +

Package Overview for Berkeley SoftFloat Release 3e

+ +

+John R. Hauser
+2018 January 20
+

+ +

+Berkeley SoftFloat is a software implementation of binary floating-point that +conforms to the IEEE Standard for Floating-Point Arithmetic. +SoftFloat is distributed in the form of C source code. +Building the SoftFloat sources generates a library file (typically +softfloat.a or libsoftfloat.a) containing the +floating-point subroutines. +

+ +

+The SoftFloat package is documented in the following files in the +doc subdirectory: +

+ + + + + + + + + + + + + +
SoftFloat.htmlDocumentation for using the SoftFloat functions.
SoftFloat-source.htmlDocumentation for building SoftFloat.
SoftFloat-history.html   History of the major changes to SoftFloat.
+
+Other files in the package comprise the source code for SoftFloat. +

+ + + diff --git a/src/cpu/softfloat3e/README.txt b/src/cpu/softfloat3e/README.txt new file mode 100644 index 000000000..1613c7671 --- /dev/null +++ b/src/cpu/softfloat3e/README.txt @@ -0,0 +1,21 @@ + +Package Overview for Berkeley SoftFloat Release 3e + +John R. Hauser +2018 January 20 + +Berkeley SoftFloat is a software implementation of binary floating-point +that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat +is distributed in the form of C source code. Building the SoftFloat sources +generates a library file (typically "softfloat.a" or "libsoftfloat.a") +containing the floating-point subroutines. + +The SoftFloat package is documented in the following files in the "doc" +subdirectory: + + SoftFloat.html Documentation for using the SoftFloat functions. + SoftFloat-source.html Documentation for building SoftFloat. + SoftFloat-history.html History of the major changes to SoftFloat. + +Other files in the package comprise the source code for SoftFloat. + diff --git a/src/cpu/softfloat3e/config.h b/src/cpu/softfloat3e/config.h new file mode 100644 index 000000000..9febce242 --- /dev/null +++ b/src/cpu/softfloat3e/config.h @@ -0,0 +1,14 @@ +#ifndef EMU_SF_CONFIG_H +#define EMU_SF_CONFIG_H + +/*---------------------------------------------------------------------------- +| The `LIT64' macro takes as its argument a textual integer literal and +| if necessary ``marks'' the literal as having a 64-bit integer type. +| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +| appended with the letters `LL' standing for `long long', which is `gcc's +| name for the 64-bit integer type. Some compilers may allow `LIT64' to be +| defined as the identity macro: `#define LIT64( a ) a'. +*----------------------------------------------------------------------------*/ +#define BX_CONST64(a) a##LL + +#endif /*EMU_SF_CONFIG_H*/ diff --git a/src/cpu/softfloat3e/consts.cc b/src/cpu/softfloat3e/consts.cc new file mode 100644 index 000000000..235a03996 --- /dev/null +++ b/src/cpu/softfloat3e/consts.cc @@ -0,0 +1,51 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include <86box/86box.h> +#include "../cpu.h" + +#include "softfloat-specialize.h" + +const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +const floatx80 Const_Z = packFloatx80(0, 0x0000, 0); +const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000)); +const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe)); +const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc)); +const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235)); +const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799)); +const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac)); +const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000)); diff --git a/src/cpu/softfloat3e/doc/SoftFloat-history.html b/src/cpu/softfloat3e/doc/SoftFloat-history.html new file mode 100644 index 000000000..d81c6bc5a --- /dev/null +++ b/src/cpu/softfloat3e/doc/SoftFloat-history.html @@ -0,0 +1,258 @@ + + + + +Berkeley SoftFloat History + + + + +

History of Berkeley SoftFloat, to Release 3e

+ +

+John R. Hauser
+2018 January 20
+

+ + +

Release 3e (2018 January)

+ +
    + +
  • +Changed the default numeric code for optional rounding mode odd +(round to odd, also known as jamming) from 5 to 6. + +
  • +Modified the behavior of rounding mode odd when rounding to an +integer value (either conversion to an integer format or a +‘roundToInt’ function). +Previously, for those cases only, rounding mode odd acted the same +as rounding to minimum magnitude. +Now all operations are rounded consistently. + +
  • +Fixed some errors in the specialization code modeling Intel x86 floating-point, +specifically the integers returned on invalid operations and the propagation of +NaN payloads in a few rare cases. + +
  • +Added specialization code modeling ARM floating-point, conforming to VFPv2 or +later. + +
  • +Added an example target for ARM processors. + +
  • +Fixed a minor bug whereby function f16_to_ui64 might return a +different integer than expected in the case that the floating-point operand is +negative. + +
  • +Added example target-specific optimization for GCC, employing GCC instrinsics +and support for 128-bit integer arithmetic. + +
  • +Made other minor improvements. + +
+ + +

Release 3d (2017 August)

+ +
    + +
  • +Fixed bugs in the square root functions for 64-bit +double-precision, 80-bit double-extended-precision, and +128-bit quadruple-precision. +For 64-bit double-precision (f64_sqrt), the result +could sometimes be off by 1 unit in the last place +(1 ulp) from what it should be. +For the larger formats, the square root could be wrong in a large portion of +the less-significant bits. +(A bug in f128_sqrt was first reported by Alexei Sibidanov.) + +
+ + +

Release 3c (2017 February)

+ +
    + +
  • +Added optional rounding mode odd (round to odd, also known as +jamming). + +
  • +Corrected the documentation concerning non-canonical representations in +80-bit double-extended-precision. + +
+ + +

Release 3b (2016 July)

+ +
    + +
  • +Implemented the common 16-bit “half-precision” +floating-point format (float16_t). + +
  • +Made the integer values returned on invalid conversions to integer formats +be determined by the port-specific specialization instead of being the same for +all ports. + +
  • +Added preprocessor macro THREAD_LOCAL to allow the floating-point +state (modes and exception flags) to be made per-thread. + +
  • +Modified the provided Makefiles to allow some options to be overridden from the +make command. + +
  • +Made other minor improvements. + +
+ + +

Release 3a (2015 October)

+ +
    + +
  • +Replaced the license text supplied by the University of California, Berkeley. + +
+ + +

Release 3 (2015 February)

+ +
    + +
  • +Complete rewrite, funded by the University of California, Berkeley, and +consequently having a different use license than earlier releases. +Major changes included renaming most types and functions, upgrading some +algorithms, restructuring the source files, and making SoftFloat into a true +library. + +
  • +Added functions to convert between floating-point and unsigned integers, both +32-bit and 64-bit (uint32_t and +uint64_t). + +
  • +Added functions for fused multiply-add, for all supported floating-point +formats except 80-bit double-extended-precision. + +
  • +Added support for a fifth rounding mode, near_maxMag (round to +nearest, with ties to maximum magnitude, away from zero). + +
  • +Dropped the timesoftfloat program (now part of the Berkeley +TestFloat package). + +
+ + +

Release 2c (2015 January)

+ +
    + +
  • +Fixed mistakes affecting some 64-bit processors. + +
  • +Further improved the documentation and the wording for the legal restrictions +on using SoftFloat releases through 2c (not applicable to +Release 3 or later). + +
+ + +

Release 2b (2002 May)

+ +
    + +
  • +Made minor updates to the documentation, including improved wording for the +legal restrictions on using SoftFloat. + +
+ + +

Release 2a (1998 December)

+ +
    + +
  • +Added functions to convert between 64-bit integers +(int64) and all supported floating-point formats. + +
  • +Fixed a bug in all 64-bit-version square root functions except +float32_sqrt that caused the result sometimes to be off by +1 unit in the last place (1 ulp) from what it should +be. +(Bug discovered by Paul Donahue.) + +
  • +Improved the Makefiles. +
+ + +

Release 2 (1997 June)

+ +
    + +
  • +Created the 64-bit (bits64) version, adding the +floatx80 and float128 formats. + +
  • +Changed the source directory structure, splitting the sources into a +bits32 and a bits64 version. +Renamed environment.h to milieu.h to avoid confusion +with environment variables. + +
  • +Fixed a small error that caused float64_round_to_int often to +round the wrong way in nearest/even mode when the operand was between +220 and 221 and halfway between two integers. + +
+ + +

Release 1a (1996 July)

+ +
    + +
  • +Corrected a mistake that caused borderline underflow cases not to raise the +underflow flag when they should have. +(Problem reported by Doug Priest.) + +
  • +Added the float_detect_tininess variable to control whether +tininess is detected before or after rounding. + +
+ + +

Release 1 (1996 July)

+ +
    + +
  • +Original release, based on work done for the International Computer Science +Institute (ICSI) in Berkeley, California. + +
+ + + + diff --git a/src/cpu/softfloat3e/doc/SoftFloat-source.html b/src/cpu/softfloat3e/doc/SoftFloat-source.html new file mode 100644 index 000000000..4ff9d4c45 --- /dev/null +++ b/src/cpu/softfloat3e/doc/SoftFloat-source.html @@ -0,0 +1,686 @@ + + + + +Berkeley SoftFloat Source Documentation + + + + +

Berkeley SoftFloat Release 3e: Source Documentation

+ +

+John R. Hauser
+2018 January 20
+

+ + +

Contents

+ +
+ +++ + + + + + + + + + + + + + + + + + + + +
1. Introduction
2. Limitations
3. Acknowledgments and License
4. SoftFloat Package Directory Structure
5. Issues for Porting SoftFloat to a New Target
5.1. Standard Headers <stdbool.h> and + <stdint.h>
5.2. Specializing Floating-Point Behavior
5.3. Macros for Build Options
5.4. Adapting a Template Target Directory
5.5. Target-Specific Optimization of Primitive Functions
6. Testing SoftFloat
7. Providing SoftFloat as a Common Library for Applications
8. Contact Information
+
+ + +

1. Introduction

+ +

+This document gives information needed for compiling and/or porting Berkeley +SoftFloat, a library of C functions implementing binary floating-point +conforming to the IEEE Standard for Floating-Point Arithmetic. +For basic documentation about SoftFloat refer to +SoftFloat.html. +

+ +

+The source code for SoftFloat is intended to be relatively machine-independent +and should be compilable with any ISO-Standard C compiler that also supports +64-bit integers. +SoftFloat has been successfully compiled with the GNU C Compiler +(gcc) for several platforms. +

+ +

+Release 3 of SoftFloat was a complete rewrite relative to +Release 2 or earlier. +Changes to the interface of SoftFloat functions are documented in +SoftFloat.html. +The current version of SoftFloat is Release 3e. +

+ + +

2. Limitations

+ +

+SoftFloat assumes the computer has an addressable byte size of either 8 or +16 bits. +(Nearly all computers in use today have 8-bit bytes.) +

+ +

+SoftFloat is written in C and is designed to work with other C code. +The C compiler used must conform at a minimum to the 1989 ANSI standard for the +C language (same as the 1990 ISO standard) and must in addition support basic +arithmetic on 64-bit integers. +Earlier releases of SoftFloat included implementations of 32-bit +single-precision and 64-bit double-precision floating-point that +did not require 64-bit integers, but this option is not supported +starting with Release 3. +Since 1999, ISO standards for C have mandated compiler support for +64-bit integers. +A compiler conforming to the 1999 C Standard or later is recommended but not +strictly required. +

+ +

+C Standard header files <stdbool.h> and +<stdint.h> are required for defining standard Boolean and +integer types. +If these headers are not supplied with the C compiler, minimal substitutes must +be provided. +SoftFloat’s dependence on these headers is detailed later in +section 5.1, Standard Headers <stdbool.h> +and <stdint.h>. +

+ + +

3. Acknowledgments and License

+ +

+The SoftFloat package was written by me, John R. Hauser. +Release 3 of SoftFloat was a completely new implementation +supplanting earlier releases. +The project to create Release 3 (now through 3e) was +done in the employ of the University of California, Berkeley, within the +Department of Electrical Engineering and Computer Sciences, first for the +Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab. +The work was officially overseen by Prof. Krste Asanovic, with funding provided +by these sources: +

+ ++++ + + + + + + + + + +
Par Lab: +Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery +(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia, +NVIDIA, Oracle, and Samsung. +
ASPIRE Lab: +DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from +ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA, +Oracle, and Samsung. +
+
+

+ +

+The following applies to the whole of SoftFloat Release 3e as well +as to each source file individually. +

+ +

+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the +University of California. +All rights reserved. +

+ +

+Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +

    + +
  1. +

    +Redistributions of source code must retain the above copyright notice, this +list of conditions, and the following disclaimer. +

    + +
  2. +

    +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions, and the following disclaimer in the documentation and/or +other materials provided with the distribution. +

    + +
  3. +

    +Neither the name of the University nor the names of its contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. +

    + +
+

+ +

+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”, +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. +IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +

+ + +

4. SoftFloat Package Directory Structure

+ +

+Because SoftFloat is targeted to multiple platforms, its source code is +slightly scattered between target-specific and target-independent directories +and files. +The supplied directory structure is as follows: +

+
+doc
+source
+    include
+    8086
+    8086-SSE
+    ARM-VFPv2
+    ARM-VFPv2-defaultNaN
+build
+    template-FAST_INT64
+    template-not-FAST_INT64
+    Linux-386-GCC
+    Linux-386-SSE2-GCC
+    Linux-x86_64-GCC
+    Linux-ARM-VFPv2-GCC
+    Win32-MinGW
+    Win32-SSE2-MinGW
+    Win64-MinGW-w64
+
+
+The majority of the SoftFloat sources are provided in the source +directory. +The include subdirectory contains several header files +(unsurprisingly), while the other subdirectories of source contain +source files that specialize the floating-point behavior to match particular +processor families: +
+
+
8086
+
+Intel’s older, 8087-derived floating-point, extended to all supported +floating-point types +
+
8086-SSE
+
+Intel’s x86 processors with Streaming SIMD Extensions (SSE) and later +compatible extensions, having 8087 behavior for 80-bit +double-extended-precision (extFloat80_t) and SSE behavior for +other floating-point types +
+
ARM-VFPv2
+
+ARM’s VFPv2 or later floating-point, with NaN payload propagation +
+
ARM-VFPv2-defaultNaN
+
+ARM’s VFPv2 or later floating-point, with the “default NaN” +option +
+
+
+If other specializations are attempted, these would be expected to be other +subdirectories of source alongside the ones listed above. +Specialization is covered later, in section 5.2, Specializing +Floating-Point Behavior. +

+ +

+The build directory is intended to contain a subdirectory for each +target platform for which a build of the SoftFloat library may be created. +For each build target, the target’s subdirectory is where all derived +object files and the completed SoftFloat library (typically +softfloat.a or libsoftfloat.a) are created. +The two template subdirectories are not actual build targets but +contain sample files for creating new target directories. +(The meaning of FAST_INT64 will be explained later.) +

+ +

+Ignoring the template directories, the supplied target directories +are intended to follow a naming system of +<execution-environment>-<compiler>. +For the example targets, +<execution-environment> is +Linux-386, Linux-386-SSE2, +Linux-x86_64, +Linux-ARM-VFPv2, Win32, +Win32-SSE2, or Win64, and +<compiler> is GCC, +MinGW, or MinGW-w64. +

+ +

+All of the supplied target directories are merely examples that may or may not +be correct for compiling on any particular system. +Despite requests, there are currently no plans to include and maintain in the +SoftFloat package the build files needed for a great many users’ +compilation environments, which can span a huge range of operating systems, +compilers, and other tools. +

+ +

+As supplied, each target directory contains two files: +

+
+Makefile
+platform.h
+
+
+The provided Makefile is written for GNU make. +A build of SoftFloat for the specific target is begun by executing the +make command with the target directory as the current directory. +A completely different build tool can be used if an appropriate +Makefile equivalent is created. +

+ +

+The platform.h header file exists to provide a location for +additional C declarations specific to the build target. +Every C source file of SoftFloat contains a #include for +platform.h. +In many cases, the contents of platform.h can be as simple as one +or two lines of code. +At the other extreme, to get maximal performance from SoftFloat, it may be +desirable to include in header platform.h (directly or via +#include) declarations for numerous target-specific optimizations. +Such possibilities are discussed in the next section, Issues for Porting +SoftFloat to a New Target. +If the target’s compiler or library has bugs or other shortcomings, +workarounds for these issues may also be possible with target-specific +declarations in platform.h, avoiding the need to modify the main +SoftFloat sources. +

+ + +

5. Issues for Porting SoftFloat to a New Target

+ +

5.1. Standard Headers <stdbool.h> and <stdint.h>

+ +

+The SoftFloat sources make use of standard headers +<stdbool.h> and <stdint.h>, which have +been part of the ISO C Standard Library since 1999. +With any recent compiler, these standard headers are likely to be supported, +even if the compiler does not claim complete conformance to the latest ISO C +Standard. +For older or nonstandard compilers, substitutes for +<stdbool.h> and <stdint.h> may need to be +created. +SoftFloat depends on these names from <stdbool.h>: +

+
+bool
+true
+false
+
+
+and on these names from <stdint.h>: +
+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+UINT64_C
+INT64_C
+uint_least8_t
+uint_fast8_t
+uint_fast16_t
+uint_fast32_t
+uint_fast64_t
+int_fast8_t
+int_fast16_t
+int_fast32_t
+int_fast64_t
+
+
+

+ + +

5.2. Specializing Floating-Point Behavior

+ +

+The IEEE Floating-Point Standard allows for some flexibility in a conforming +implementation, particularly concerning NaNs. +The SoftFloat source directory is supplied with some +specialization subdirectories containing possible definitions for this +implementation-specific behavior. +For example, the 8086 and 8086-SSE +subdirectories have source files that specialize SoftFloat’s behavior to +match that of Intel’s x86 line of processors. +The files in a specialization subdirectory must determine: +

    +
  • +whether tininess for underflow is detected before or after rounding by default; +
  • +how signaling NaNs are distinguished from quiet NaNs; +
  • +what (if anything) special happens when exceptions are raised; +
  • +the default generated quiet NaNs; +
  • +how NaNs are propagated from function inputs to output; and +
  • +the integer results returned when conversions to integer type raise the +invalid exception. +
+

+ +

+As provided, the build process for a target expects to involve exactly +one specialization directory that defines all of these +implementation-specific details for the target. +A specialization directory such as 8086 is expected to contain a +header file called specialize.h, together with whatever other +source files are needed to complete the specialization. +

+ +

+A new build target may use an existing specialization, such as the ones +provided by the 8086 and 8086-SSE +subdirectories. +If a build target needs a new specialization, different from any existing ones, +it is recommended that a new specialization directory be created for this +purpose. +The specialize.h header file from any of the provided +specialization subdirectories can be used as a model for what definitions are +needed. +

+ + +

5.3. Macros for Build Options

+ +

+The SoftFloat source files adapt the floating-point implementation according to +several C preprocessor macros: +

+
+
LITTLEENDIAN +
+Must be defined for little-endian machines; must not be defined for big-endian +machines. +
INLINE +
+Specifies the sequence of tokens used to indicate that a C function should be +inlined. +If macro INLINE_LEVEL is defined with a value of 1 or higher, this +macro must be defined; otherwise, this macro is ignored and need not be +defined. +For compilers that conform to the C Standard’s rules for inline +functions, this macro can be defined as the single keyword inline. +For other compilers that follow a convention pre-dating the standardization of +inline, this macro may need to be defined to extern +inline. +
THREAD_LOCAL +
+Can be defined to a sequence of tokens that, when appearing at the start of a +variable declaration, indicates to the C compiler that the variable is +per-thread, meaning that each execution thread gets its own separate +instance of the variable. +This macro is used in header softfloat.h in the declarations of +variables softfloat_roundingMode, +softfloat_detectTininess, extF80_roundingPrecision, +and softfloat_exceptionFlags. +If macro THREAD_LOCAL is left undefined, these variables will +default to being ordinary global variables. +Depending on the compiler, possible valid definitions of this macro include +_Thread_local and __thread. +
+
+
SOFTFLOAT_ROUND_ODD +
+Can be defined to enable support for optional rounding mode +softfloat_round_odd. +
+
+
INLINE_LEVEL +
+Can be defined to an integer to determine the degree of inlining requested of +the compiler. +Larger numbers request that more inlining be done. +If this macro is not defined or is defined to a value less than 1 +(zero or negative), no inlining is requested. +The maximum effective value is no higher than 5. +Defining this macro to a value greater than 5 is the same as defining it +to 5. +
SOFTFLOAT_FAST_INT64 +
+Can be defined to indicate that the build target’s implementation of +64-bit arithmetic is efficient. +For newer 64-bit processors, this macro should usually be defined. +For very small microprocessors whose buses and registers are 8-bit +or 16-bit in size, this macro should usually not be defined. +Whether this macro should be defined for a 32-bit processor may +depend on the target machine and the applications that will use SoftFloat. +
SOFTFLOAT_FAST_DIV32TO16 +
+Can be defined to indicate that the target’s division operator +in C (written as /) is reasonably efficient for +dividing a 32-bit unsigned integer by a 16-bit +unsigned integer. +Setting this macro may affect the performance of function f16_div. +
SOFTFLOAT_FAST_DIV64TO32 +
+Can be defined to indicate that the target’s division operator +in C (written as /) is reasonably efficient for +dividing a 64-bit unsigned integer by a 32-bit +unsigned integer. +Setting this macro may affect the performance of division, remainder, and +square root operations other than f16_div. +
+
+

+ +

+Following the usual custom for C, for most of these macros (all +except INLINE, THREAD_LOCAL, and +INLINE_LEVEL), the content of any definition is irrelevant; +what matters is a macro’s effect on #ifdef directives. +

+ +

+It is recommended that any definitions of macros LITTLEENDIAN, +INLINE, and THREAD_LOCAL be made in a build +target’s platform.h header file, because these macros are +expected to be determined inflexibly by the target machine and compiler. +The other five macros select options and control optimization, and thus might +be better located in the target’s Makefile (or its equivalent). +

+ + +

5.4. Adapting a Template Target Directory

+ +

+In the build directory, two template subdirectories +provide models for new target directories. +Two different templates exist because different functions are needed in the +SoftFloat library depending on whether macro SOFTFLOAT_FAST_INT64 +is defined. +If macro SOFTFLOAT_FAST_INT64 will be defined, +template-FAST_INT64 is the template to use; +otherwise, template-not-FAST_INT64 is the appropriate +template. +A new target directory can be created by copying the correct template directory +and editing the files inside. +To avoid confusion, it would be wise to refrain from editing the files within a +template directory directly. +

+ + +

5.5. Target-Specific Optimization of Primitive Functions

+ +

+Header file primitives.h (in directory +source/include) declares macros and functions for numerous +underlying arithmetic operations upon which many of SoftFloat’s +floating-point functions are ultimately built. +The SoftFloat sources include implementations of all of these functions/macros, +written as standard C code, so a complete and correct SoftFloat library can be +created using only the supplied code for all functions. +However, for many targets, SoftFloat’s performance can be improved by +substituting target-specific implementations of some of the functions/macros +declared in primitives.h. +

+ +

+For example, primitives.h declares a function called +softfloat_countLeadingZeros32 that takes an unsigned +32-bit integer as an argument and returns the number of the +integer’s most-significant bits that are zeros. +While the SoftFloat sources include an implementation of this function written +in standard C, many processors can perform this same function +directly in only one or two machine instructions. +An alternative, target-specific implementation that maps to those instructions +is likely to be more efficient than the generic C code from the SoftFloat +package. +

+ +

+A build target can replace the supplied version of any function or macro of +primitives.h by defining a macro with the same name in the +target’s platform.h header file. +For this purpose, it may be helpful for platform.h to +#include header file primitiveTypes.h, which defines +types used for arguments and results of functions declared in +primitives.h. +When a desired replacement implementation is a function, not a macro, it is +sufficient for platform.h to include the line +

+
+#define <function-name> <function-name>
+
+
+where <function-name> is the name of the +function. +This technically defines <function-name> +as a macro, but one that resolves to the same name, which may then be a +function. +(A preprocessor that conforms to the C Standard is required to limit recursive +macro expansion from being applied more than once.) +

+ +

+The supplied header file opts-GCC.h (in directory +source/include) provides an example of target-specific +optimization for the GCC compiler. +Each GCC target example in the build directory has +

+#include "opts-GCC.h" +
+in its platform.h header file. +Before opts-GCC.h is included, the following macros must be +defined (or not) to control which features are invoked: +
+
+
SOFTFLOAT_BUILTIN_CLZ
+
+If defined, SoftFloat’s internal +‘countLeadingZeros’ functions use intrinsics +__builtin_clz and __builtin_clzll. +
+
SOFTFLOAT_INTRINSIC_INT128
+
+If defined, SoftFloat makes use of GCC’s nonstandard 128-bit +integer type __int128. +
+
+
+On some machines, these improvements are observed to increase the speeds of +f64_mul and f128_mul by around 20 to 25%, although +other functions receive less dramatic boosts, or none at all. +Results can vary greatly across different platforms. +

+ + +

6. Testing SoftFloat

+ +

+SoftFloat can be tested using the testsoftfloat program by the +same author. +This program is part of the Berkeley TestFloat package available at the Web +page +http://www.jhauser.us/arithmetic/TestFloat.html. +The TestFloat package also has a program called timesoftfloat that +measures the speed of SoftFloat’s floating-point functions. +

+ + +

7. Providing SoftFloat as a Common Library for Applications

+ +

+Header file softfloat.h defines the SoftFloat interface as seen by +clients. +If the SoftFloat library will be made a common library for programs on a +system, the supplied softfloat.h has a couple of deficiencies for +this purpose: +

    +
  • +As supplied, softfloat.h depends on another header, +softfloat_types.h, that is not intended for public use but which +must also be visible to the programmer’s compiler. +
  • +More troubling, at the time softfloat.h is included in a C source +file, macros SOFTFLOAT_FAST_INT64 and THREAD_LOCAL +must be defined, or not defined, consistent with how these macro were defined +when the SoftFloat library was built. +
+In the situation that new programs may regularly #include header +file softfloat.h, it is recommended that a custom, self-contained +version of this header file be created that eliminates these issues. +

+ + +

8. Contact Information

+ +

+At the time of this writing, the most up-to-date information about SoftFloat +and the latest release can be found at the Web page +http://www.jhauser.us/arithmetic/SoftFloat.html. +

+ + + + diff --git a/src/cpu/softfloat3e/doc/SoftFloat.html b/src/cpu/softfloat3e/doc/SoftFloat.html new file mode 100644 index 000000000..b72b407f4 --- /dev/null +++ b/src/cpu/softfloat3e/doc/SoftFloat.html @@ -0,0 +1,1527 @@ + + + + +Berkeley SoftFloat Library Interface + + + + +

Berkeley SoftFloat Release 3e: Library Interface

+ +

+John R. Hauser
+2018 January 20
+

+ + +

Contents

+ +
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1. Introduction
2. Limitations
3. Acknowledgments and License
4. Types and Functions
4.1. Boolean and Integer Types
4.2. Floating-Point Types
4.3. Supported Floating-Point Functions
4.4. Non-canonical Representations in extFloat80_t
4.5. Conventions for Passing Arguments and Results
5. Reserved Names
6. Mode Variables
6.1. Rounding Mode
6.2. Underflow Detection
6.3. Rounding Precision for the 80-Bit Extended Format
7. Exceptions and Exception Flags
8. Function Details
8.1. Conversions from Integer to Floating-Point
8.2. Conversions from Floating-Point to Integer
8.3. Conversions Among Floating-Point Types
8.4. Basic Arithmetic Functions
8.5. Fused Multiply-Add Functions
8.6. Remainder Functions
8.7. Round-to-Integer Functions
8.8. Comparison Functions
8.9. Signaling NaN Test Functions
8.10. Raise-Exception Function
9. Changes from SoftFloat Release 2
9.1. Name Changes
9.2. Changes to Function Arguments
9.3. Added Capabilities
9.4. Better Compatibility with the C Language
9.5. New Organization as a Library
9.6. Optimization Gains (and Losses)
10. Future Directions
11. Contact Information
+
+ + +

1. Introduction

+ +

+Berkeley SoftFloat is a software implementation of binary floating-point that +conforms to the IEEE Standard for Floating-Point Arithmetic. +The current release supports five binary formats: 16-bit +half-precision, 32-bit single-precision, 64-bit +double-precision, 80-bit double-extended-precision, and +128-bit quadruple-precision. +The following functions are supported for each format: +

    +
  • +addition, subtraction, multiplication, division, and square root; +
  • +fused multiply-add as defined by the IEEE Standard, except for +80-bit double-extended-precision; +
  • +remainder as defined by the IEEE Standard; +
  • +round to integral value; +
  • +comparisons; +
  • +conversions to/from other supported formats; and +
  • +conversions to/from 32-bit and 64-bit integers, +signed and unsigned. +
+All operations required by the original 1985 version of the IEEE Floating-Point +Standard are implemented, except for conversions to and from decimal. +

+ +

+This document gives information about the types defined and the routines +implemented by SoftFloat. +It does not attempt to define or explain the IEEE Floating-Point Standard. +Information about the standard is available elsewhere. +

+ +

+The current version of SoftFloat is Release 3e. +This release modifies the behavior of the rarely used odd rounding mode +(round to odd, also known as jamming), and also adds some new +specialization and optimization examples for those compiling SoftFloat. +

+ +

+The previous Release 3d fixed bugs that were found in the square +root functions for the 64-bit, 80-bit, and +128-bit floating-point formats. +(Thanks to Alexei Sibidanov at the University of Victoria for reporting an +incorrect result.) +The bugs affected all prior Release-3 versions of SoftFloat +through 3c. +The flaw in the 64-bit floating-point square root function was of +very minor impact, causing a 1-ulp error (1 unit in +the last place) a few times out of a billion. +The bugs in the 80-bit and 128-bit square root +functions were more serious. +Although incorrect results again occurred only a few times out of a billion, +when they did occur a large portion of the less-significant bits could be +wrong. +

+ +

+Among earlier releases, 3b was notable for adding support for the +16-bit half-precision format. +For more about the evolution of SoftFloat releases, see +SoftFloat-history.html. +

+ +

+The functional interface of SoftFloat Release 3 and later differs +in many details from the releases that came before. +For specifics of these differences, see section 9 below, +Changes from SoftFloat Release 2. +

+ + +

2. Limitations

+ +

+SoftFloat assumes the computer has an addressable byte size of 8 or +16 bits. +(Nearly all computers in use today have 8-bit bytes.) +

+ +

+SoftFloat is written in C and is designed to work with other C code. +The C compiler used must conform at a minimum to the 1989 ANSI standard for the +C language (same as the 1990 ISO standard) and must in addition support basic +arithmetic on 64-bit integers. +Earlier releases of SoftFloat included implementations of 32-bit +single-precision and 64-bit double-precision floating-point that +did not require 64-bit integers, but this option is not supported +starting with Release 3. +Since 1999, ISO standards for C have mandated compiler support for +64-bit integers. +A compiler conforming to the 1999 C Standard or later is recommended but not +strictly required. +

+ +

+Most operations not required by the original 1985 version of the IEEE +Floating-Point Standard but added in the 2008 version are not yet supported in +SoftFloat Release 3e. +

+ + +

3. Acknowledgments and License

+ +

+The SoftFloat package was written by me, John R. Hauser. +Release 3 of SoftFloat was a completely new implementation +supplanting earlier releases. +The project to create Release 3 (now through 3e) was +done in the employ of the University of California, Berkeley, within the +Department of Electrical Engineering and Computer Sciences, first for the +Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab. +The work was officially overseen by Prof. Krste Asanovic, with funding provided +by these sources: +

+ ++++ + + + + + + + + + +
Par Lab: +Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery +(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia, +NVIDIA, Oracle, and Samsung. +
ASPIRE Lab: +DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from +ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA, +Oracle, and Samsung. +
+
+

+ +

+The following applies to the whole of SoftFloat Release 3e as well +as to each source file individually. +

+ +

+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the +University of California. +All rights reserved. +

+ +

+Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +

    + +
  1. +

    +Redistributions of source code must retain the above copyright notice, this +list of conditions, and the following disclaimer. +

    + +
  2. +

    +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions, and the following disclaimer in the documentation and/or +other materials provided with the distribution. +

    + +
  3. +

    +Neither the name of the University nor the names of its contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. +

    + +
+

+ +

+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”, +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. +IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +

+ + +

4. Types and Functions

+ +

+The types and functions of SoftFloat are declared in header file +softfloat.h. +

+ +

4.1. Boolean and Integer Types

+ +

+Header file softfloat.h depends on standard headers +<stdbool.h> and <stdint.h> to define type +bool and several integer types. +These standard headers have been part of the ISO C Standard Library since 1999. +With any recent compiler, they are likely to be supported, even if the compiler +does not claim complete conformance to the latest ISO C Standard. +For older or nonstandard compilers, a port of SoftFloat may have substitutes +for these headers. +Header softfloat.h depends only on the name bool from +<stdbool.h> and on these type names from +<stdint.h>: +

+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+uint_fast8_t
+uint_fast32_t
+uint_fast64_t
+int_fast32_t
+int_fast64_t
+
+
+

+ + +

4.2. Floating-Point Types

+ +

+The softfloat.h header defines five floating-point types: +

+ + + + + + + + + + + + + + + + + + + + + +
float16_t16-bit half-precision binary format
float32_t32-bit single-precision binary format
float64_t64-bit double-precision binary format
extFloat80_t   80-bit double-extended-precision binary format (old Intel or +Motorola format)
float128_t128-bit quadruple-precision binary format
+
+The non-extended types are each exactly the size specified: +16 bits for float16_t, 32 bits for +float32_t, 64 bits for float64_t, and +128 bits for float128_t. +Aside from these size requirements, the definitions of all these types may +differ for different ports of SoftFloat to specific systems. +A given port of SoftFloat may or may not define some of the floating-point +types as aliases for the C standard types float, +double, and long double. +

+ +

+Header file softfloat.h also defines a structure, +struct extFloat80M, for the representation of +80-bit double-extended-precision floating-point values in memory. +This structure is the same size as type extFloat80_t and contains +at least these two fields (not necessarily in this order): +

+
+uint16_t signExp;
+uint64_t signif;
+
+
+Field signExp contains the sign and exponent of the floating-point +value, with the sign in the most significant bit (bit 15) and the +encoded exponent in the other 15 bits. +Field signif is the complete 64-bit significand of +the floating-point value. +(In the usual encoding for 80-bit extended floating-point, the +leading 1 bit of normalized numbers is not implicit but is stored +in the most significant bit of the significand.) +

+ +

4.3. Supported Floating-Point Functions

+ +

+SoftFloat implements these arithmetic operations for its floating-point types: +

    +
  • +conversions between any two floating-point formats; +
  • +for each floating-point format, conversions to and from signed and unsigned +32-bit and 64-bit integers; +
  • +for each format, the usual addition, subtraction, multiplication, division, and +square root operations; +
  • +for each format except extFloat80_t, the fused multiply-add +operation defined by the IEEE Standard; +
  • +for each format, the floating-point remainder operation defined by the IEEE +Standard; +
  • +for each format, a “round to integer” operation that rounds to the +nearest integer value in the same format; and +
  • +comparisons between two values in the same floating-point format. +
+

+ +

+The following operations required by the 2008 IEEE Floating-Point Standard are +not supported in SoftFloat Release 3e: +

    +
  • +nextUp, nextDown, minNum, maxNum, minNumMag, +maxNumMag, scaleB, and logB; +
  • +conversions between floating-point formats and decimal or hexadecimal character +sequences; +
  • +all “quiet-computation” operations (copy, negate, +abs, and copySign, which all involve only simple copying and/or +manipulation of the floating-point sign bit); and +
  • +all “non-computational” operations other than isSignaling +(which is supported). +
+

+ +

4.4. Non-canonical Representations in extFloat80_t

+ +

+Because the 80-bit double-extended-precision format, +extFloat80_t, stores an explicit leading significand bit, many +finite floating-point numbers are encodable in this type in multiple equivalent +forms. +Of these multiple encodings, there is always a unique one with the least +encoded exponent value, and this encoding is considered the canonical +representation of the floating-point number. +Any other equivalent representations (having a higher encoded exponent value) +are non-canonical. +For a value in the subnormal range (including zero), the canonical +representation always has an encoded exponent of zero and a leading significand +bit of 0. +For finite values outside the subnormal range, the canonical representation +always has an encoded exponent that is nonzero and a leading significand bit +of 1. +

+ +

+For an infinity or NaN, the leading significand bit is similarly expected to +be 1. +An infinity or NaN with a leading significand bit of 0 is again +considered non-canonical. +Hence, altogether, to be canonical, a value of type extFloat80_t +must have a leading significand bit of 1, unless the value is +subnormal or zero, in which case the leading significand bit and the encoded +exponent must both be zero. +

+ +

+SoftFloat’s functions are not guaranteed to operate as expected when +inputs of type extFloat80_t are non-canonical. +Assuming all of a function’s extFloat80_t inputs (if any) +are canonical, function outputs of type extFloat80_t will always +be canonical. +

+ +

4.5. Conventions for Passing Arguments and Results

+ +

+Values that are at most 64 bits in size (i.e., not the +80-bit or 128-bit floating-point formats) are in all +cases passed as function arguments by value. +Likewise, when an output of a function is no more than 64 bits, it +is always returned directly as the function result. +Thus, for example, the SoftFloat function for adding two 64-bit +floating-point values has this simple signature: +

+float64_t f64_add( float64_t, float64_t ); +
+

+ +

+The story is more complex when function inputs and outputs are +80-bit and 128-bit floating-point. +For these types, SoftFloat always provides a function that passes these larger +values into or out of the function indirectly, via pointers. +For example, for adding two 128-bit floating-point values, +SoftFloat supplies this function: +

+void f128M_add( const float128_t *, const float128_t *, float128_t * ); +
+The first two arguments point to the values to be added, and the last argument +points to the location where the sum will be stored. +The M in the name f128M_add is mnemonic for the fact +that the 128-bit inputs and outputs are “in memory”, +pointed to by pointer arguments. +

+ +

+All ports of SoftFloat implement these pass-by-pointer functions for +types extFloat80_t and float128_t. +At the same time, SoftFloat ports may also implement alternate versions of +these same functions that pass extFloat80_t and +float128_t by value, like the smaller formats. +Thus, besides the function with name f128M_add shown above, a +SoftFloat port may also supply an equivalent function with this signature: +

+float128_t f128_add( float128_t, float128_t ); +
+

+ +

+As a general rule, on computers where the machine word size is +32 bits or smaller, only the pass-by-pointer versions of functions +(e.g., f128M_add) are provided for types extFloat80_t +and float128_t, because passing such large types directly can have +significant extra cost. +On computers where the word size is 64 bits or larger, both +function versions (f128M_add and f128_add) are +provided, because the cost of passing by value is then more reasonable. +Applications that must be portable accross both classes of computers must use +the pointer-based functions, as these are always implemented. +However, if it is known that SoftFloat includes the by-value functions for all +platforms of interest, programmers can use whichever version they prefer. +

+ + +

5. Reserved Names

+ +

+In addition to the variables and functions documented here, SoftFloat defines +some symbol names for its own private use. +These private names always begin with the prefix +‘softfloat_’. +When a program includes header softfloat.h or links with the +SoftFloat library, all names with prefix ‘softfloat_’ +are reserved for possible use by SoftFloat. +Applications that use SoftFloat should not define their own names with this +prefix, and should reference only such names as are documented. +

+ + +

6. Mode Variables

+ +

+The following global variables control rounding mode, underflow detection, and +the 80-bit extended format’s rounding precision: +

+softfloat_roundingMode
+softfloat_detectTininess
+extF80_roundingPrecision +
+These mode variables are covered in the next several subsections. +For some SoftFloat ports, these variables may be per-thread (declared +thread_local), meaning that different execution threads have their +own separate copies of the variables. +

+ +

6.1. Rounding Mode

+ +

+All five rounding modes defined by the 2008 IEEE Floating-Point Standard are +implemented for all operations that require rounding. +Some ports of SoftFloat may also implement the round-to-odd mode. +

+ +

+The rounding mode is selected by the global variable +

+uint_fast8_t softfloat_roundingMode; +
+This variable may be set to one of the values +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
softfloat_round_near_evenround to nearest, with ties to even
softfloat_round_near_maxMag  round to nearest, with ties to maximum magnitude (away from zero)
softfloat_round_minMaground to minimum magnitude (toward zero)
softfloat_round_minround to minimum (down)
softfloat_round_maxround to maximum (up)
softfloat_round_oddround to odd (jamming), if supported by the SoftFloat port
+
+Variable softfloat_roundingMode is initialized to +softfloat_round_near_even. +

+ +

+When softfloat_round_odd is the rounding mode for a function that +rounds to an integer value (either conversion to an integer format or a +‘roundToInt’ function), if the input is not already an +integer, the rounded result is the closest odd integer. +For other operations, this rounding mode acts as though the floating-point +result is first rounded to minimum magnitude, the same as +softfloat_round_minMag, and then, if the result is inexact, the +least-significant bit of the result is set to 1. +Rounding to odd is also known as jamming. +

+ +

6.2. Underflow Detection

+ +

+In the terminology of the IEEE Standard, SoftFloat can detect tininess for +underflow either before or after rounding. +The choice is made by the global variable +

+uint_fast8_t softfloat_detectTininess; +
+which can be set to either +
+softfloat_tininess_beforeRounding
+softfloat_tininess_afterRounding +
+Detecting tininess after rounding is usually better because it results in fewer +spurious underflow signals. +The other option is provided for compatibility with some systems. +Like most systems (and as required by the newer 2008 IEEE Standard), SoftFloat +always detects loss of accuracy for underflow as an inexact result. +

+ +

6.3. Rounding Precision for the 80-Bit Extended Format

+ +

+For extFloat80_t only, the rounding precision of the basic +arithmetic operations is controlled by the global variable +

+uint_fast8_t extF80_roundingPrecision; +
+The operations affected are: +
+extF80_add
+extF80_sub
+extF80_mul
+extF80_div
+extF80_sqrt +
+When extF80_roundingPrecision is set to its default value of 80, +these operations are rounded to the full precision of the 80-bit +double-extended-precision format, like occurs for other formats. +Setting extF80_roundingPrecision to 32 or to 64 causes the +operations listed to be rounded to 32-bit precision (equivalent to +float32_t) or to 64-bit precision (equivalent to +float64_t), respectively. +When rounding to reduced precision, additional bits in the result significand +beyond the rounding point are set to zero. +The consequences of setting extF80_roundingPrecision to a value +other than 32, 64, or 80 is not specified. +Operations other than the ones listed above are not affected by +extF80_roundingPrecision. +

+ + +

7. Exceptions and Exception Flags

+ +

+All five exception flags required by the IEEE Floating-Point Standard are +implemented. +Each flag is stored as a separate bit in the global variable +

+uint_fast8_t softfloat_exceptionFlags; +
+The positions of the exception flag bits within this variable are determined by +the bit masks +
+softfloat_flag_inexact
+softfloat_flag_underflow
+softfloat_flag_overflow
+softfloat_flag_infinite
+softfloat_flag_invalid +
+Variable softfloat_exceptionFlags is initialized to all zeros, +meaning no exceptions. +

+ +

+For some SoftFloat ports, softfloat_exceptionFlags may be +per-thread (declared thread_local), meaning that different +execution threads have their own separate instances of it. +

+ +

+An individual exception flag can be cleared with the statement +

+softfloat_exceptionFlags &= ~softfloat_flag_<exception>; +
+where <exception> is the appropriate name. +To raise a floating-point exception, function softfloat_raiseFlags +should normally be used. +

+ +

+When SoftFloat detects an exception other than inexact, it calls +softfloat_raiseFlags. +The default version of this function simply raises the corresponding exception +flags. +Particular ports of SoftFloat may support alternate behavior, such as exception +traps, by modifying the default softfloat_raiseFlags. +A program may also supply its own softfloat_raiseFlags function to +override the one from the SoftFloat library. +

+ +

+Because inexact results occur frequently under most circumstances (and thus are +hardly exceptional), SoftFloat does not ordinarily call +softfloat_raiseFlags for inexact exceptions. +It does always raise the inexact exception flag as required. +

+ + +

8. Function Details

+ +

+In this section, <float> appears in function names as +a substitute for one of these abbreviations: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
f16indicates float16_t, passed by value
f32indicates float32_t, passed by value
f64indicates float64_t, passed by value
extF80M   indicates extFloat80_t, passed indirectly via pointers
extF80indicates extFloat80_t, passed by value
f128Mindicates float128_t, passed indirectly via pointers
f128indicates float128_t, passed by value
+
+The circumstances under which values of floating-point types +extFloat80_t and float128_t may be passed either by +value or indirectly via pointers was discussed earlier in +section 4.5, Conventions for Passing Arguments and Results. +

+ +

8.1. Conversions from Integer to Floating-Point

+ +

+All conversions from a 32-bit or 64-bit integer, +signed or unsigned, to a floating-point format are supported. +Functions performing these conversions have these names: +

+ui32_to_<float>
+ui64_to_<float>
+i32_to_<float>
+i64_to_<float> +
+Conversions from 32-bit integers to 64-bit +double-precision and larger formats are always exact, and likewise conversions +from 64-bit integers to 80-bit +double-extended-precision and 128-bit quadruple-precision are also +always exact. +

+ +

+Each conversion function takes one input of the appropriate type and generates +one output. +The following illustrates the signatures of these functions in cases when the +floating-point result is passed either by value or via pointers: +

+
+float64_t i32_to_f64( int32_t a );
+
+
+void i32_to_f128M( int32_t a, float128_t *destPtr );
+
+
+

+ +

8.2. Conversions from Floating-Point to Integer

+ +

+Conversions from a floating-point format to a 32-bit or +64-bit integer, signed or unsigned, are supported with these +functions: +

+<float>_to_ui32
+<float>_to_ui64
+<float>_to_i32
+<float>_to_i64 +
+The functions have signatures as follows, depending on whether the +floating-point input is passed by value or via pointers: +
+
+int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+int_fast32_t
+ f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact );
+
+
+

+ +

+The roundingMode argument specifies the rounding mode for +the conversion. +The variable that usually indicates rounding mode, +softfloat_roundingMode, is ignored. +Argument exact determines whether the inexact +exception flag is raised if the conversion is not exact. +If exact is true, the inexact flag may +be raised; +otherwise, it will not be, even if the conversion is inexact. +

+ +

+A conversion from floating-point to integer format raises the invalid +exception if the source value cannot be rounded to a representable integer of +the desired size (32 or 64 bits). +In such circumstances, the integer result returned is determined by the +particular port of SoftFloat, although typically this value will be either the +maximum or minimum value of the integer format. +The functions that convert to integer types never raise the floating-point +overflow exception. +

+ +

+Because languages such as C require that conversions to integers +be rounded toward zero, the following functions are provided for improved speed +and convenience: +

+<float>_to_ui32_r_minMag
+<float>_to_ui64_r_minMag
+<float>_to_i32_r_minMag
+<float>_to_i64_r_minMag +
+These functions round only toward zero (to minimum magnitude). +The signatures for these functions are the same as above without the redundant +roundingMode argument: +
+
+int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact );
+
+
+int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact );
+
+
+

+ +

8.3. Conversions Among Floating-Point Types

+ +

+Conversions between floating-point formats are done by functions with these +names: +

+<float>_to_<float> +
+All combinations of source and result type are supported where the source and +result are different formats. +There are four different styles of signature for these functions, depending on +whether the input and the output floating-point values are passed by value or +via pointers: +
+
+float32_t f64_to_f32( float64_t a );
+
+
+float32_t f128M_to_f32( const float128_t *aPtr );
+
+
+void f32_to_f128M( float32_t a, float128_t *destPtr );
+
+
+void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *destPtr );
+
+
+

+ +

+Conversions from a smaller to a larger floating-point format are always exact +and so require no rounding. +

+ +

8.4. Basic Arithmetic Functions

+ +

+The following basic arithmetic functions are provided: +

+<float>_add
+<float>_sub
+<float>_mul
+<float>_div
+<float>_sqrt +
+Each floating-point operation takes two operands, except for sqrt +(square root) which takes only one. +The operands and result are all of the same floating-point format. +Signatures for these functions take the following forms: +
+
+float64_t f64_add( float64_t a, float64_t b );
+
+
+void
+ f128M_add(
+     const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+float64_t f64_sqrt( float64_t a );
+
+
+void f128M_sqrt( const float128_t *aPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments +aPtr and bPtr point to the input +operands, and the last argument, destPtr, points to the +location where the result is stored. +

+ +

+Rounding of the 80-bit double-extended-precision +(extFloat80_t) functions is affected by variable +extF80_roundingPrecision, as explained earlier in +section 6.3, +Rounding Precision for the 80-Bit Extended Format. +

+ +

8.5. Fused Multiply-Add Functions

+ +

+The 2008 version of the IEEE Floating-Point Standard defines a fused +multiply-add operation that does a combined multiplication and addition +with only a single rounding. +SoftFloat implements fused multiply-add with functions +

+<float>_mulAdd +
+Unlike other operations, fused multiple-add is not supported for the +80-bit double-extended-precision format, +extFloat80_t. +

+ +

+Depending on whether floating-point values are passed by value or via pointers, +the fused multiply-add functions have signatures of these forms: +

+
+float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c );
+
+
+void
+ f128M_mulAdd(
+     const float128_t *aPtr,
+     const float128_t *bPtr,
+     const float128_t *cPtr,
+     float128_t *destPtr
+ );
+
+
+The functions compute +(a × b) + + c +with a single rounding. +When floating-point values are passed indirectly through pointers, arguments +aPtr, bPtr, and +cPtr point to operands a, +b, and c respectively, and +destPtr points to the location where the result is stored. +

+ +

+If one of the multiplication operands a and +b is infinite and the other is zero, these functions raise +the invalid exception even if operand c is a quiet NaN. +

+ +

8.6. Remainder Functions

+ +

+For each format, SoftFloat implements the remainder operation defined by the +IEEE Floating-Point Standard. +The remainder functions have names +

+<float>_rem +
+Each remainder operation takes two floating-point operands of the same format +and returns a result in the same format. +Depending on whether floating-point values are passed by value or via pointers, +the remainder functions have signatures of these forms: +
+
+float64_t f64_rem( float64_t a, float64_t b );
+
+
+void
+ f128M_rem(
+     const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments +aPtr and bPtr point to operands +a and b respectively, and +destPtr points to the location where the result is stored. +

+ +

+The IEEE Standard remainder operation computes the value +a + − n × b, +where n is the integer closest to +a ÷ b. +If a ÷ b is exactly +halfway between two integers, n is the even integer closest to +a ÷ b. +The IEEE Standard’s remainder operation is always exact and so requires +no rounding. +

+ +

+Depending on the relative magnitudes of the operands, the remainder +functions can take considerably longer to execute than the other SoftFloat +functions. +This is an inherent characteristic of the remainder operation itself and is not +a flaw in the SoftFloat implementation. +

+ +

8.7. Round-to-Integer Functions

+ +

+For each format, SoftFloat implements the round-to-integer operation specified +by the IEEE Floating-Point Standard. +These functions are named +

+<float>_roundToInt +
+Each round-to-integer operation takes a single floating-point operand. +This operand is rounded to an integer according to a specified rounding mode, +and the resulting integer value is returned in the same floating-point format. +(Note that the result is not an integer type.) +

+ +

+The signatures of the round-to-integer functions are similar to those for +conversions to an integer type: +

+
+float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+void
+ f128M_roundToInt(
+     const float128_t *aPtr,
+     uint_fast8_t roundingMode,
+     bool exact,
+     float128_t *destPtr
+ );
+
+
+When floating-point values are passed indirectly through pointers, +aPtr points to the input operand and +destPtr points to the location where the result is stored. +

+ +

+The roundingMode argument specifies the rounding mode to +apply. +The variable that usually indicates rounding mode, +softfloat_roundingMode, is ignored. +Argument exact determines whether the inexact +exception flag is raised if the conversion is not exact. +If exact is true, the inexact flag may +be raised; +otherwise, it will not be, even if the conversion is inexact. +

+ +

8.8. Comparison Functions

+ +

+For each format, the following floating-point comparison functions are +provided: +

+<float>_eq
+<float>_le
+<float>_lt +
+Each comparison takes two operands of the same type and returns a Boolean. +The abbreviation eq stands for “equal” (=); +le stands for “less than or equal” (≤); +and lt stands for “less than” (<). +Depending on whether the floating-point operands are passed by value or via +pointers, the comparison functions have signatures of these forms: +
+
+bool f64_eq( float64_t a, float64_t b );
+
+
+bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr );
+
+
+

+ +

+The usual greater-than (>), greater-than-or-equal (≥), and not-equal +(≠) comparisons are easily obtained from the functions provided. +The not-equal function is just the logical complement of the equal function. +The greater-than-or-equal function is identical to the less-than-or-equal +function with the arguments in reverse order, and likewise the greater-than +function is identical to the less-than function with the arguments reversed. +

+ +

+The IEEE Floating-Point Standard specifies that the less-than-or-equal and +less-than comparisons by default raise the invalid exception if either +operand is any kind of NaN. +Equality comparisons, on the other hand, are defined by default to raise the +invalid exception only for signaling NaNs, not quiet NaNs. +For completeness, SoftFloat provides these complementary functions: +

+<float>_eq_signaling
+<float>_le_quiet
+<float>_lt_quiet +
+The signaling equality comparisons are identical to the default +equality comparisons except that the invalid exception is raised for any +NaN input, not just for signaling NaNs. +Similarly, the quiet comparison functions are identical to their +default counterparts except that the invalid exception is not raised for +quiet NaNs. +

+ +

8.9. Signaling NaN Test Functions

+ +

+Functions for testing whether a floating-point value is a signaling NaN are +provided with these names: +

+<float>_isSignalingNaN +
+The functions take one floating-point operand and return a Boolean indicating +whether the operand is a signaling NaN. +Accordingly, the functions have the forms +
+
+bool f64_isSignalingNaN( float64_t a );
+
+
+bool f128M_isSignalingNaN( const float128_t *aPtr );
+
+
+

+ +

8.10. Raise-Exception Function

+ +

+SoftFloat provides a single function for raising floating-point exceptions: +

+
+void softfloat_raiseFlags( uint_fast8_t exceptions );
+
+
+The exceptions argument is a mask indicating the set of +exceptions to raise. +(See earlier section 7, Exceptions and Exception Flags.) +In addition to setting the specified exception flags in variable +softfloat_exceptionFlags, the softfloat_raiseFlags +function may cause a trap or abort appropriate for the current system. +

+ + +

9. Changes from SoftFloat Release 2

+ +

+Apart from a change in the legal use license, Release 3 of +SoftFloat introduced numerous technical differences compared to earlier +releases. +

+ +

9.1. Name Changes

+ +

+The most obvious and pervasive difference compared to Release 2 +is that the names of most functions and variables have changed, even when the +behavior has not. +First, the floating-point types, the mode variables, the exception flags +variable, the function to raise exceptions, and various associated constants +have been renamed as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
old name, Release 2:new name, Release 3:
float32float32_t
float64float64_t
floatx80extFloat80_t
float128float128_t
float_rounding_modesoftfloat_roundingMode
float_round_nearest_evensoftfloat_round_near_even
float_round_to_zerosoftfloat_round_minMag
float_round_downsoftfloat_round_min
float_round_upsoftfloat_round_max
float_detect_tininesssoftfloat_detectTininess
float_tininess_before_rounding    softfloat_tininess_beforeRounding
float_tininess_after_roundingsoftfloat_tininess_afterRounding
floatx80_rounding_precisionextF80_roundingPrecision
float_exception_flagssoftfloat_exceptionFlags
float_flag_inexactsoftfloat_flag_inexact
float_flag_underflowsoftfloat_flag_underflow
float_flag_overflowsoftfloat_flag_overflow
float_flag_divbyzerosoftfloat_flag_infinite
float_flag_invalidsoftfloat_flag_invalid
float_raisesoftfloat_raiseFlags
+
+

+ +

+Furthermore, Release 3 adopted the following new abbreviations for +function names: +

+ + + + + + + + + + + +
used in names in Release 2:    used in names in Release 3:
int32 i32
int64 i64
float32 f32
float64 f64
floatx80 extF80
float128 f128
+
+Thus, for example, the function to add two 32-bit floating-point +numbers, previously called float32_add in Release 2, +is now f32_add. +Lastly, there have been a few other changes to function names: +
+ + + + + + + + + + + + + + + + + + + + + +
used in names in Release 2:   used in names in Release 3:   relevant functions:
_round_to_zero_r_minMagconversions from floating-point to integer (section 8.2)
round_to_introundToIntround-to-integer functions (section 8.7)
is_signaling_nan    isSignalingNaNsignaling NaN test functions (section 8.9)
+
+

+ +

9.2. Changes to Function Arguments

+ +

+Besides simple name changes, some operations were given a different interface +in Release 3 than they had in Release 2: +

    + +
  • +

    +Since Release 3, integer arguments and results of functions have +standard types from header <stdint.h>, such as +uint32_t, whereas previously their types could be defined +differently for each port of SoftFloat, usually using traditional C types such +as unsigned int. +Likewise, functions in Release 3 and later pass Booleans as +standard type bool from <stdbool.h>, whereas +previously these were again passed as a port-specific type (usually +int). +

    + +
  • +

    +As explained earlier in section 4.5, Conventions for Passing +Arguments and Results, SoftFloat functions in Release 3 and +later may pass 80-bit and 128-bit floating-point +values through pointers, meaning that functions take pointer arguments and then +read or write floating-point values at the locations indicated by the pointers. +In Release 2, floating-point arguments and results were always +passed by value, regardless of their size. +

    + +
  • +

    +Functions that round to an integer have additional +roundingMode and exact arguments that +they did not have in Release 2. +Refer to sections 8.2 and 8.7 for descriptions of these functions +since Release 3. +For Release 2, the rounding mode, when needed, was taken from the +same global variable that affects the basic arithmetic operations (now called +softfloat_roundingMode but previously known as +float_rounding_mode). +Also, for Release 2, if the original floating-point input was not +an exact integer value, and if the invalid exception was not raised by +the function, the inexact exception was always raised. +Release 2 had no option to suppress raising inexact in this +case. +Applications using SoftFloat Release 3 or later can get the same +effect as Release 2 by passing variable +softfloat_roundingMode for argument +roundingMode and true for argument +exact. +

    + +
+

+ +

9.3. Added Capabilities

+ +

+With Release 3, some new features have been added that were not +present in Release 2: +

    + +
  • +

    +A port of SoftFloat can now define any of the floating-point types +float32_t, float64_t, extFloat80_t, and +float128_t as aliases for C’s standard floating-point types +float, double, and long +double, using either #define or typedef. +This potential convenience was not supported under Release 2. +

    + +

    +(Note, however, that there may be a performance cost to defining +SoftFloat’s floating-point types this way, depending on the platform and +the applications using SoftFloat. +Ports of SoftFloat may choose to forgo the convenience in favor of better +speed.) +

    + +

    +

  • +As of Release 3b, 16-bit half-precision, +float16_t, is supported. +

    + +

    +

  • +Functions have been added for converting between the floating-point types and +unsigned integers. +Release 2 supported only signed integers, not unsigned. +

    + +

    +

  • +Fused multiply-add functions have been added for all floating-point formats +except 80-bit double-extended-precision, +extFloat80_t. +

    + +

    +

  • +New rounding modes are supported: +softfloat_round_near_maxMag (round to nearest, with ties to +maximum magnitude, away from zero), and, as of Release 3c, +optional softfloat_round_odd (round to odd, also known as +jamming). +

    + +
+

+ +

9.4. Better Compatibility with the C Language

+ +

+Release 3 of SoftFloat was written to conform better to the ISO C +Standard’s rules for portability. +For example, older releases of SoftFloat employed type conversions in ways +that, while commonly practiced, are not fully defined by the C Standard. +Such problematic type conversions have generally been replaced by the use of +unions, the behavior around which is more strictly regulated these days. +

+ +

9.5. New Organization as a Library

+ +

+Starting with Release 3, SoftFloat now builds as a library. +Previously, SoftFloat compiled into a single, monolithic object file containing +all the SoftFloat functions, with the consequence that a program linking with +SoftFloat would get every SoftFloat function in its binary file even if only a +few functions were actually used. +With SoftFloat in the form of a library, a program that is linked by a standard +linker will include only those functions of SoftFloat that it needs and no +others. +

+ +

9.6. Optimization Gains (and Losses)

+ +

+Individual SoftFloat functions have been variously improved in +Release 3 compared to earlier releases. +In particular, better, faster algorithms have been deployed for the operations +of division, square root, and remainder. +For functions operating on the larger 80-bit and +128-bit formats, extFloat80_t and +float128_t, code size has also generally been reduced. +

+ +

+However, because Release 2 compiled all of SoftFloat together as a +single object file, compilers could make optimizations across function calls +when one SoftFloat function calls another. +Now that the functions of SoftFloat are compiled separately and only afterward +linked together into a program, there is not usually the same opportunity to +optimize across function calls. +Some loss of speed has been observed due to this change. +

+ + +

10. Future Directions

+ +

+The following improvements are anticipated for future releases of SoftFloat: +

    +
  • +more functions from the 2008 version of the IEEE Floating-Point Standard; +
  • +consistent, defined behavior for non-canonical representations of extended +format extFloat80_t (discussed in section 4.4, +Non-canonical Representations in extFloat80_t). + +
+

+ + +

11. Contact Information

+ +

+At the time of this writing, the most up-to-date information about SoftFloat +and the latest release can be found at the Web page +http://www.jhauser.us/arithmetic/SoftFloat.html. +

+ + + + diff --git a/src/cpu/softfloat3e/extF80_addsub.cc b/src/cpu/softfloat3e/extF80_addsub.cc new file mode 100644 index 000000000..a60d2c6be --- /dev/null +++ b/src/cpu/softfloat3e/extF80_addsub.cc @@ -0,0 +1,106 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extern extFloat80_t softfloat_addMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *); +extern extFloat80_t softfloat_subMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *); + +extFloat80_t extF80_add(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + uint16_t uiB64; + uint64_t uiB0; + bool signB; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + a.signExp = defaultNaNExtF80UI64; + a.signif = defaultNaNExtF80UI0; + return a; + } + + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + + if (signA == signB) { + return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status); + } else { + return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status); + } +} + +extFloat80_t extF80_sub(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + uint16_t uiB64; + uint64_t uiB0; + bool signB; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + a.signExp = defaultNaNExtF80UI64; + a.signif = defaultNaNExtF80UI0; + return a; + } + + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + + if (signA == signB) { + return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status); + } else { + return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status); + } +} diff --git a/src/cpu/softfloat3e/extF80_class.cc b/src/cpu/softfloat3e/extF80_class.cc new file mode 100644 index 000000000..155dc51a2 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_class.cc @@ -0,0 +1,71 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "softfloat.h" + +softfloat_class_t extF80_class(extFloat80_t a) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + + if (! expA) { + if (! sigA) return softfloat_zero; + return softfloat_denormal; /* denormal or pseudo-denormal */ + } + + /* valid numbers have the MS bit set */ + if (!(sigA & UINT64_C(0x8000000000000000))) + return softfloat_SNaN; /* report unsupported as SNaNs */ + + if (expA == 0x7FFF) { + if ((sigA<<1) == 0) + return (signA) ? softfloat_negative_inf : softfloat_positive_inf; + + return (sigA & UINT64_C(0x4000000000000000)) ? softfloat_QNaN : softfloat_SNaN; + } + + return softfloat_normalized; +} diff --git a/src/cpu/softfloat3e/extF80_compare.cc b/src/cpu/softfloat3e/extF80_compare.cc new file mode 100644 index 000000000..f8a360a41 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_compare.cc @@ -0,0 +1,147 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include <86box/86box.h> +#include "../cpu.h" + +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two extended precision floating point numbers. Returns +| 'float_relation_equal' if the operands are equal, 'float_relation_less' if +| the value 'a' is less than the corresponding value `b', +| 'float_relation_greater' if the value 'a' is greater than the corresponding +| value `b', or 'float_relation_unordered' otherwise. +*----------------------------------------------------------------------------*/ + +int extF80_compare(extFloat80_t a, extFloat80_t b, int quiet, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + + uint16_t uiB64; + uint64_t uiB0; + bool signB; + int32_t expB; + uint64_t sigB; + + struct exp32_sig64 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + softfloat_class_t aClass = extF80_class(a); + softfloat_class_t bClass = extF80_class(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (fpu_type < FPU_287XL) { + if ((aClass == softfloat_positive_inf) && (bClass == softfloat_negative_inf)) + { + return softfloat_relation_equal; + } + + if ((aClass == softfloat_negative_inf) && (bClass == softfloat_positive_inf)) + { + return softfloat_relation_equal; + } + } + + if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) + { + /* unsupported reported as SNaN */ + softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) { + if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (aClass == softfloat_denormal || bClass == softfloat_denormal) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + expB = expExtF80UI64(uiB64); + sigB = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (aClass == softfloat_zero) { + if (bClass == softfloat_zero) return softfloat_relation_equal; + return signB ? softfloat_relation_greater : softfloat_relation_less; + } + + if (bClass == softfloat_zero || signA != signB) { + return signA ? softfloat_relation_less : softfloat_relation_greater; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (aClass == softfloat_denormal) { + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA += normExpSig.exp + 1; + sigA = normExpSig.sig; + } + if (bClass == softfloat_denormal) { + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB += normExpSig.exp + 1; + sigB = normExpSig.sig; + } + + if (expA == expB && sigA == sigB) + return softfloat_relation_equal; + + int less_than = + signA ? ((expB < expA) || ((expB == expA) && (sigB < sigA))) + : ((expA < expB) || ((expA == expB) && (sigA < sigB))); + + if (less_than) return softfloat_relation_less; + return softfloat_relation_greater; +} diff --git a/src/cpu/softfloat3e/extF80_div.cc b/src/cpu/softfloat3e/extF80_div.cc new file mode 100644 index 000000000..e4b1fbb24 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_div.cc @@ -0,0 +1,188 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + uint16_t uiB64; + uint64_t uiB0; + bool signB; + int32_t expB; + uint64_t sigB; + bool signZ; + struct exp32_sig64 normExpSig; + int32_t expZ; + struct uint128 rem; + uint32_t recip32; + uint64_t sigZ; + int ix; + uint64_t q64; + uint32_t q; + struct uint128 term; + uint64_t sigZExtra; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) + goto invalid; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + expB = expExtF80UI64(uiB64); + sigB = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; + if (expB == 0x7FFF) { + if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; + goto invalid; + } + if (! expB && sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); + } + if (expB == 0x7FFF) { + if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; + if (! expA && sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + expB = 1; + if (sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigB & UINT64_C(0x8000000000000000))) { + if (! sigB) { + if (! sigA) goto invalid; + softfloat_raiseFlags(status, softfloat_flag_infinite); + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB += normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigA & UINT64_C(0x8000000000000000))) { + if (! sigA) return packToExtF80(signZ, 0, 0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA += normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x3FFF; + if (sigA < sigB) { + --expZ; + rem = softfloat_shortShiftLeft128(0, sigA, 32); + } else { + rem = softfloat_shortShiftLeft128(0, sigA, 31); + } + recip32 = softfloat_approxRecip32_1(sigB>>32); + sigZ = 0; + ix = 2; + for (;;) { + q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32; + q = (q64 + 0x80000000)>>32; + --ix; + if (ix < 0) break; + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + term = softfloat_mul64ByShifted32To128(sigB, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + --q; + rem = softfloat_add128(rem.v64, rem.v0, sigB>>32, sigB<<32); + } + sigZ = (sigZ<<29) + q; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (((q + 1) & 0x3FFFFF) < 2) { + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + term = softfloat_mul64ByShifted32To128(sigB, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + term = softfloat_shortShiftLeft128(0, sigB, 32); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + --q; + rem = softfloat_add128(rem.v64, rem.v0, term.v64, term.v0); + } else if (softfloat_le128(term.v64, term.v0, rem.v64, rem.v0)) { + ++q; + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + } + if (rem.v64 | rem.v0) q |= 1; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigZ = (sigZ<<6) + (q>>23); + sigZExtra = (uint64_t) ((uint64_t) q<<41); + return + softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); +} diff --git a/src/cpu/softfloat3e/extF80_extract.cc b/src/cpu/softfloat3e/extF80_extract.cc new file mode 100644 index 000000000..692190a47 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_extract.cc @@ -0,0 +1,97 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Separate the source extended double-precision floating point value `a' +| into its exponent and significand, store the significant back to the +| 'a' and return the exponent. The operation performed is a superset of +| the IEC/IEEE recommended logb(x) function. +*----------------------------------------------------------------------------*/ + +extFloat80_t extF80_extract(extFloat80_t *a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + struct exp32_sig64 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(*a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + *a = packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + return *a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a->signExp; + uiA0 = a->signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if (sigA<<1) { + *a = softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status); + return *a; + } + return packToExtF80(0, 0x7FFF, BX_CONST64(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + softfloat_raiseFlags(status, softfloat_flag_divbyzero); + *a = packToExtF80(signA, 0, 0); + return packToExtF80(1, 0x7FFF, BX_CONST64(0x8000000000000000)); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + } + + *a = packToExtF80(signA, 0x3FFF, sigA); + return i32_to_extF80(expA - 0x3FFF); +} diff --git a/src/cpu/softfloat3e/extF80_mul.cc b/src/cpu/softfloat3e/extF80_mul.cc new file mode 100644 index 000000000..d38e97f02 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_mul.cc @@ -0,0 +1,153 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + uint16_t uiB64; + uint64_t uiB0; + bool signB; + int32_t expB; + uint64_t sigB; + bool signZ; + uint64_t magBits; + struct exp32_sig64 normExpSig; + int32_t expZ; + struct uint128 sig128Z; + uint16_t uiZ64; + uint64_t uiZ0; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + expB = expExtF80UI64(uiB64); + sigB = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) { + goto propagateNaN; + } + magBits = expB | sigB; + goto infArg; + } + if (expB == 0x7FFF) { + if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; + magBits = expA | sigA; + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigA & UINT64_C(0x8000000000000000))) { + if (! sigA) { + if (! expB && sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA += normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + expB = 1; + if (sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigB & UINT64_C(0x8000000000000000))) { + if (! sigB) return packToExtF80(signZ, 0, 0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB += normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FFE; + sig128Z = softfloat_mul64To128(sigA, sigB); + if (sig128Z.v64 < UINT64_C(0x8000000000000000)) { + --expZ; + sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0); + } + return + softfloat_roundPackToExtF80(signZ, expZ, sig128Z.v64, sig128Z.v0, softfloat_extF80_roundingPrecision(status), status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if (! magBits) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ64 = defaultNaNExtF80UI64; + uiZ0 = defaultNaNExtF80UI0; + } else { + if ((! expA && sigA) || (! expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + uiZ64 = packToExtF80UI64(signZ, 0x7FFF); + uiZ0 = UINT64_C(0x8000000000000000); + } + return packToExtF80_twoargs(uiZ64, uiZ0); +} diff --git a/src/cpu/softfloat3e/extF80_rem.cc b/src/cpu/softfloat3e/extF80_rem.cc new file mode 100644 index 000000000..39d233a7e --- /dev/null +++ b/src/cpu/softfloat3e/extF80_rem.cc @@ -0,0 +1,199 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + uint16_t uiB64; + uint64_t uiB0; + int32_t expB; + uint64_t sigB; + struct exp32_sig64 normExpSig; + int32_t expDiff; + struct uint128 rem, shiftedSigB; + uint32_t q, recip32; + uint64_t q64; + struct uint128 term, altRem, meanRem; + bool signRem; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) + goto invalid; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + uiB64 = b.signExp; + uiB0 = b.signif; + expB = expExtF80UI64(uiB64); + sigB = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) { + goto propagateNaN; + } + goto invalid; + } + if (expB == 0x7FFF) { + if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; + /*-------------------------------------------------------------------- + | Argument b is an infinity. Doubling `expB' is an easy way to ensure + | that `expDiff' later is less than -1, which will result in returning + | a canonicalized version of argument a. + *--------------------------------------------------------------------*/ + expB += expB; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + expB = 1; + if (sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigB & UINT64_C(0x8000000000000000))) { + if (! sigB) goto invalid; + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB += normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigA & UINT64_C(0x8000000000000000))) { + if (! sigA) { + expA = 0; + goto copyA; + } + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA += normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (expDiff < -1) goto copyA; + rem = softfloat_shortShiftLeft128(0, sigA, 32); + shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 32); + if (expDiff < 1) { + if (expDiff) { + --expB; + shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 33); + q = 0; + } else { + q = (sigB <= sigA); + if (q) { + rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0); + } + } + } else { + recip32 = softfloat_approxRecip32_1(sigB>>32); + expDiff -= 30; + for (;;) { + q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32; + if (expDiff < 0) break; + q = (q64 + 0x80000000)>>32; + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + term = softfloat_mul64ByShifted32To128(sigB, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + rem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0); + } + expDiff -= 29; + } + /*-------------------------------------------------------------------- + | (`expDiff' cannot be less than -29 here.) + *--------------------------------------------------------------------*/ + q = (uint32_t) (q64>>32)>>(~expDiff & 31); + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, expDiff + 30); + term = softfloat_mul64ByShifted32To128(sigB, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + altRem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0); + goto selectRem; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + do { + altRem = rem; + ++q; + rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0); + } while (! (rem.v64 & UINT64_C(0x8000000000000000))); + selectRem: + meanRem = softfloat_add128(rem.v64, rem.v0, altRem.v64, altRem.v0); + if ((meanRem.v64 & UINT64_C(0x8000000000000000)) || (! (meanRem.v64 | meanRem.v0) && (q & 1))) { + rem = altRem; + } + signRem = signA; + if (rem.v64 & UINT64_C(0x8000000000000000)) { + signRem = ! signRem; + rem = softfloat_sub128(0, 0, rem.v64, rem.v0); + } + return softfloat_normRoundPackToExtF80(signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + copyA: + if (expA < 1) { + sigA >>= 1 - expA; + expA = 0; + } + return packToExtF80(signA, expA, sigA); +} diff --git a/src/cpu/softfloat3e/extF80_roundToInt.cc b/src/cpu/softfloat3e/extF80_roundToInt.cc new file mode 100644 index 000000000..f71cdfc50 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_roundToInt.cc @@ -0,0 +1,123 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t + extF80_roundToInt(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64, signUI64; + int32_t exp; + uint64_t sigA; + uint16_t uiZ64; + uint64_t sigZ; + uint64_t lastBitMask, roundBitsMask; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + signUI64 = uiA64 & packToExtF80UI64(1, 0); + exp = expExtF80UI64(uiA64); + sigA = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x403E <= exp) { + if ((exp == 0x7FFF) && (uint64_t) (sigA<<1)) { + return softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status); + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp <= 0x3FFE) { + if (! exp) { + if ((sigA<<1) == 0) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + switch (roundingMode) { + case softfloat_round_near_even: + if (!(sigA & UINT64_C(0x7FFFFFFFFFFFFFFF))) break; + case softfloat_round_near_maxMag: + if (exp == 0x3FFE) goto mag1; + break; + case softfloat_round_min: + if (signUI64) goto mag1; + break; + case softfloat_round_max: + if (!signUI64) goto mag1; + break; + } + return packToExtF80(signUI64, 0, 0); + mag1: + softfloat_setRoundingUp(status); + return packToExtF80(signUI64, 0x3FFF, UINT64_C(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ64 = signUI64 | exp; + lastBitMask = (uint64_t) 1<<(0x403E - exp); + roundBitsMask = lastBitMask - 1; + sigZ = sigA; + if (roundingMode == softfloat_round_near_maxMag) { + sigZ += lastBitMask>>1; + } else if (roundingMode == softfloat_round_near_even) { + sigZ += lastBitMask>>1; + if (!(sigZ & roundBitsMask)) sigZ &= ~lastBitMask; + } else if (roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max)) { + sigZ += roundBitsMask; + } + sigZ &= ~roundBitsMask; + if (!sigZ) { + ++uiZ64; + sigZ = UINT64_C(0x8000000000000000); + softfloat_setRoundingUp(status); + } + if (sigZ != sigA) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sigZ > sigA) + softfloat_setRoundingUp(status); + } + return packToExtF80_twoargs(uiZ64, sigZ); +} diff --git a/src/cpu/softfloat3e/extF80_scale.cc b/src/cpu/softfloat3e/extF80_scale.cc new file mode 100644 index 000000000..48bd53afd --- /dev/null +++ b/src/cpu/softfloat3e/extF80_scale.cc @@ -0,0 +1,136 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Scales extended double-precision floating-point value in operand `a' by +| value `b'. The function truncates the value in the second operand 'b' to +| an integral value and adds that value to the exponent of the operand 'a'. +| The operation performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +extFloat80_t extF80_scale(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + uint16_t uiB64; + uint64_t uiB0; + bool signB; + int32_t expB; + uint64_t sigB; + struct exp32_sig64 normExpSig; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { +invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + uiB64 = b.signExp; + uiB0 = b.signif; + signB = signExtF80UI64(uiB64); + expB = expExtF80UI64(uiB64); + sigB = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + + if (expA == 0x7FFF) { + if ((sigA<<1) || ((expB == 0x7FFF) && (sigB<<1))) { + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); + } + if ((expB == 0x7FFF) && signB) goto invalid; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + return a; + } + if (expB == 0x7FFF) { + if (sigB<<1) { + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); + } + if ((expA | sigA) == 0) { + if (! signB) goto invalid; + return a; + } + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + if (signB) return packToExtF80(signA, 0, 0); + return packToExtF80(signA, 0x7FFF, BX_CONST64(0x8000000000000000)); + } + if (! expA) { + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + if (! sigA) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + if (expB < 0x3FFF) + return softfloat_normRoundPackToExtF80(signA, expA, sigA, 0, 80, status); + } + if (!expB) { + if (!sigB) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + + if (expB > 0x400E) { + /* generate appropriate overflow/underflow */ + return softfloat_roundPackToExtF80(signA, signB ? -0x3FFF : 0x7FFF, sigA, 0, 80, status); + } + + if (expB < 0x3FFF) return a; + + int shiftCount = 0x403E - expB; + sigB >>= shiftCount; + int32_t scale = (int32_t) sigB; + if (signB) scale = -scale; /* -32768..32767 */ + + return softfloat_roundPackToExtF80(signA, expA + scale, sigA, 0, 80, status); +} diff --git a/src/cpu/softfloat3e/extF80_sqrt.cc b/src/cpu/softfloat3e/extF80_sqrt.cc new file mode 100644 index 000000000..1a5d52e5d --- /dev/null +++ b/src/cpu/softfloat3e/extF80_sqrt.cc @@ -0,0 +1,159 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool signA; + int32_t expA; + uint64_t sigA; + struct exp32_sig64 normExpSig; + int32_t expZ; + uint32_t sig32A, recipSqrt32, sig32Z; + struct uint128 rem; + uint64_t q, x64, sigZ; + struct uint128 y, term; + uint64_t sigZExtra; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) + goto invalid; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + signA = signExtF80UI64(uiA64); + expA = expExtF80UI64(uiA64); + sigA = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) { + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status); + } + if (! signA) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (signA) { + if ((expA | sigA) == 0) return packToExtF80(signA, 0, 0); + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + if (! (sigA & UINT64_C(0x8000000000000000))) { + if (! sigA) return packToExtF80(signA, 0, 0); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA += normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + | (`sig32Z' is guaranteed to be a lower bound on the square root of + | `sig32A', which makes `sig32Z' also a lower bound on the square root of + | `sigA'.) + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x3FFF)>>1) + 0x3FFF; + expA &= 1; + sig32A = sigA>>32; + recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A); + sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32; + if (expA) { + sig32Z >>= 1; + rem = softfloat_shortShiftLeft128(0, sigA, 61); + } else { + rem = softfloat_shortShiftLeft128(0, sigA, 62); + } + rem.v64 -= (uint64_t) sig32Z * sig32Z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = ((uint32_t) (rem.v64>>2) * (uint64_t) recipSqrt32)>>32; + x64 = (uint64_t) sig32Z<<32; + sigZ = x64 + (q<<3); + y = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + /*------------------------------------------------------------------------ + | (Repeating this loop is a rare occurrence.) + *------------------------------------------------------------------------*/ + for (;;) { + term = softfloat_mul64ByShifted32To128(x64 + sigZ, q); + rem = softfloat_sub128(y.v64, y.v0, term.v64, term.v0); + if (! (rem.v64 & UINT64_C(0x8000000000000000))) break; + --q; + sigZ -= 1<<3; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = (((rem.v64>>2) * recipSqrt32)>>32) + 2; + x64 = sigZ; + sigZ = (sigZ<<1) + (q>>25); + sigZExtra = (uint64_t) (q<<39); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((q & 0xFFFFFF) <= 2) { + q &= ~(uint64_t) 0xFFFF; + sigZExtra = (uint64_t) (q<<39); + term = softfloat_mul64ByShifted32To128(x64 + (q>>27), q); + x64 = (uint32_t) (q<<5) * (uint64_t) (uint32_t) q; + term = softfloat_add128(term.v64, term.v0, 0, x64); + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 28); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + if (! sigZExtra) --sigZ; + --sigZExtra; + } else { + if (rem.v64 | rem.v0) sigZExtra |= 1; + } + } + return + softfloat_roundPackToExtF80(0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); +} diff --git a/src/cpu/softfloat3e/extF80_to_f128.cc b/src/cpu/softfloat3e/extF80_to_f128.cc new file mode 100644 index 000000000..24e523cac --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_f128.cc @@ -0,0 +1,75 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + uint16_t exp; + uint64_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + bool sign; + struct uint128 frac128; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + } + + uiA64 = a.signExp; + uiA0 = a.signif; + exp = expExtF80UI64(uiA64); + frac = uiA0 & UINT64_C(0x7FFFFFFFFFFFFFFF); + if ((exp == 0x7FFF) && frac) { + softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF128UI(&commonNaN); + } else { + sign = signExtF80UI64(uiA64); + frac128 = softfloat_shortShiftLeft128(0, frac, 49); + uiZ.v64 = packToF128UI64(sign, exp, frac128.v64); + uiZ.v0 = frac128.v0; + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/extF80_to_f16.cc b/src/cpu/softfloat3e/extF80_to_f16.cc new file mode 100644 index 000000000..5078e689c --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_f16.cc @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float16 extF80_to_f16(extFloat80_t a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool sign; + int32_t exp; + uint64_t sig; + struct commonNaN commonNaN; + uint16_t uiZ, sig16; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) { + softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF16UI(&commonNaN); + } else { + uiZ = packToF16UI(sign, 0x1F, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig16 = softfloat_shortShiftRightJam64(sig, 49); + if (! (exp | sig16)) { + return packToF16UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3FF1; + if (sizeof (int16_t) < sizeof (int32_t)) { + if (exp < -0x40) exp = -0x40; + } + return softfloat_roundPackToF16(sign, exp, sig16, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_f32.cc b/src/cpu/softfloat3e/extF80_to_f32.cc new file mode 100644 index 000000000..558df4c23 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_f32.cc @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 extF80_to_f32(extFloat80_t a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool sign; + int32_t exp; + uint64_t sig; + struct commonNaN commonNaN; + uint32_t uiZ, sig32; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) { + softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF32UI(&commonNaN); + } else { + uiZ = packToF32UI(sign, 0xFF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = softfloat_shortShiftRightJam64(sig, 33); + if (! (exp | sig32)) { + return packToF32UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3F81; + if (sizeof (int16_t) < sizeof (int32_t)) { + if (exp < -0x1000) exp = -0x1000; + } + return softfloat_roundPackToF32(sign, exp, sig32, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_f64.cc b/src/cpu/softfloat3e/extF80_to_f64.cc new file mode 100644 index 000000000..4ba4174e3 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_f64.cc @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 extF80_to_f64(extFloat80_t a, struct softfloat_status_t *status) +{ + uint16_t uiA64; + uint64_t uiA0; + bool sign; + int32_t exp; + uint64_t sig; + struct commonNaN commonNaN; + uint64_t uiZ; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + uiA0 = a.signif; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! (exp | sig)) { + return packToF64UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) { + softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF64UI(&commonNaN); + } else { + uiZ = packToF64UI(sign, 0x7FF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = softfloat_shortShiftRightJam64(sig, 1); + exp -= 0x3C01; + if (sizeof (int16_t) < sizeof (int32_t)) { + if (exp < -0x1000) exp = -0x1000; + } + return softfloat_roundPackToF64(sign, exp, sig, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_i32.cc b/src/cpu/softfloat3e/extF80_to_i32.cc new file mode 100644 index 000000000..ea6c94484 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_i32.cc @@ -0,0 +1,82 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t extF80_to_i32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + bool sign; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x4032 - exp; + if (shiftDist <= 0) shiftDist = 1; + sig = softfloat_shiftRightJam64(sig, shiftDist); + return softfloat_roundToI32(sign, sig, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc new file mode 100644 index 000000000..42415c459 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc @@ -0,0 +1,93 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t extF80_to_i32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + bool sign; + int32_t absZ; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64(uiA64); + if (shiftDist < 33) { + if ((uiA64 == packToExtF80UI64(1, 0x401E)) && (sig < UINT64_C(0x8000000100000000))) { + if (exact && (sig & UINT64_C(0x00000000FFFFFFFF))) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return -0x7FFFFFFF - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + absZ = sig>>shiftDist; + if (exact && ((uint64_t) (uint32_t) absZ< +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t extF80_to_i64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + bool sign; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + uint64_t sigExtra; + struct uint64_extra sig64Extra; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i64_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (shiftDist <= 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (shiftDist) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigExtra = 0; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist); + sig = sig64Extra.v; + sigExtra = sig64Extra.extra; + } + return softfloat_roundToI64(sign, sig, sigExtra, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc new file mode 100644 index 000000000..3500b20d2 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc @@ -0,0 +1,90 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t extF80_to_i64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + bool sign; + int64_t absZ; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i64_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64(uiA64); + if (shiftDist <= 0) { + if ((uiA64 == packToExtF80UI64(1, 0x403E)) && (sig == UINT64_C(0x8000000000000000))) { + return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + absZ = sig>>shiftDist; + if (exact && (uint64_t) (sig<<(-shiftDist & 63))) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return sign ? -absZ : absZ; +} diff --git a/src/cpu/softfloat3e/extF80_to_ui32.cc b/src/cpu/softfloat3e/extF80_to_ui32.cc new file mode 100644 index 000000000..449cafa88 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_ui32.cc @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t + extF80_to_ui32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + bool sign; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x4032 - exp; + if (shiftDist <= 0) shiftDist = 1; + sig = softfloat_shiftRightJam64(sig, shiftDist); + return softfloat_roundToUI32(sign, sig, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc new file mode 100644 index 000000000..7ef100139 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc @@ -0,0 +1,87 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t extF80_to_ui32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + bool sign; + uint32_t z; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64(uiA64); + if (sign || (shiftDist < 32)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + z = sig>>shiftDist; + if (exact && ((uint64_t) z< +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t extF80_to_ui64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + bool sign; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + uint64_t sigExtra; + struct uint64_extra sig64Extra; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui64_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + sign = signExtF80UI64(uiA64); + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (shiftDist < 0) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigExtra = 0; + if (shiftDist) { + sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist); + sig = sig64Extra.v; + sigExtra = sig64Extra.extra; + } + return softfloat_roundToUI64(sign, sig, sigExtra, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc new file mode 100644 index 000000000..78b058754 --- /dev/null +++ b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc @@ -0,0 +1,87 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t extF80_to_ui64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status) +{ + uint16_t uiA64; + int32_t exp; + uint64_t sig; + int32_t shiftDist; + bool sign; + uint64_t z; + + // handle unsupported extended double-precision floating encodings + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui64_fromNaN; + } + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.signExp; + exp = expExtF80UI64(uiA64); + sig = a.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64(uiA64); + if (sign || (shiftDist < 0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + z = sig>>shiftDist; + if (exact && (z< +#include +#include "internals.h" +#include "softfloat.h" + +extern float128_t + softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); +extern float128_t + softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); + +float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool signA; + uint64_t uiB64, uiB0; + bool signB; + + uiA64 = a.v64; + uiA0 = a.v0; + signA = signF128UI64(uiA64); + + uiB64 = b.v64; + uiB0 = b.v0; + signB = signF128UI64(uiB64); + + if (signA == signB) { + return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status); + } else { + return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status); + } +} + +float128_t f128_sub(float128_t a, float128_t b, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool signA; + uint64_t uiB64, uiB0; + bool signB; + + uiA64 = a.v64; + uiA0 = a.v0; + signA = signF128UI64(uiA64); + + uiB64 = b.v64; + uiB0 = b.v0; + signB = signF128UI64(uiB64); + + if (signA == signB) { + return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status); + } else { + return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status); + } +} diff --git a/src/cpu/softfloat3e/f128_div.cc b/src/cpu/softfloat3e/f128_div.cc new file mode 100644 index 000000000..837eb15aa --- /dev/null +++ b/src/cpu/softfloat3e/f128_div.cc @@ -0,0 +1,187 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool signA; + int32_t expA; + struct uint128 sigA; + uint64_t uiB64, uiB0; + bool signB; + int32_t expB; + struct uint128 sigB; + bool signZ; + struct exp32_sig128 normExpSig; + int32_t expZ; + struct uint128 rem; + uint32_t recip32; + int ix; + uint64_t q64; + uint32_t q; + struct uint128 term; + uint32_t qs[3]; + uint64_t sigZExtra; + struct uint128 sigZ, uiZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + signA = signF128UI64(uiA64); + expA = expF128UI64(uiA64); + sigA.v64 = fracF128UI64(uiA64); + sigA.v0 = uiA0; + uiB64 = b.v64; + uiB0 = b.v0; + signB = signF128UI64(uiB64); + expB = expF128UI64(uiB64); + sigB.v64 = fracF128UI64(uiB64); + sigB.v0 = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if (sigA.v64 | sigA.v0) goto propagateNaN; + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN; + goto invalid; + } + goto infinity; + } + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN; + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! (sigB.v64 | sigB.v0)) { + if (! (expA | sigA.v64 | sigA.v0)) goto invalid; + softfloat_raiseFlags(status, softfloat_flag_infinite); + goto infinity; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + if (! (sigA.v64 | sigA.v0)) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x3FFE; + sigA.v64 |= UINT64_C(0x0001000000000000); + sigB.v64 |= UINT64_C(0x0001000000000000); + rem = sigA; + if (softfloat_lt128(sigA.v64, sigA.v0, sigB.v64, sigB.v0)) { + --expZ; + rem = softfloat_add128(sigA.v64, sigA.v0, sigA.v64, sigA.v0); + } + recip32 = softfloat_approxRecip32_1(sigB.v64>>17); + ix = 3; + for (;;) { + q64 = (uint64_t) (uint32_t) (rem.v64>>19) * recip32; + q = (q64 + 0x80000000)>>32; + --ix; + if (ix < 0) break; + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + term = softfloat_mul128By32(sigB.v64, sigB.v0, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + --q; + rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0); + } + qs[ix] = q; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (((q + 1) & 7) < 2) { + rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29); + term = softfloat_mul128By32(sigB.v64, sigB.v0, q); + rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0); + if (rem.v64 & UINT64_C(0x8000000000000000)) { + --q; + rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0); + } else if (softfloat_le128(sigB.v64, sigB.v0, rem.v64, rem.v0)) { + ++q; + rem = softfloat_sub128(rem.v64, rem.v0, sigB.v64, sigB.v0); + } + if (rem.v64 | rem.v0) q |= 1; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigZExtra = (uint64_t) ((uint64_t) q<<60); + term = softfloat_shortShiftLeft128(0, qs[1], 54); + sigZ = softfloat_add128((uint64_t) qs[2]<<19, ((uint64_t) qs[0]<<25) + (q>>4), term.v64, term.v0); + return + softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); + uiZ.v0 = 0; + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ.v64 = packToF128UI64(signZ, 0, 0); + uiZ.v0 = 0; + return uiZ; +} diff --git a/src/cpu/softfloat3e/f128_mul.cc b/src/cpu/softfloat3e/f128_mul.cc new file mode 100644 index 000000000..fd63a4590 --- /dev/null +++ b/src/cpu/softfloat3e/f128_mul.cc @@ -0,0 +1,148 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "primitiveTypes.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool signA; + int32_t expA; + struct uint128 sigA; + uint64_t uiB64, uiB0; + bool signB; + int32_t expB; + struct uint128 sigB; + bool signZ; + uint64_t magBits; + struct exp32_sig128 normExpSig; + int32_t expZ; + uint64_t sig256Z[4]; + uint64_t sigZExtra; + struct uint128 sigZ; + struct uint128_extra sig128Extra; + struct uint128 uiZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + signA = signF128UI64(uiA64); + expA = expF128UI64(uiA64); + sigA.v64 = fracF128UI64(uiA64); + sigA.v0 = uiA0; + uiB64 = b.v64; + uiB0 = b.v0; + signB = signF128UI64(uiB64); + expB = expF128UI64(uiB64); + sigB.v64 = fracF128UI64(uiB64); + sigB.v0 = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) { + goto propagateNaN; + } + magBits = expB | sigB.v64 | sigB.v0; + goto infArg; + } + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN; + magBits = expA | sigA.v64 | sigA.v0; + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! (sigA.v64 | sigA.v0)) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! (sigB.v64 | sigB.v0)) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x4000; + sigA.v64 |= UINT64_C(0x0001000000000000); + sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 16); + softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z); + sigZExtra = sig256Z[indexWord(4, 1)] | (sig256Z[indexWord(4, 0)] != 0); + sigZ = softfloat_add128(sig256Z[indexWord(4, 3)], sig256Z[indexWord(4, 2)], sigA.v64, sigA.v0); + if (UINT64_C(0x0002000000000000) <= sigZ.v64) { + ++expZ; + sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1); + sigZ = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } + return + softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if (! magBits) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + } + uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); + uiZ.v0 = 0; + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ.v64 = packToF128UI64(signZ, 0, 0); + uiZ.v0 = 0; + return uiZ; +} diff --git a/src/cpu/softfloat3e/f128_mulAdd.cc b/src/cpu/softfloat3e/f128_mulAdd.cc new file mode 100644 index 000000000..749342f5f --- /dev/null +++ b/src/cpu/softfloat3e/f128_mulAdd.cc @@ -0,0 +1,332 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "primitiveTypes.h" +#include "softfloat.h" +#include "specialize.h" + +float128_t f128_mulAdd(float128_t a, float128_t b, float128_t c, uint8_t op, struct softfloat_status_t *status) +{ + bool signA; + int32_t expA; + struct uint128 sigA; + bool signB; + int32_t expB; + struct uint128 sigB; + bool signC; + int32_t expC; + struct uint128 sigC; + bool signZ; + uint64_t magBits; + struct uint128 uiZ; + struct exp32_sig128 normExpSig; + int32_t expZ; + uint64_t sig256Z[4]; + struct uint128 sigZ; + int32_t shiftDist, expDiff; + struct uint128 x128; + uint64_t sig256C[4]; + static uint64_t zero256[4] = INIT_UINTM4(0, 0, 0, 0); + uint64_t sigZExtra, sig256Z0; + uint64_t uiA64, uiA0; + uint64_t uiB64, uiB0; + uint64_t uiC64, uiC0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + uiB64 = b.v64; + uiB0 = b.v0; + uiC64 = c.v64; + uiC0 = c.v0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF128UI64(uiA64); + expA = expF128UI64(uiA64); + sigA.v64 = fracF128UI64(uiA64); + sigA.v0 = uiA0; + signB = signF128UI64(uiB64); + expB = expF128UI64(uiB64); + sigB.v64 = fracF128UI64(uiB64); + sigB.v0 = uiB0; + signC = signF128UI64(uiC64) ^ ((op & softfloat_mulAdd_subC) != 0); + expC = expF128UI64(uiC64); + sigC.v64 = fracF128UI64(uiC64); + sigC.v0 = uiC0; + signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) { + goto propagateNaN_ABC; + } + magBits = expB | sigB.v64 | sigB.v0; + goto infProdArg; + } + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN_ABC; + magBits = expA | sigA.v64 | sigA.v0; + goto infProdArg; + } + if (expC == 0x7FFF) { + if (sigC.v64 | sigC.v0) { + uiZ.v64 = 0; + uiZ.v0 = 0; + goto propagateNaN_ZC; + } + uiZ.v64 = uiC64; + uiZ.v0 = uiC0; + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! (sigA.v64 | sigA.v0)) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! (sigB.v64 | sigB.v0)) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FFE; + sigA.v64 |= UINT64_C(0x0001000000000000); + sigB.v64 |= UINT64_C(0x0001000000000000); + sigA = softfloat_shortShiftLeft128(sigA.v64, sigA.v0, 8); + sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 15); + softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z); + sigZ.v64 = sig256Z[indexWord(4, 3)]; + sigZ.v0 = sig256Z[indexWord(4, 2)]; + shiftDist = 0; + if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) { + --expZ; + shiftDist = -1; + } + if (! expC) { + if (! (sigC.v64 | sigC.v0)) { + shiftDist += 8; + goto sigZ; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(sigC.v64, sigC.v0); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC.v64 |= UINT64_C(0x0001000000000000); + sigC = softfloat_shortShiftLeft128(sigC.v64, sigC.v0, 8); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expZ - expC; + if (expDiff < 0) { + expZ = expC; + if ((signZ == signC) || (expDiff < -1)) { + shiftDist -= expDiff; + if (shiftDist) { + sigZ = softfloat_shiftRightJam128(sigZ.v64, sigZ.v0, shiftDist); + } + } else { + if (! shiftDist) { + x128 = softfloat_shortShiftRight128(sig256Z[indexWord(4, 1)], sig256Z[indexWord(4, 0)], 1); + sig256Z[indexWord(4, 1)] = (sigZ.v0<<63) | x128.v64; + sig256Z[indexWord(4, 0)] = x128.v0; + sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, 1); + sig256Z[indexWord(4, 3)] = sigZ.v64; + sig256Z[indexWord(4, 2)] = sigZ.v0; + } + } + } else { + if (shiftDist) softfloat_add256M(sig256Z, sig256Z, sig256Z); + if (! expDiff) { + sigZ.v64 = sig256Z[indexWord(4, 3)]; + sigZ.v0 = sig256Z[indexWord(4, 2)]; + } else { + sig256C[indexWord(4, 3)] = sigC.v64; + sig256C[indexWord(4, 2)] = sigC.v0; + sig256C[indexWord(4, 1)] = 0; + sig256C[indexWord(4, 0)] = 0; + softfloat_shiftRightJam256M(sig256C, expDiff, sig256C); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 8; + if (signZ == signC) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff <= 0) { + sigZ = softfloat_add128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0); + } else { + softfloat_add256M(sig256Z, sig256C, sig256Z); + sigZ.v64 = sig256Z[indexWord(4, 3)]; + sigZ.v0 = sig256Z[indexWord(4, 2)]; + } + if (sigZ.v64 & UINT64_C(0x0200000000000000)) { + ++expZ; + shiftDist = 9; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff < 0) { + signZ = signC; + if (expDiff < -1) { + sigZ = softfloat_sub128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0); + sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)]; + if (sigZExtra) { + sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, 0, 1); + } + if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) { + --expZ; + shiftDist = 7; + } + goto shiftRightRoundPack; + } else { + sig256C[indexWord(4, 3)] = sigC.v64; + sig256C[indexWord(4, 2)] = sigC.v0; + sig256C[indexWord(4, 1)] = 0; + sig256C[indexWord(4, 0)] = 0; + softfloat_sub256M(sig256C, sig256Z, sig256Z); + } + } else if (! expDiff) { + sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, sigC.v64, sigC.v0); + if (! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord(4, 1)] && ! sig256Z[indexWord(4, 0)]) { + goto completeCancellation; + } + sig256Z[indexWord(4, 3)] = sigZ.v64; + sig256Z[indexWord(4, 2)] = sigZ.v0; + if (sigZ.v64 & UINT64_C(0x8000000000000000)) { + signZ = ! signZ; + softfloat_sub256M(zero256, sig256Z, sig256Z); + } + } else { + softfloat_sub256M(sig256Z, sig256C, sig256Z); + if (1 < expDiff) { + sigZ.v64 = sig256Z[indexWord(4, 3)]; + sigZ.v0 = sig256Z[indexWord(4, 2)]; + if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) { + --expZ; + shiftDist = 7; + } + goto sigZ; + } + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigZ.v64 = sig256Z[indexWord(4, 3)]; + sigZ.v0 = sig256Z[indexWord(4, 2)]; + sigZExtra = sig256Z[indexWord(4, 1)]; + sig256Z0 = sig256Z[indexWord(4, 0)]; + if (sigZ.v64) { + if (sig256Z0) sigZExtra |= 1; + } else { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = sigZExtra; + sigZExtra = sig256Z0; + if (! sigZ.v64) { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = sigZExtra; + sigZExtra = 0; + if (! sigZ.v64) { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = 0; + } + } + } + shiftDist = softfloat_countLeadingZeros64(sigZ.v64); + expZ += 7 - shiftDist; + shiftDist = 15 - shiftDist; + if (0 < shiftDist) goto shiftRightRoundPack; + if (shiftDist) { + shiftDist = -shiftDist; + sigZ = softfloat_shortShiftLeft128(sigZ.v64, sigZ.v0, shiftDist); + x128 = softfloat_shortShiftLeft128(0, sigZExtra, shiftDist); + sigZ.v0 |= x128.v64; + sigZExtra = x128.v0; + } + goto roundPack; + } + sigZ: + sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)]; + shiftRightRoundPack: + sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0); + sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, shiftDist); + roundPack: + return softfloat_roundPackToF128(signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN_ABC: + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); + goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if ((sigC.v64 | sigC.v0) && expC == 0x7FFF) goto propagateNaN_ZC; + if (magBits) { + uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); + uiZ.v0 = 0; + if (expC != 0x7FFF) return uiZ; + if (signZ == signC) return uiZ; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + propagateNaN_ZC: + uiZ = softfloat_propagateNaNF128UI(uiZ.v64, uiZ.v0, uiC64, uiC0, status); + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ.v64 = uiC64; + uiZ.v0 = uiC0; + if (! (expC | sigC.v64 | sigC.v0) && (signZ != signC)) { + completeCancellation: + uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + uiZ.v0 = 0; + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f128_roundToInt.cc b/src/cpu/softfloat3e/f128_roundToInt.cc new file mode 100644 index 000000000..c3b728704 --- /dev/null +++ b/src/cpu/softfloat3e/f128_roundToInt.cc @@ -0,0 +1,142 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t + f128_roundToInt(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + int32_t exp; + struct uint128 uiZ; + uint64_t lastBitMask0, roundBitsMask; + bool roundNearEven; + uint64_t lastBitMask64; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + exp = expF128UI64(uiA64); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x402F <= exp) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (0x406F <= exp) { + if ((exp == 0x7FFF) && (fracF128UI64(uiA64) | uiA0)) { + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status); + return uiZ; + } + return a; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + lastBitMask0 = (uint64_t) 2<<(0x406E - exp); + roundBitsMask = lastBitMask0 - 1; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + roundNearEven = (roundingMode == softfloat_round_near_even); + if (roundNearEven || (roundingMode == softfloat_round_near_maxMag)) { + if (exp == 0x402F) { + if (UINT64_C(0x8000000000000000) <= uiZ.v0) { + ++uiZ.v64; + if (roundNearEven && (uiZ.v0 == UINT64_C(0x8000000000000000))) { + uiZ.v64 &= ~1; + } + } + } else { + uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, lastBitMask0>>1); + if (roundNearEven && !(uiZ.v0 & roundBitsMask)) { + uiZ.v0 &= ~lastBitMask0; + } + } + } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) { + uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, roundBitsMask); + } + uiZ.v0 &= ~roundBitsMask; + lastBitMask64 = !lastBitMask0; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (exp < 0x3FFF) { + if (!((uiA64 & UINT64_C(0x7FFFFFFFFFFFFFFF)) | uiA0)) return a; + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + uiZ.v64 = uiA64 & packToF128UI64(1, 0, 0); + uiZ.v0 = 0; + switch (roundingMode) { + case softfloat_round_near_even: + if (!(fracF128UI64(uiA64) | uiA0)) break; + case softfloat_round_near_maxMag: + if (exp == 0x3FFE) uiZ.v64 |= packToF128UI64(0, 0x3FFF, 0); + break; + case softfloat_round_min: + if (uiZ.v64) uiZ.v64 = packToF128UI64(1, 0x3FFF, 0); + break; + case softfloat_round_max: + if (!uiZ.v64) uiZ.v64 = packToF128UI64(0, 0x3FFF, 0); + break; + } + return uiZ; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + uiZ.v64 = uiA64; + uiZ.v0 = 0; + lastBitMask64 = (uint64_t) 1<<(0x402F - exp); + roundBitsMask = lastBitMask64 - 1; + if (roundingMode == softfloat_round_near_maxMag) { + uiZ.v64 += lastBitMask64>>1; + } else if (roundingMode == softfloat_round_near_even) { + uiZ.v64 += lastBitMask64>>1; + if (!((uiZ.v64 & roundBitsMask) | uiA0)) { + uiZ.v64 &= ~lastBitMask64; + } + } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) { + uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask; + } + uiZ.v64 &= ~roundBitsMask; + lastBitMask0 = 0; + } + if ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f128_to_extF80.cc b/src/cpu/softfloat3e/f128_to_extF80.cc new file mode 100644 index 000000000..916820bc9 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_extF80.cc @@ -0,0 +1,94 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t frac64, frac0; + struct commonNaN commonNaN; + struct uint128 uiZ; + uint16_t uiZ64; + uint64_t uiZ0; + struct exp32_sig128 normExpSig; + struct uint128 sig128; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + frac64 = fracF128UI64(uiA64); + frac0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (frac64 | frac0) { + softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToExtF80UI(&commonNaN); + uiZ64 = uiZ.v64; + uiZ0 = uiZ.v0; + } else { + uiZ64 = packToExtF80UI64(sign, 0x7FFF); + uiZ0 = UINT64_C(0x8000000000000000); + } + return packToExtF80_twoargs(uiZ64, uiZ0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! (frac64 | frac0)) { + return packToExtF80(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF128Sig(frac64, frac0); + exp = normExpSig.exp; + frac64 = normExpSig.sig.v64; + frac0 = normExpSig.sig.v0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig128 = softfloat_shortShiftLeft128(frac64 | UINT64_C(0x0001000000000000), frac0, 15); + return softfloat_roundPackToExtF80(sign, exp, sig128.v64, sig128.v0, 80, status); +} diff --git a/src/cpu/softfloat3e/f128_to_f32.cc b/src/cpu/softfloat3e/f128_to_f32.cc new file mode 100644 index 000000000..485d68a0c --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_f32.cc @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f128_to_f32(float128_t a, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t frac64; + struct commonNaN commonNaN; + uint32_t uiZ, frac32; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + frac64 = fracF128UI64(uiA64) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (frac64) { + softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF32UI(&commonNaN); + } else { + uiZ = packToF32UI(sign, 0xFF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac32 = softfloat_shortShiftRightJam64(frac64, 18); + if (! (exp | frac32)) { + return packToF32UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3F81; + if (sizeof (int16_t) < sizeof (int32_t)) { + if (exp < -0x1000) exp = -0x1000; + } + return softfloat_roundPackToF32(sign, exp, frac32 | 0x40000000, status); +} diff --git a/src/cpu/softfloat3e/f128_to_f64.cc b/src/cpu/softfloat3e/f128_to_f64.cc new file mode 100644 index 000000000..0809c7102 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_f64.cc @@ -0,0 +1,87 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f128_to_f64(float128_t a, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t frac64, frac0; + struct commonNaN commonNaN; + uint64_t uiZ; + struct uint128 frac128; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + frac64 = fracF128UI64(uiA64); + frac0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FFF) { + if (frac64 | frac0) { + softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status); + uiZ = softfloat_commonNaNToF64UI(&commonNaN); + } else { + uiZ = packToF64UI(sign, 0x7FF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac128 = softfloat_shortShiftLeft128(frac64, frac0, 14); + frac64 = frac128.v64 | (frac128.v0 != 0); + if (! (exp | frac64)) { + return packToF64UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3C01; + if (sizeof (int16_t) < sizeof (int32_t)) { + if (exp < -0x1000) exp = -0x1000; + } + return + softfloat_roundPackToF64(sign, exp, frac64 | UINT64_C(0x4000000000000000), status); +} diff --git a/src/cpu/softfloat3e/f128_to_i32.cc b/src/cpu/softfloat3e/f128_to_i32.cc new file mode 100644 index 000000000..68cf2b3a7 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_i32.cc @@ -0,0 +1,80 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64, sig0; + int32_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ((exp == 0x7FFF) && (sig64 | sig0)) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig64 |= UINT64_C(0x0001000000000000); + sig64 |= (sig0 != 0); + shiftDist = 0x4023 - exp; + if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist); + return softfloat_roundToI32(sign, sig64, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc new file mode 100644 index 000000000..a62233d4d --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + int32_t exp; + uint64_t sig64; + int32_t shiftDist; + bool sign; + int32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (49 <= shiftDist) { + if (exact && (exp | sig64)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI64(uiA64); + if (shiftDist < 18) { + if (sign && (shiftDist == 17) && (sig64 < UINT64_C(0x0000000000020000))) { + if (exact && sig64) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return -0x7FFFFFFF - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && sig64 ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig64 |= UINT64_C(0x0001000000000000); + absZ = sig64>>shiftDist; + if (exact && ((uint64_t) (uint32_t) absZ< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64, sig0; + int32_t shiftDist; + struct uint128 sig128; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (shiftDist <= 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (shiftDist < -15) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C(0x0001000000000000); + if (shiftDist) { + sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (exp) sig64 |= UINT64_C(0x0001000000000000); + sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist); + sig64 = sigExtra.v; + sig0 = sigExtra.extra; + } + return softfloat_roundToI64(sign, sig64, sig0, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc new file mode 100644 index 000000000..edeccf182 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc @@ -0,0 +1,104 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64, sig0; + int32_t shiftDist; + int8_t negShiftDist; + uint64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (shiftDist < 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (shiftDist < -14) { + if ((uiA64 == UINT64_C(0xC03E000000000000)) && (sig0 < UINT64_C(0x0002000000000000))) { + if (exact && sig0) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FFF) && (sig64 | sig0) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C(0x0001000000000000); + negShiftDist = -shiftDist; + absZ = sig64<>(shiftDist & 63); + if (exact && (uint64_t) (sig0<>shiftDist; + if (exact && (sig0 || (absZ< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64; + int32_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ((exp == 0x7FFF) && sig64) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig64 |= UINT64_C(0x0001000000000000); + shiftDist = 0x4023 - exp; + if (0 < shiftDist) { + sig64 = softfloat_shiftRightJam64(sig64, shiftDist); + } + return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status); +} + diff --git a/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc new file mode 100644 index 000000000..96007f6a1 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + int32_t exp; + uint64_t sig64; + int32_t shiftDist; + bool sign; + uint32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (49 <= shiftDist) { + if (exact && (exp | sig64)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI64(uiA64); + if (sign || (shiftDist < 17)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && sig64 ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig64 |= UINT64_C(0x0001000000000000); + z = sig64>>shiftDist; + if (exact && ((uint64_t) z< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64, sig0; + int32_t shiftDist; + struct uint128 sig128; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (shiftDist <= 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (shiftDist < -15) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C(0x0001000000000000); + if (shiftDist) { + sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (exp) sig64 |= UINT64_C(0x0001000000000000); + sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist); + sig64 = sigExtra.v; + sig0 = sigExtra.extra; + } + return softfloat_roundToUI64(sign, sig64, sig0, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc new file mode 100644 index 000000000..8d30420b0 --- /dev/null +++ b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc @@ -0,0 +1,99 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) +{ + uint64_t uiA64, uiA0; + bool sign; + int32_t exp; + uint64_t sig64, sig0; + int32_t shiftDist; + int8_t negShiftDist; + uint64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA64 = a.v64; + uiA0 = a.v0; + sign = signF128UI64(uiA64); + exp = expF128UI64(uiA64); + sig64 = fracF128UI64(uiA64); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if (shiftDist < 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (sign || (shiftDist < -15)) goto invalid; + sig64 |= UINT64_C(0x0001000000000000); + negShiftDist = -shiftDist; + z = sig64<>(shiftDist & 63); + if (exact && (uint64_t) (sig0<>shiftDist; + if (exact && (sig0 || (z< +#include +#include "internals.h" +#include "softfloat.h" + +extern float16 softfloat_addMagsF16(uint16_t, uint16_t, struct softfloat_status_t *); +extern float16 softfloat_subMagsF16(uint16_t, uint16_t, struct softfloat_status_t *); + +float16 f16_add(float16 a, float16 b, struct softfloat_status_t *status) +{ + if (signF16UI((uint16_t) a ^ (uint16_t) b)) { + return softfloat_subMagsF16(a, b, status); + } else { + return softfloat_addMagsF16(a, b, status); + } +} + +float16 f16_sub(float16 a, float16 b, struct softfloat_status_t *status) +{ + if (signF16UI((uint16_t) a ^ (uint16_t) b)) { + return softfloat_addMagsF16(a, b, status); + } else { + return softfloat_subMagsF16(a, b, status); + } +} diff --git a/src/cpu/softfloat3e/f16_class.c b/src/cpu/softfloat3e/f16_class.c new file mode 100644 index 000000000..b375c1544 --- /dev/null +++ b/src/cpu/softfloat3e/f16_class.c @@ -0,0 +1,64 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +softfloat_class_t f16_class(float16 a) +{ + bool signA; + int8_t expA; + uint16_t sigA; + + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + + if (expA == 0x1F) { + if (sigA == 0) + return (signA) ? softfloat_negative_inf : softfloat_positive_inf; + + return (sigA & 0x200) ? softfloat_QNaN : softfloat_SNaN; + } + + if (expA == 0) { + if (sigA == 0) return softfloat_zero; + return softfloat_denormal; + } + + return softfloat_normalized; +} diff --git a/src/cpu/softfloat3e/f16_compare.c b/src/cpu/softfloat3e/f16_compare.c new file mode 100644 index 000000000..1cfd56bec --- /dev/null +++ b/src/cpu/softfloat3e/f16_compare.c @@ -0,0 +1,92 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two half precision floating point numbers. Returns +| 'float_relation_equal' if the operands are equal, 'float_relation_less' if +| the value 'a' is less than the corresponding value `b', +| 'float_relation_greater' if the value 'a' is greater than the corresponding +| value `b', or 'float_relation_unordered' otherwise. +*----------------------------------------------------------------------------*/ + +int f16_compare(float16 a, float16 b, bool quiet, struct softfloat_status_t *status) +{ + softfloat_class_t aClass; + softfloat_class_t bClass; + bool signA; + bool signB; + + aClass = f16_class(a); + bClass = f16_class(b); + + if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) { + if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + a = a & 0x8000; + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if (bClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + b = b & 0x8000; + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if ((a == b) || ((uint16_t) ((a | b)<<1) == 0)) return softfloat_relation_equal; + + signA = signF16UI(a); + signB = signF16UI(b); + if (signA != signB) + return (signA) ? softfloat_relation_less : softfloat_relation_greater; + + if (signA ^ (a < b)) return softfloat_relation_less; + return softfloat_relation_greater; +} diff --git a/src/cpu/softfloat3e/f16_div.c b/src/cpu/softfloat3e/f16_div.c new file mode 100644 index 000000000..c91760b03 --- /dev/null +++ b/src/cpu/softfloat3e/f16_div.c @@ -0,0 +1,149 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +#define SOFTFLOAT_FAST_DIV32TO16 1 + +extern const uint16_t softfloat_approxRecip_1k0s[]; +extern const uint16_t softfloat_approxRecip_1k1s[]; + +float16 f16_div(float16 a, float16 b, struct softfloat_status_t *status) +{ + bool signA; + int8_t expA; + uint16_t sigA; + bool signB; + int8_t expB; + uint16_t sigB; + bool signZ; + struct exp8_sig16 normExpSig; + int8_t expZ; +#ifdef SOFTFLOAT_FAST_DIV32TO16 + uint32_t sig32A; + uint16_t sigZ; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + signB = signF16UI(b); + expB = expF16UI(b); + sigB = fracF16UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x1F) { + if (sigA) goto propagateNaN; + if (expB == 0x1F) { + if (sigB) goto propagateNaN; + goto invalid; + } + if (sigB && !expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infinity; + } + if (expB == 0x1F) { + if (sigB) goto propagateNaN; + if (sigA && !expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! sigB) { + if (! (expA | sigA)) goto invalid; + softfloat_raiseFlags(status, softfloat_flag_infinite); + goto infinity; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + if (! sigA) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0xE; + sigA |= 0x0400; + sigB |= 0x0400; +#ifdef SOFTFLOAT_FAST_DIV32TO16 + if (sigA < sigB) { + --expZ; + sig32A = (uint32_t) sigA<<15; + } else { + sig32A = (uint32_t) sigA<<14; + } + sigZ = sig32A / sigB; + if (! (sigZ & 7)) sigZ |= ((uint32_t) sigB * sigZ != sig32A); +#endif + return softfloat_roundPackToF16(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF16UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + return packToF16UI(signZ, 0x1F, 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF16UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f16_getExp.c b/src/cpu/softfloat3e/f16_getExp.c new file mode 100644 index 000000000..dfade995f --- /dev/null +++ b/src/cpu/softfloat3e/f16_getExp.c @@ -0,0 +1,73 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the exponent portion of half-precision floating-point value 'a', +| and returns the result as a half-precision floating-point value +| representing unbiased integer exponent. The operation is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float16 f16_getExp(float16 a, struct softfloat_status_t *status) +{ + int8_t expA; + uint16_t sigA; + struct exp8_sig16 normExpSig; + + expA = expF16UI(a); + sigA = fracF16UI(a); + + if (expA == 0x1F) { + if (sigA) return softfloat_propagateNaNF16UI(a, 0, status); + return (float16)packToF32UI(0, 0x1F, 0); + } + + if (! expA) { + if (! sigA || softfloat_denormalsAreZeros(status)) + return (float16)packToF32UI(1, 0x1F, 0); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + } + + return i32_to_f16((int32_t)(expA) - 0xF, status); +} diff --git a/src/cpu/softfloat3e/f16_getMant.c b/src/cpu/softfloat3e/f16_getMant.c new file mode 100644 index 000000000..f0d8d5482 --- /dev/null +++ b/src/cpu/softfloat3e/f16_getMant.c @@ -0,0 +1,108 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the mantissa of half-precision floating-point value 'a' and +| returns the result as a half-precision floating-point after applying +| the mantissa interval normalization and sign control. The operation is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float16 f16_getMant(float16 a, struct softfloat_status_t *status, int sign_ctrl, int interv) +{ + bool signA; + int8_t expA; + uint16_t sigA; + struct exp8_sig16 normExpSig; + + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + + if (expA == 0x1F) { + if (sigA) return softfloat_propagateNaNF16UI(a, 0, status); + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; + } + } + return packToF16UI(~sign_ctrl & signA, 0x1F, 0); + } + + if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) { + return packToF16UI(~sign_ctrl & signA, 0x1F, 0); + } + + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; + } + } + + if (expA == 0) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + sigA &= 0x3ff; + } + + switch(interv) { + case 0x0: // interval [1,2) + expA = 0xF; + break; + case 0x1: // interval [1/2,2) + expA -= 0xF; + expA = 0xF - (expA & 0x1); + break; + case 0x2: // interval [1/2,1) + expA = 0xE; + break; + case 0x3: // interval [3/4,3/2) + expA = 0xF - ((sigA >> 9) & 0x1); + break; + } + + return packToF16UI(~sign_ctrl & signA, expA, sigA); +} diff --git a/src/cpu/softfloat3e/f16_minmax.c b/src/cpu/softfloat3e/f16_minmax.c new file mode 100644 index 000000000..11922a1ba --- /dev/null +++ b/src/cpu/softfloat3e/f16_minmax.c @@ -0,0 +1,69 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two half precision floating point numbers and return the +| smaller of them. +*----------------------------------------------------------------------------*/ + +float16 f16_min(float16 a, float16 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f16_denormal_to_zero(a); + b = f16_denormal_to_zero(b); + } + + return (f16_compare_normal(a, b, status) == softfloat_relation_less) ? a : b; +} + +/*---------------------------------------------------------------------------- +| Compare between two half precision floating point numbers and return the +| larger of them. +*----------------------------------------------------------------------------*/ + +float16 f16_max(float16 a, float16 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f16_denormal_to_zero(a); + b = f16_denormal_to_zero(b); + } + + return (f16_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b; +} diff --git a/src/cpu/softfloat3e/f16_mul.c b/src/cpu/softfloat3e/f16_mul.c new file mode 100644 index 000000000..2e7e74826 --- /dev/null +++ b/src/cpu/softfloat3e/f16_mul.c @@ -0,0 +1,139 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16 f16_mul(float16 a, float16 b, struct softfloat_status_t *status) +{ + bool signA; + int8_t expA; + uint16_t sigA; + bool signB; + int8_t expB; + uint16_t sigB; + bool signZ; + uint16_t magBits; + struct exp8_sig16 normExpSig; + int8_t expZ; + uint32_t sig32Z; + uint16_t sigZ, uiZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + signB = signF16UI(b); + expB = expF16UI(b); + sigB = fracF16UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x1F) { + if (sigA || ((expB == 0x1F) && sigB)) goto propagateNaN; + magBits = expB | sigB; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + if (expB == 0x1F) { + if (sigB) goto propagateNaN; + magBits = expA | sigA; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) { + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0xF; + sigA = (sigA | 0x0400)<<4; + sigB = (sigB | 0x0400)<<5; + sig32Z = (uint32_t) sigA * sigB; + sigZ = sig32Z>>16; + if (sig32Z & 0xFFFF) sigZ |= 1; + if (sigZ < 0x4000) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF16(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF16UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if (! magBits) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ = defaultNaNF16UI; + } else { + uiZ = packToF16UI(signZ, 0x1F, 0); + } + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF16UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f16_mulAdd.c b/src/cpu/softfloat3e/f16_mulAdd.c new file mode 100644 index 000000000..0e630a9b7 --- /dev/null +++ b/src/cpu/softfloat3e/f16_mulAdd.c @@ -0,0 +1,232 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" +#include "specialize.h" + +float16 f16_mulAdd(float16 a, float16 b, float16 c, uint8_t op, struct softfloat_status_t *status) +{ + bool signA; + int8_t expA; + uint16_t sigA; + bool signB; + int8_t expB; + uint16_t sigB; + bool signC; + int8_t expC; + uint16_t sigC; + bool signProd; + uint16_t magBits, uiA, uiB, uiC, uiZ; + struct exp8_sig16 normExpSig; + int8_t expProd; + uint32_t sigProd; + bool signZ; + int8_t expZ; + uint16_t sigZ; + int8_t expDiff; + uint32_t sig32Z, sig32C; + int8_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA = a; + uiB = b; + uiC = c; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI(uiA); + expA = expF16UI(uiA); + sigA = fracF16UI(uiA); + signB = signF16UI(uiB); + expB = expF16UI(uiB); + sigB = fracF16UI(uiB); + signC = signF16UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0); + expC = expF16UI(uiC); + sigC = fracF16UI(uiC); + signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + bool aisNaN = (expA == 0x1F) && sigA; + bool bisNaN = (expB == 0x1F) && sigB; + bool cisNaN = (expC == 0x1F) && sigC; + if (aisNaN | bisNaN | cisNaN) { + uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF16UI(uiA, uiB, status) : 0; + return softfloat_propagateNaNF16UI(uiZ, uiC, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + if (!expC) sigC = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x1F) { + magBits = expB | sigB; + goto infProdArg; + } + if (expB == 0x1F) { + magBits = expA | sigA; + goto infProdArg; + } + if (expC == 0x1F) { + if ((sigA && !expA) || (sigB && !expB)) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + return packToF16UI(signC, 0x1F, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expProd = expA + expB - 0xE; + sigA = (sigA | 0x0400)<<4; + sigB = (sigB | 0x0400)<<4; + sigProd = (uint32_t) sigA * sigB; + if (sigProd < 0x20000000) { + --expProd; + sigProd <<= 1; + } + signZ = signProd; + if (! expC) { + if (! sigC) { + expZ = expProd - 1; + sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0); + goto roundPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigC); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | 0x0400)<<3; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expProd - expC; + if (signProd == signC) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff <= 0) { + expZ = expC; + sigZ = sigC + softfloat_shiftRightJam32(sigProd, 16 - expDiff); + } else { + expZ = expProd; + sig32Z = sigProd + softfloat_shiftRightJam32((uint32_t) sigC<<16, expDiff); + sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0); + } + if (sigZ < 0x4000) { + --expZ; + sigZ <<= 1; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig32C = (uint32_t) sigC<<16; + if (expDiff < 0) { + signZ = signC; + expZ = expC; + sig32Z = sig32C - softfloat_shiftRightJam32(sigProd, -expDiff); + } else if (! expDiff) { + expZ = expProd; + sig32Z = sigProd - sig32C; + if (! sig32Z) goto completeCancellation; + if (sig32Z & 0x80000000) { + signZ = ! signZ; + sig32Z = -sig32Z; + } + } else { + expZ = expProd; + sig32Z = sigProd - softfloat_shiftRightJam32(sig32C, expDiff); + } + shiftDist = softfloat_countLeadingZeros32(sig32Z) - 1; + expZ -= shiftDist; + shiftDist -= 16; + if (shiftDist < 0) { + sigZ = sig32Z>>(-shiftDist) | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0); + } else { + sigZ = (uint16_t) sig32Z< +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16 f16_range(float16 a, float16 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status) +{ + bool signA; + int8_t expA; + uint16_t sigA; + bool signB; + int8_t expB; + uint16_t sigB; + bool aIsNaN, bIsNaN; + uint16_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + signB = signF16UI(b); + expB = expF16UI(b); + sigB = fracF16UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_isSigNaNF16UI(a)) { + return softfloat_propagateNaNF16UI(a, 0, status); + } + if (softfloat_isSigNaNF16UI(b)) { + return softfloat_propagateNaNF16UI(b, 0, status); + } + + aIsNaN = isNaNF16UI(a); + bIsNaN = isNaNF16UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA && sigA) { + if (softfloat_denormalsAreZeros(status)) { + a = packToF16UI(signA, 0, 0); + } + else if (! bIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + + if (! expB && sigB) { + if (softfloat_denormalsAreZeros(status)) { + b = packToF16UI(signB, 0, 0); + } + else if (! aIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (bIsNaN) { + z = a; + } + else if (aIsNaN) { + z = b; + } + else if (signA != signB && ! is_abs) { + if (! is_max) { + z = signA ? a : b; + } else { + z = signA ? b : a; + } + } else { + float16 tmp_a = a, tmp_b = b; + if (is_abs) { + tmp_a = tmp_a & ~0x8000; // clear the sign bit + tmp_b = tmp_b & ~0x8000; + signA = 0; + } + + if (! is_max) { + z = (signA ^ (tmp_a < tmp_b)) ? a : b; + } else { + z = (signA ^ (tmp_a < tmp_b)) ? b : a; + } + } + + switch(sign_ctrl) { + case 0: + z = (z & ~0x8000) | (a & 0x8000); // keep sign of a + break; + case 1: + break; // preserve sign of compare result + case 2: + z = z & ~0x8000; // zero out the sign bit + break; + case 3: + z = z | 0x8000; // set the sign bit + break; + } + + return z; +} diff --git a/src/cpu/softfloat3e/f16_roundToInt.c b/src/cpu/softfloat3e/f16_roundToInt.c new file mode 100644 index 000000000..ee9be0c0b --- /dev/null +++ b/src/cpu/softfloat3e/f16_roundToInt.c @@ -0,0 +1,112 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16 f16_roundToInt(float16 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + int8_t exp; + uint16_t frac; + bool sign; + uint16_t uiZ, lastBitMask, roundBitsMask; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + scale &= 0xF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF16UI(a); + frac = fracF16UI(a); + sign = signF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x19 <= (exp + scale)) { + if ((exp == 0x1F) && frac) { + return softfloat_propagateNaNF16UI(a, 0, status); + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!exp) { + frac = 0; + a = packToF16UI(sign, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((exp + scale) <= 0xE) { + if (!(exp | frac)) return a; + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + uiZ = packToF16UI(sign, 0, 0); + switch (roundingMode) { + case softfloat_round_near_even: + if (!frac) break; + case softfloat_round_near_maxMag: + if ((exp + scale) == 0xE) uiZ |= packToF16UI(0, 0xF - scale, 0); + break; + case softfloat_round_min: + if (uiZ) uiZ = packToF16UI(1, 0xF - scale, 0); + break; + case softfloat_round_max: + if (!uiZ) uiZ = packToF16UI(0, 0xF - scale, 0); + break; + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = a; + lastBitMask = (uint16_t) 1<<(0x19 - exp - scale); + roundBitsMask = lastBitMask - 1; + if (roundingMode == softfloat_round_near_maxMag) { + uiZ += lastBitMask>>1; + } else if (roundingMode == softfloat_round_near_even) { + uiZ += lastBitMask>>1; + if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask; + } else if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) { + uiZ += roundBitsMask; + } + uiZ &= ~roundBitsMask; + if (uiZ != a) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f16_sqrt.c b/src/cpu/softfloat3e/f16_sqrt.c new file mode 100644 index 000000000..f0f8afef1 --- /dev/null +++ b/src/cpu/softfloat3e/f16_sqrt.c @@ -0,0 +1,130 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; + +float16 f16_sqrt(float16 a, struct softfloat_status_t *status) +{ + bool signA; + int8_t expA; + uint16_t sigA; + struct exp8_sig16 normExpSig; + int8_t expZ; + int index; + uint16_t r0; + uint32_t ESqrR0; + uint16_t sigma0; + uint16_t recipSqrt16, sigZ, shiftedSigZ; + uint16_t negRem; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI(a); + expA = expF16UI(a); + sigA = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x1F) { + if (sigA) { + return softfloat_propagateNaNF16UI(a, 0, status); + } + if (! signA) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + a = packToF16UI(signA, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (signA) { + if (! (expA | sigA)) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = ((expA - 0xF)>>1) + 0xE; + expA &= 1; + sigA |= 0x0400; + index = (sigA>>6 & 0xE) + expA; + r0 = softfloat_approxRecipSqrt_1k0s[index] + - (((uint32_t) softfloat_approxRecipSqrt_1k1s[index] * (sigA & 0x7F)) >>11); + ESqrR0 = ((uint32_t) r0 * r0)>>1; + if (expA) ESqrR0 >>= 1; + sigma0 = ~(uint16_t) ((ESqrR0 * sigA)>>16); + recipSqrt16 = r0 + (((uint32_t) r0 * sigma0)>>25); + if (! (recipSqrt16 & 0x8000)) recipSqrt16 = 0x8000; + sigZ = ((uint32_t) (sigA<<5) * recipSqrt16)>>16; + if (expA) sigZ >>= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + ++sigZ; + if (! (sigZ & 7)) { + shiftedSigZ = sigZ>>1; + negRem = shiftedSigZ * shiftedSigZ; + sigZ &= ~1; + if (negRem & 0x8000) { + sigZ |= 1; + } else { + if (negRem) --sigZ; + } + } + return softfloat_roundPackToF16(0, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; +} diff --git a/src/cpu/softfloat3e/f16_to_extF80.cc b/src/cpu/softfloat3e/f16_to_extF80.cc new file mode 100644 index 000000000..418be8083 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_extF80.cc @@ -0,0 +1,88 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t f16_to_extF80(float16 a, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + uint16_t uiZ64; + uint64_t uiZ0; + struct exp8_sig16 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + if (frac) { + softfloat_f16UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToExtF80UI(&commonNaN); + uiZ64 = uiZ.v64; + uiZ0 = uiZ.v0; + } else { + uiZ64 = packToExtF80UI64(sign, 0x7FFF); + uiZ0 = UINT64_C(0x8000000000000000); + } + return packToExtF80_twoargs(uiZ64, uiZ0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac) { + return packToExtF80(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(frac); + exp = normExpSig.exp; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ64 = packToExtF80UI64(sign, exp + 0x3FF0); + uiZ0 = (uint64_t) (frac | 0x0400)<<53; + return packToExtF80_twoargs(uiZ64, uiZ0); +} diff --git a/src/cpu/softfloat3e/f16_to_f32.c b/src/cpu/softfloat3e/f16_to_f32.c new file mode 100644 index 000000000..4d862161d --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_f32.c @@ -0,0 +1,81 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f16_to_f32(float16 a, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + struct commonNaN commonNaN; + uint32_t uiZ; + struct exp8_sig16 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + if (frac) { + softfloat_f16UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF32UI(&commonNaN); + } else { + uiZ = packToF32UI(sign, 0xFF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac || softfloat_denormalsAreZeros(status)) { + return packToF32UI(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(frac); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF32UI(sign, exp + 0x70, (uint32_t) frac<<13); +} diff --git a/src/cpu/softfloat3e/f16_to_f64.c b/src/cpu/softfloat3e/f16_to_f64.c new file mode 100644 index 000000000..7d61b6357 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_f64.c @@ -0,0 +1,81 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f16_to_f64(float16 a, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + struct commonNaN commonNaN; + uint64_t uiZ; + struct exp8_sig16 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + if (frac) { + softfloat_f16UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF64UI(&commonNaN); + } else { + uiZ = packToF64UI(sign, 0x7FF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac || softfloat_denormalsAreZeros(status)) { + return packToF64UI(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF16Sig(frac); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF64UI(sign, exp + 0x3F0, (uint64_t) frac<<42); +} diff --git a/src/cpu/softfloat3e/f16_to_i32.c b/src/cpu/softfloat3e/f16_to_i32.c new file mode 100644 index 000000000..d00cfe236 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_i32.c @@ -0,0 +1,81 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f16_to_i32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + int32_t sig32; + int8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + frac ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if (exp) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if (0 <= shiftDist) { + sig32 <<= shiftDist; + return sign ? -sig32 : sig32; + } + shiftDist = exp - 0x0D; + if (0 < shiftDist) sig32 <<= shiftDist; + } + else { + if (softfloat_denormalsAreZeros(status)) sig32 = 0; + } + return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status); +} + diff --git a/src/cpu/softfloat3e/f16_to_i32_r_minMag.c b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c new file mode 100644 index 000000000..9a6bbdf83 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c @@ -0,0 +1,82 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f16_to_i32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status) +{ + int8_t exp; + uint16_t frac; + int8_t shiftDist; + bool sign; + int32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF16UI(a); + frac = fracF16UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && frac) frac = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if (shiftDist < 0) { + if (exact && (exp | frac)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x1F) && frac + ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (int32_t) (frac | 0x0400)<>= 10; + return sign ? -alignedSig : alignedSig; +} diff --git a/src/cpu/softfloat3e/f16_to_i64.c b/src/cpu/softfloat3e/f16_to_i64.c new file mode 100644 index 000000000..7dcbeaad8 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_i64.c @@ -0,0 +1,80 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f16_to_i64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + int32_t sig32; + int8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + frac ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if (exp) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if (0 <= shiftDist) { + sig32 <<= shiftDist; + return sign ? -sig32 : sig32; + } + shiftDist = exp - 0x0D; + if (0 < shiftDist) sig32 <<= shiftDist; + } + else { + if (softfloat_denormalsAreZeros(status)) sig32 = 0; + } + return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f16_to_i64_r_minMag.c b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c new file mode 100644 index 000000000..4289c5352 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c @@ -0,0 +1,82 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f16_to_i64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status) +{ + int8_t exp; + uint16_t frac; + int8_t shiftDist; + bool sign; + int32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF16UI(a); + frac = fracF16UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && frac) frac = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if (shiftDist < 0) { + if (exact && (exp | frac)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x1F) && frac + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (int32_t) (frac | 0x0400)<>= 10; + return sign ? -alignedSig : alignedSig; +} diff --git a/src/cpu/softfloat3e/f16_to_ui32.c b/src/cpu/softfloat3e/f16_to_ui32.c new file mode 100644 index 000000000..d217b2627 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_ui32.c @@ -0,0 +1,79 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f16_to_ui32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + uint32_t sig32; + int8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + frac ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if (exp) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ((0 <= shiftDist) && ! sign) { + return sig32< +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f16_to_ui32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status) +{ + int8_t exp; + uint16_t frac; + int8_t shiftDist; + bool sign; + uint32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF16UI(a); + frac = fracF16UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && frac) frac = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if (shiftDist < 0) { + if (exact && (exp | frac)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + if (sign || (exp == 0x1F)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x1F) && frac + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (uint32_t) (frac | 0x0400)<>10; +} diff --git a/src/cpu/softfloat3e/f16_to_ui64.c b/src/cpu/softfloat3e/f16_to_ui64.c new file mode 100644 index 000000000..351edb32c --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_ui64.c @@ -0,0 +1,79 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f16_to_ui64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int8_t exp; + uint16_t frac; + uint32_t sig32; + int8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + exp = expF16UI(a); + frac = fracF16UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x1F) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + frac ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if (exp) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ((0 <= shiftDist) && ! sign) { + return sig32<>12, (uint64_t) sig32<<52, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c new file mode 100644 index 000000000..d80d6e8f5 --- /dev/null +++ b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c @@ -0,0 +1,81 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f16_to_ui64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status) +{ + int8_t exp; + uint16_t frac; + int8_t shiftDist; + bool sign; + uint32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF16UI(a); + frac = fracF16UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && frac) frac = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if (shiftDist < 0) { + if (exact && (exp | frac)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI(a); + if (sign || (exp == 0x1F)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x1F) && frac + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (uint32_t) (frac | 0x0400)<>10; +} diff --git a/src/cpu/softfloat/f2xm1.cc b/src/cpu/softfloat3e/f2xm1.cc similarity index 77% rename from src/cpu/softfloat/f2xm1.cc rename to src/cpu/softfloat3e/f2xm1.cc index ed4af1d12..16daec1d3 100644 --- a/src/cpu/softfloat/f2xm1.cc +++ b/src/cpu/softfloat3e/f2xm1.cc @@ -25,12 +25,15 @@ these four paragraphs for those parts of this code that are retained. #define FLOAT128 -#include "softfloatx80.h" -#include "softfloat-round-pack.h" +#include "config.h" +#include "specialize.h" + +#include "fpu_trans.h" +#include "softfloat-helpers.h" static const floatx80 floatx80_negone = packFloatx80(1, 0x3fff, BX_CONST64(0x8000000000000000)); static const floatx80 floatx80_neghalf = packFloatx80(1, 0x3ffe, BX_CONST64(0x8000000000000000)); -static const float128 float128_ln2 = +static const float128_t float128_ln2 = packFloat128(BX_CONST64(0x3ffe62e42fefa39e), BX_CONST64(0xf35793c7673007e6)); #ifdef BETTER_THAN_PENTIUM @@ -47,7 +50,7 @@ static const float128 float128_ln2 = #define EXP_ARR_SIZE 15 -static float128 exp_arr[EXP_ARR_SIZE] = +static float128_t exp_arr[EXP_ARR_SIZE] = { PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */ @@ -66,10 +69,10 @@ static float128 exp_arr[EXP_ARR_SIZE] = PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */ }; -extern float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status); +extern float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status); /* required -1 < x < 1 */ -static float128 poly_exp(float128 x, struct float_status_t *status) +static float128_t poly_exp(float128_t x, struct softfloat_status_t *status) { /* // 2 3 4 5 6 7 8 9 @@ -92,8 +95,8 @@ static float128 poly_exp(float128 x, struct float_status_t *status) // e - 1 ~ x * [ p(x) + x * q(x) ] // */ - float128 t = EvalPoly(x, exp_arr, EXP_ARR_SIZE, status); - return float128_mul(t, x, status); + float128_t t = EvalPoly(x, (const float128_t*) exp_arr, EXP_ARR_SIZE, status); + return f128_mul(t, x, status); } // ================================================= @@ -114,49 +117,51 @@ static float128 poly_exp(float128 x, struct float_status_t *status) // e = 1 + --- + --- + --- + --- + --- + ... + --- + ... // 1! 2! 3! 4! 5! n! // - -floatx80 f2xm1(floatx80 a, struct float_status_t *status) +floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - Bit64u zSig0, zSig1, zSig2; + static const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + + uint64_t zSig0, zSig1, zSig2; + struct exp32_sig64 normExpSig; // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); return floatx80_default_nan; } - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); + uint64_t aSig = extF80_fraction(a); + int32_t aExp = extF80_exp(a); + int aSign = extF80_sign(a); if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - return propagateFloatx80NaNOne(a, status); + if (aSig << 1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, 0, 0, status); return (aSign) ? floatx80_negone : a; } - if (aExp == 0) { - if (aSig == 0) return a; - float_raise(status, float_flag_denormal | float_flag_inexact); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + if (! aExp) { + if (! aSig) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal | softfloat_flag_inexact); + normExpSig = softfloat_normSubnormalExtF80Sig(aSig); + aExp = normExpSig.exp + 1; + aSig = normExpSig.sig; tiny_argument: mul128By64To192(LN2_SIG_HI, LN2_SIG_LO, aSig, &zSig0, &zSig1, &zSig2); - if (0 < (Bit64s) zSig0) { + if (0 < (int64_t) zSig0) { shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); --aExp; } - return - roundAndPackFloatx80(80, aSign, aExp, zSig0, zSig1, status); + return softfloat_roundPackToExtF80(aSign, aExp, zSig0, zSig1, 80, status); } - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(status, softfloat_flag_inexact); if (aExp < 0x3FFF) { @@ -167,14 +172,14 @@ floatx80 f2xm1(floatx80 a, struct float_status_t *status) /* using float128 for approximation */ /* ******************************** */ - float128 x = floatx80_to_float128(a, status); - x = float128_mul(x, float128_ln2, status); + float128_t x = extF80_to_f128(a, status); + x = f128_mul(x, float128_ln2, status); x = poly_exp(x, status); - return float128_to_floatx80(x, status); + return f128_to_extF80(x, status); } else { - if (a.exp == 0xBFFF && ! (aSig<<1)) + if (a.signExp == 0xBFFF && ! (aSig<<1)) return floatx80_neghalf; return a; diff --git a/src/cpu/softfloat3e/f32_addsub.c b/src/cpu/softfloat3e/f32_addsub.c new file mode 100644 index 000000000..0b12d0e76 --- /dev/null +++ b/src/cpu/softfloat3e/f32_addsub.c @@ -0,0 +1,60 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +extern float32 softfloat_addMagsF32(uint32_t, uint32_t, struct softfloat_status_t *); +extern float32 softfloat_subMagsF32(uint32_t, uint32_t, struct softfloat_status_t *); + +float32 f32_add(float32 a, float32 b, struct softfloat_status_t *status) +{ + if (signF32UI((uint32_t) a ^ (uint32_t) b)) { + return softfloat_subMagsF32(a, b, status); + } else { + return softfloat_addMagsF32(a, b, status); + } +} + +float32 f32_sub(float32 a, float32 b, struct softfloat_status_t *status) +{ + if (signF32UI((uint32_t) a ^ (uint32_t) b)) { + return softfloat_addMagsF32(a, b, status); + } else { + return softfloat_subMagsF32(a, b, status); + } +} diff --git a/src/cpu/softfloat3e/f32_class.c b/src/cpu/softfloat3e/f32_class.c new file mode 100644 index 000000000..84c337d0e --- /dev/null +++ b/src/cpu/softfloat3e/f32_class.c @@ -0,0 +1,64 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +softfloat_class_t f32_class(float32 a) +{ + bool signA; + int16_t expA; + uint32_t sigA; + + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + + if (expA == 0xFF) { + if (sigA == 0) + return (signA) ? softfloat_negative_inf : softfloat_positive_inf; + + return (sigA & 0x00400000) ? softfloat_QNaN : softfloat_SNaN; + } + + if (expA == 0) { + if (sigA == 0) return softfloat_zero; + return softfloat_denormal; + } + + return softfloat_normalized; +} diff --git a/src/cpu/softfloat3e/f32_compare.c b/src/cpu/softfloat3e/f32_compare.c new file mode 100644 index 000000000..6c8ecfaae --- /dev/null +++ b/src/cpu/softfloat3e/f32_compare.c @@ -0,0 +1,92 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two single precision floating point numbers. Returns +| 'float_relation_equal' if the operands are equal, 'float_relation_less' if +| the value 'a' is less than the corresponding value `b', +| 'float_relation_greater' if the value 'a' is greater than the corresponding +| value `b', or 'float_relation_unordered' otherwise. +*----------------------------------------------------------------------------*/ + +int f32_compare(float32 a, float32 b, bool quiet, struct softfloat_status_t *status) +{ + softfloat_class_t aClass; + softfloat_class_t bClass; + bool signA; + bool signB; + + aClass = f32_class(a); + bClass = f32_class(b); + + if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) { + if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + a = a & 0x80000000; + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if (bClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + b = b & 0x80000000; + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if ((a == b) || ((uint32_t) ((a | b)<<1) == 0)) return softfloat_relation_equal; + + signA = signF32UI(a); + signB = signF32UI(b); + if (signA != signB) + return (signA) ? softfloat_relation_less : softfloat_relation_greater; + + if (signA ^ (a < b)) return softfloat_relation_less; + return softfloat_relation_greater; +} diff --git a/src/cpu/softfloat3e/f32_div.c b/src/cpu/softfloat3e/f32_div.c new file mode 100644 index 000000000..a9ccfcfd4 --- /dev/null +++ b/src/cpu/softfloat3e/f32_div.c @@ -0,0 +1,146 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +#define SOFTFLOAT_FAST_DIV64TO32 + +float32 f32_div(float32 a, float32 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + bool signB; + int16_t expB; + uint32_t sigB; + bool signZ; + struct exp16_sig32 normExpSig; + int16_t expZ; +#ifdef SOFTFLOAT_FAST_DIV64TO32 + uint64_t sig64A; + uint32_t sigZ; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + signB = signF32UI(b); + expB = expF32UI(b); + sigB = fracF32UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0xFF) { + if (sigA) goto propagateNaN; + if (expB == 0xFF) { + if (sigB) goto propagateNaN; + goto invalid; + } + if (sigB && !expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infinity; + } + if (expB == 0xFF) { + if (sigB) goto propagateNaN; + if (sigA && !expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! sigB) { + if (! (expA | sigA)) goto invalid; + softfloat_raiseFlags(status, softfloat_flag_infinite); + goto infinity; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + if (! sigA) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x7E; + sigA |= 0x00800000; + sigB |= 0x00800000; +#ifdef SOFTFLOAT_FAST_DIV64TO32 + if (sigA < sigB) { + --expZ; + sig64A = (uint64_t) sigA<<31; + } else { + sig64A = (uint64_t) sigA<<30; + } + sigZ = sig64A / sigB; + if (! (sigZ & 0x3F)) sigZ |= ((uint64_t) sigB * sigZ != sig64A); +#endif + return softfloat_roundPackToF32(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF32UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + return packToF32UI(signZ, 0xFF, 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF32UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f32_frc.c b/src/cpu/softfloat3e/f32_frc.c new file mode 100644 index 000000000..fc1b02460 --- /dev/null +++ b/src/cpu/softfloat3e/f32_frc.c @@ -0,0 +1,101 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the fractional portion of single-precision floating-point value `a', +| and returns the result as a single-precision floating-point value. The +| fractional results are precise. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 f32_frc(float32 a, struct softfloat_status_t *status) +{ + int roundingMode = softfloat_getRoundingMode(status); + + bool signA; + int16_t expA; + uint32_t sigA; + uint32_t lastBitMask; + uint32_t roundBitsMask; + + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + + if (expA == 0xFF) { + if (sigA) return softfloat_propagateNaNF32UI(a, 0, status); + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + + if (expA >= 0x96) { + return packToF32UI(roundingMode == softfloat_round_down, 0, 0); + } + + if (expA < 0x7F) { + if (! expA) { + if (! sigA || softfloat_denormalsAreZeros(status)) + return packToF32UI(roundingMode == softfloat_round_down, 0, 0); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) + softfloat_raiseFlags(status, softfloat_flag_underflow); + + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF32UI(signA, 0, 0); + } + } + return a; + } + + lastBitMask = 1 << (0x96 - expA); + roundBitsMask = lastBitMask - 1; + + sigA &= roundBitsMask; + sigA <<= 7; + expA--; + + if (! sigA) + return packToF32UI(roundingMode == softfloat_round_down, 0, 0); + + return softfloat_normRoundPackToF32(signA, expA, sigA, status); +} diff --git a/src/cpu/softfloat3e/f32_getExp.c b/src/cpu/softfloat3e/f32_getExp.c new file mode 100644 index 000000000..66b00ac7c --- /dev/null +++ b/src/cpu/softfloat3e/f32_getExp.c @@ -0,0 +1,73 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the exponent portion of single-precision floating-point value 'a', +| and returns the result as a single-precision floating-point value +| representing unbiased integer exponent. The operation is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 f32_getExp(float32 a, struct softfloat_status_t *status) +{ + int16_t expA; + uint32_t sigA; + struct exp16_sig32 normExpSig; + + expA = expF32UI(a); + sigA = fracF32UI(a); + + if (expA == 0xFF) { + if (sigA) return softfloat_propagateNaNF32UI(a, 0, status); + return packToF32UI(0, 0xFF, 0); + } + + if (! expA) { + if (! sigA || softfloat_denormalsAreZeros(status)) + return packToF32UI(1, 0xFF, 0); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + } + + return i32_to_f32((int32_t)(expA) - 0x7F, status); +} diff --git a/src/cpu/softfloat3e/f32_getMant.c b/src/cpu/softfloat3e/f32_getMant.c new file mode 100644 index 000000000..9dfa58a63 --- /dev/null +++ b/src/cpu/softfloat3e/f32_getMant.c @@ -0,0 +1,108 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the mantissa of single-precision floating-point value 'a' and +| returns the result as a single-precision floating-point after applying +| the mantissa interval normalization and sign control. The operation is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 f32_getMant(float32 a, struct softfloat_status_t *status, int sign_ctrl, int interv) +{ + bool signA; + int16_t expA; + uint32_t sigA; + struct exp16_sig32 normExpSig; + + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + + if (expA == 0xFF) { + if (sigA) return softfloat_propagateNaNF32UI(a, 0, status); + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + } + return packToF32UI(~sign_ctrl & signA, 0x7F, 0); + } + + if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) { + return packToF32UI(~sign_ctrl & signA, 0x7F, 0); + } + + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + } + + if (! expA) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + sigA &= 0x7FFFFF; + } + + switch(interv) { + case 0x0: // interval [1,2) + expA = 0x7F; + break; + case 0x1: // interval [1/2,2) + expA -= 0x7F; + expA = 0x7F - (expA & 0x1); + break; + case 0x2: // interval [1/2,1) + expA = 0x7E; + break; + case 0x3: // interval [3/4,3/2) + expA = 0x7F - ((sigA >> 22) & 0x1); + break; + } + + return packToF32UI(~sign_ctrl & signA, expA, sigA); +} diff --git a/src/cpu/softfloat3e/f32_minmax.c b/src/cpu/softfloat3e/f32_minmax.c new file mode 100644 index 000000000..e36c297ae --- /dev/null +++ b/src/cpu/softfloat3e/f32_minmax.c @@ -0,0 +1,69 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two single precision floating point numbers and return the +| smaller of them. +*----------------------------------------------------------------------------*/ + +float32 f32_min(float32 a, float32 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f32_denormal_to_zero(a); + b = f32_denormal_to_zero(b); + } + + return (f32_compare_normal(a, b, status) == softfloat_relation_less) ? a : b; +} + +/*---------------------------------------------------------------------------- +| Compare between two single precision floating point numbers and return the +| larger of them. +*----------------------------------------------------------------------------*/ + +float32 f32_max(float32 a, float32 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f32_denormal_to_zero(a); + b = f32_denormal_to_zero(b); + } + + return (f32_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b; +} diff --git a/src/cpu/softfloat3e/f32_mul.c b/src/cpu/softfloat3e/f32_mul.c new file mode 100644 index 000000000..db96e0db7 --- /dev/null +++ b/src/cpu/softfloat3e/f32_mul.c @@ -0,0 +1,137 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f32_mul(float32 a, float32 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + bool signB; + int16_t expB; + uint32_t sigB; + bool signZ; + uint32_t magBits; + struct exp16_sig32 normExpSig; + int16_t expZ; + uint32_t sigZ, uiZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + signB = signF32UI(b); + expB = expF32UI(b); + sigB = fracF32UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0xFF) { + if (sigA || ((expB == 0xFF) && sigB)) goto propagateNaN; + magBits = expB | sigB; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + if (expB == 0xFF) { + if (sigB) goto propagateNaN; + magBits = expA | sigA; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) { + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x7F; + sigA = (sigA | 0x00800000)<<7; + sigB = (sigB | 0x00800000)<<8; + sigZ = softfloat_shortShiftRightJam64((uint64_t) sigA * sigB, 32); + if (sigZ < 0x40000000) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF32(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF32UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if (! magBits) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ = defaultNaNF32UI; + } else { + uiZ = packToF32UI(signZ, 0xFF, 0); + } + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF32UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f32_mulAdd.c b/src/cpu/softfloat3e/f32_mulAdd.c new file mode 100644 index 000000000..101b20f18 --- /dev/null +++ b/src/cpu/softfloat3e/f32_mulAdd.c @@ -0,0 +1,233 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" +#include "specialize.h" + +float32 f32_mulAdd(float32 a, float32 b, float32 c, uint8_t op, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + bool signB; + int16_t expB; + uint32_t sigB; + bool signC; + int16_t expC; + uint32_t sigC; + bool signProd; + uint32_t magBits, uiA, uiB, uiC, uiZ; + struct exp16_sig32 normExpSig; + int16_t expProd; + uint64_t sigProd; + bool signZ; + int16_t expZ; + uint32_t sigZ; + int16_t expDiff; + uint64_t sig64Z, sig64C; + int8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA = a; + uiB = b; + uiC = c; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(uiA); + expA = expF32UI(uiA); + sigA = fracF32UI(uiA); + signB = signF32UI(uiB); + expB = expF32UI(uiB); + sigB = fracF32UI(uiB); + signC = signF32UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0); + expC = expF32UI(uiC); + sigC = fracF32UI(uiC); + signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + bool aisNaN = (expA == 0xFF) && sigA; + bool bisNaN = (expB == 0xFF) && sigB; + bool cisNaN = (expC == 0xFF) && sigC; + if (aisNaN | bisNaN | cisNaN) { + uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF32UI(uiA, uiB, status) : 0; + return softfloat_propagateNaNF32UI(uiZ, uiC, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + if (!expC) sigC = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0xFF) { + magBits = expB | sigB; + goto infProdArg; + } + if (expB == 0xFF) { + magBits = expA | sigA; + goto infProdArg; + } + if (expC == 0xFF) { + if ((sigA && !expA) || (sigB && !expB)) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + return packToF32UI(signC, 0xFF, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expProd = expA + expB - 0x7E; + sigA = (sigA | 0x00800000)<<7; + sigB = (sigB | 0x00800000)<<7; + sigProd = (uint64_t) sigA * sigB; + if (sigProd < UINT64_C(0x2000000000000000)) { + --expProd; + sigProd <<= 1; + } + signZ = signProd; + if (! expC) { + if (! sigC) { + expZ = expProd - 1; + sigZ = softfloat_shortShiftRightJam64(sigProd, 31); + goto roundPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigC); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | 0x00800000)<<6; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expProd - expC; + if (signProd == signC) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff <= 0) { + expZ = expC; + sigZ = sigC + softfloat_shiftRightJam64(sigProd, 32 - expDiff); + } else { + expZ = expProd; + sig64Z = sigProd + softfloat_shiftRightJam64((uint64_t) sigC<<32, expDiff); + sigZ = softfloat_shortShiftRightJam64(sig64Z, 32); + } + if (sigZ < 0x40000000) { + --expZ; + sigZ <<= 1; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64C = (uint64_t) sigC<<32; + if (expDiff < 0) { + signZ = signC; + expZ = expC; + sig64Z = sig64C - softfloat_shiftRightJam64(sigProd, -expDiff); + } else if (! expDiff) { + expZ = expProd; + sig64Z = sigProd - sig64C; + if (! sig64Z) goto completeCancellation; + if (sig64Z & UINT64_C(0x8000000000000000)) { + signZ = ! signZ; + sig64Z = -sig64Z; + } + } else { + expZ = expProd; + sig64Z = sigProd - softfloat_shiftRightJam64(sig64C, expDiff); + } + shiftDist = softfloat_countLeadingZeros64(sig64Z) - 1; + expZ -= shiftDist; + shiftDist -= 32; + if (shiftDist < 0) { + sigZ = softfloat_shortShiftRightJam64(sig64Z, -shiftDist); + } else { + sigZ = (uint32_t) sig64Z< +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f32_range(float32 a, float32 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + bool signB; + int16_t expB; + uint32_t sigB; + bool aIsNaN, bIsNaN; + uint32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + signB = signF32UI(b); + expB = expF32UI(b); + sigB = fracF32UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_isSigNaNF32UI(a)) { + return softfloat_propagateNaNF32UI(a, 0, status); + } + if (softfloat_isSigNaNF32UI(b)) { + return softfloat_propagateNaNF32UI(b, 0, status); + } + + aIsNaN = isNaNF32UI(a); + bIsNaN = isNaNF32UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA && sigA) { + if (softfloat_denormalsAreZeros(status)) { + a = packToF32UI(signA, 0, 0); + } + else if (! bIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + + if (! expB && sigB) { + if (softfloat_denormalsAreZeros(status)) { + b = packToF32UI(signB, 0, 0); + } + else if (! aIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (bIsNaN) { + z = a; + } + else if (aIsNaN) { + z = b; + } + else if (signA != signB && ! is_abs) { + if (! is_max) { + z = signA ? a : b; + } else { + z = signA ? b : a; + } + } else { + float32 tmp_a = a, tmp_b = b; + if (is_abs) { + tmp_a = tmp_a & ~0x80000000; // clear the sign bit + tmp_b = tmp_b & ~0x80000000; + signA = 0; + } + if (! is_max) { + z = (signA ^ (tmp_a < tmp_b)) ? a : b; + } else { + z = (signA ^ (tmp_a < tmp_b)) ? b : a; + } + } + + switch(sign_ctrl) { + case 0: + z = (z & ~0x80000000) | (a & 0x80000000); // keep sign of a + break; + case 1: + break; // preserve sign of compare result + case 2: + z = z & ~0x80000000; // zero out the sign bit + break; + case 3: + z = z | 0x80000000; // set the sign bit + break; + } + + return z; +} diff --git a/src/cpu/softfloat3e/f32_roundToInt.c b/src/cpu/softfloat3e/f32_roundToInt.c new file mode 100644 index 000000000..7791fbbf4 --- /dev/null +++ b/src/cpu/softfloat3e/f32_roundToInt.c @@ -0,0 +1,112 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f32_roundToInt(float32 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + int32_t frac; + uint32_t uiZ, lastBitMask, roundBitsMask; + bool sign; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + scale &= 0xF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF32UI(a); + frac = fracF32UI(a); + sign = signF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x96 <= (exp + scale)) { + if ((exp == 0xFF) && frac) { + return softfloat_propagateNaNF32UI(a, 0, status); + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!exp) { + frac = 0; + a = packToF32UI(sign, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((exp + scale) <= 0x7E) { + if (!(exp | frac)) return a; + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + uiZ = packToF32UI(sign, 0, 0); + switch (roundingMode) { + case softfloat_round_near_even: + if (!frac) break; + case softfloat_round_near_maxMag: + if ((exp + scale) == 0x7E) uiZ |= packToF32UI(0, 0x7F - scale, 0); + break; + case softfloat_round_min: + if (uiZ) uiZ = packToF32UI(1, 0x7F - scale, 0); + break; + case softfloat_round_max: + if (!uiZ) uiZ = packToF32UI(0, 0x7F - scale, 0); + break; + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = a; + lastBitMask = (uint32_t) 1<<(0x96 - exp - scale); + roundBitsMask = lastBitMask - 1; + if (roundingMode == softfloat_round_near_maxMag) { + uiZ += lastBitMask>>1; + } else if (roundingMode == softfloat_round_near_even) { + uiZ += lastBitMask>>1; + if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask; + } else if (roundingMode == (signF32UI(uiZ) ? softfloat_round_min : softfloat_round_max)) { + uiZ += roundBitsMask; + } + uiZ &= ~roundBitsMask; + if (uiZ != a) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f32_scalef.c b/src/cpu/softfloat3e/f32_scalef.c new file mode 100644 index 000000000..320baff30 --- /dev/null +++ b/src/cpu/softfloat3e/f32_scalef.c @@ -0,0 +1,155 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Return the result of a floating point scale of the single-precision floating +| point value `a' by multiplying it by 2 power of the single-precision +| floating point value 'b' converted to integral value. If the result cannot +| be represented in single precision, then the proper overflow response (for +| positive scaling operand), or the proper underflow response (for negative +| scaling operand) is issued. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 f32_scalef(float32 a, float32 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + bool signB; + int16_t expB; + uint32_t sigB; + int shiftCount; + int scale = 0; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + signB = signF32UI(b); + expB = expF32UI(b); + sigB = fracF32UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB == 0xFF) { + if (sigB) return softfloat_propagateNaNF32UI(a, b, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0xFF) { + if (sigA) { + int aIsSignalingNaN = (sigA & 0x00400000) == 0; + if (aIsSignalingNaN || expB != 0xFF || sigB) + return softfloat_propagateNaNF32UI(a, b, status); + + return signB ? 0 : packToF32UI(0, 0xFF, 0); + } + + if (expB == 0xFF && signB) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (expB == 0xFF && ! signB) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + return packToF32UI(signA, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((expB | sigB) == 0) return a; + + if (expB == 0xFF) { + if (signB) return packToF32UI(signA, 0, 0); + return packToF32UI(signA, 0xFF, 0); + } + + if (expB >= 0x8E) { + // handle obvious overflow/underflow result + return softfloat_roundPackToF32(signA, signB ? -0x7F : 0xFF, sigA, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB <= 0x7E) { + if (! expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + scale = -signB; + } + else { + shiftCount = expB - 0x9E; + sigB = (sigB | 0x800000)<<8; + scale = sigB>>(-shiftCount); + + if (signB) { + if ((uint32_t) (sigB<<(shiftCount & 31))) scale++; + scale = -scale; + } + + if (scale > 0x200) scale = 0x200; + if (scale < -0x200) scale = -0x200; + } + + if (expA != 0) { + sigA |= 0x00800000; + } else { + expA++; + } + + expA += scale - 1; + sigA <<= 7; + return softfloat_normRoundPackToF32(signA, expA, sigA, status); +} diff --git a/src/cpu/softfloat3e/f32_sqrt.c b/src/cpu/softfloat3e/f32_sqrt.c new file mode 100644 index 000000000..fc2ef8f76 --- /dev/null +++ b/src/cpu/softfloat3e/f32_sqrt.c @@ -0,0 +1,117 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f32_sqrt(float32 a, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint32_t sigA; + struct exp16_sig32 normExpSig; + int16_t expZ; + uint32_t sigZ, shiftedSigZ; + uint32_t negRem; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF32UI(a); + expA = expF32UI(a); + sigA = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0xFF) { + if (sigA) { + return softfloat_propagateNaNF32UI(a, 0, status); + } + if (! signA) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + a = packToF32UI(signA, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (signA) { + if (! (expA | sigA)) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x7F)>>1) + 0x7E; + expA &= 1; + sigA = (sigA | 0x00800000)<<8; + sigZ = + ((uint64_t) sigA * softfloat_approxRecipSqrt32_1(expA, sigA))>>32; + if (expA) sigZ >>= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigZ += 2; + if ((sigZ & 0x3F) < 2) { + shiftedSigZ = sigZ>>2; + negRem = shiftedSigZ * shiftedSigZ; + sigZ &= ~3; + if (negRem & 0x80000000) { + sigZ |= 1; + } else { + if (negRem) --sigZ; + } + } + return softfloat_roundPackToF32(0, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; +} diff --git a/src/cpu/softfloat3e/f32_to_extF80.cc b/src/cpu/softfloat3e/f32_to_extF80.cc new file mode 100644 index 000000000..73b8bedfd --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_extF80.cc @@ -0,0 +1,88 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t f32_to_extF80(float32 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + uint16_t uiZ64; + uint64_t uiZ0; + struct exp16_sig32 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + frac = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0xFF) { + if (frac) { + softfloat_f32UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToExtF80UI(&commonNaN); + uiZ64 = uiZ.v64; + uiZ0 = uiZ.v0; + } else { + uiZ64 = packToExtF80UI64(sign, 0x7FFF); + uiZ0 = UINT64_C(0x8000000000000000); + } + return packToExtF80_twoargs(uiZ64, uiZ0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac) { + return packToExtF80(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(frac); + exp = normExpSig.exp; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ64 = packToExtF80UI64(sign, exp + 0x3F80); + uiZ0 = (uint64_t) (frac | 0x00800000)<<40; + return packToExtF80_twoargs(uiZ64, uiZ0); +} diff --git a/src/cpu/softfloat3e/f32_to_f128.cc b/src/cpu/softfloat3e/f32_to_f128.cc new file mode 100644 index 000000000..6d3fafec2 --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_f128.cc @@ -0,0 +1,86 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f32_to_f128(float32 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + struct exp16_sig32 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + frac = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0xFF) { + if (frac) { + softfloat_f32UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF128UI(&commonNaN); + } else { + uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0); + uiZ.v0 = 0; + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac) { + uiZ.v64 = packToF128UI64(sign, 0, 0); + uiZ.v0 = 0; + return uiZ; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(frac); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ.v64 = packToF128UI64(sign, exp + 0x3F80, (uint64_t) frac<<25); + uiZ.v0 = 0; + return uiZ; +} diff --git a/src/cpu/softfloat3e/f32_to_f16.c b/src/cpu/softfloat3e/f32_to_f16.c new file mode 100644 index 000000000..9253a958a --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_f16.c @@ -0,0 +1,82 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16 f32_to_f16(float32 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t frac; + struct commonNaN commonNaN; + uint16_t uiZ, frac16; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + frac = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0xFF) { + if (frac) { + softfloat_f32UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF16UI(&commonNaN); + } else { + uiZ = packToF16UI(sign, 0x1F, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (!exp && frac) { + if (softfloat_denormalsAreZeros(status)) + return packToF16UI(sign, 0, 0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac16 = frac>>9 | ((frac & 0x1FF) != 0); + if (! (exp | frac16)) { + return packToF16UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF16(sign, exp - 0x71, frac16 | 0x4000, status); +} diff --git a/src/cpu/softfloat3e/f32_to_f64.c b/src/cpu/softfloat3e/f32_to_f64.c new file mode 100644 index 000000000..28ebb61b6 --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_f64.c @@ -0,0 +1,81 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f32_to_f64(float32 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t frac; + struct commonNaN commonNaN; + uint64_t uiZ; + struct exp16_sig32 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + frac = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0xFF) { + if (frac) { + softfloat_f32UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF64UI(&commonNaN); + } else { + uiZ = packToF64UI(sign, 0x7FF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac || softfloat_denormalsAreZeros(status)) { + return packToF64UI(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF32Sig(frac); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF64UI(sign, exp + 0x380, (uint64_t) frac<<29); +} diff --git a/src/cpu/softfloat3e/f32_to_i32.c b/src/cpu/softfloat3e/f32_to_i32.c new file mode 100644 index 000000000..2b3df52a3 --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_i32.c @@ -0,0 +1,78 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f32_to_i32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t sig; + uint64_t sig64; + int16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + sig = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ((exp == 0xFF) && sig) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= 0x00800000; + else if (softfloat_denormalsAreZeros(status)) sig = 0; + sig64 = (uint64_t) sig<<32; + shiftDist = 0xAA - exp; + if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist); + return softfloat_roundToI32(sign, sig64, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f32_to_i32_r_minMag.c b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c new file mode 100644 index 000000000..abe782d3b --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f32_to_i32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint32_t sig; + int16_t shiftDist; + bool sign; + int32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if (32 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + if (shiftDist <= 0) { + if (a == packToF32UI(1, 0x9E, 0)) return -0x7FFFFFFF - 1; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = (sig | 0x00800000)<<8; + absZ = sig>>shiftDist; + if (exact && ((uint32_t) absZ< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f32_to_i64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t sig; + int16_t shiftDist; + uint64_t sig64, extra; + struct uint64_extra sig64Extra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if (shiftDist < 0) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= 0x00800000; + sig64 = (uint64_t) sig<<40; + extra = 0; + if (shiftDist) { + sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist); + sig64 = sig64Extra.v; + extra = sig64Extra.extra; + } + return softfloat_roundToI64(sign, sig64, extra, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f32_to_i64_r_minMag.c b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c new file mode 100644 index 000000000..2ccabd09d --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c @@ -0,0 +1,88 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f32_to_i64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint32_t sig; + int16_t shiftDist; + bool sign; + uint64_t sig64; + int64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + if (shiftDist <= 0) { + if (a == packToF32UI(1, 0xBE, 0)) { + return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= 0x00800000; + sig64 = (uint64_t) sig<<40; + absZ = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return sign ? -absZ : absZ; +} diff --git a/src/cpu/softfloat3e/f32_to_ui32.c b/src/cpu/softfloat3e/f32_to_ui32.c new file mode 100644 index 000000000..5a8d57414 --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_ui32.c @@ -0,0 +1,80 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f32_to_ui32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t sig; + uint64_t sig64; + int16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ((exp == 0xFF) && sig) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= 0x00800000; + else if (softfloat_denormalsAreZeros(status)) sig = 0; + sig64 = (uint64_t) sig<<32; + shiftDist = 0xAA - exp; + if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist); + return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c new file mode 100644 index 000000000..4b37708b0 --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c @@ -0,0 +1,83 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f32_to_ui32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint32_t sig; + int16_t shiftDist; + bool sign; + uint32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if (32 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + if (sign || (shiftDist < 0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = (sig | 0x00800000)<<8; + z = sig>>shiftDist; + if (exact && (z< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f32_to_ui64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint32_t sig; + int16_t shiftDist; + uint64_t sig64, extra; + struct uint64_extra sig64Extra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + exp = expF32UI(a); + sig = fracF32UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if (shiftDist < 0) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= 0x00800000; + else if (softfloat_denormalsAreZeros(status)) sig = 0; + sig64 = (uint64_t) sig<<40; + extra = 0; + if (shiftDist) { + sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist); + sig64 = sig64Extra.v; + extra = sig64Extra.extra; + } + return softfloat_roundToUI64(sign, sig64, extra, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c new file mode 100644 index 000000000..111c50e7f --- /dev/null +++ b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c @@ -0,0 +1,84 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f32_to_ui64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint32_t sig; + int16_t shiftDist; + bool sign; + uint64_t sig64, z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF32UI(a); + sig = fracF32UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if (64 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI(a); + if (sign || (shiftDist < 0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0xFF) && sig + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= 0x00800000; + sig64 = (uint64_t) sig<<40; + z = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return z; +} diff --git a/src/cpu/softfloat3e/f64_addsub.c b/src/cpu/softfloat3e/f64_addsub.c new file mode 100644 index 000000000..6c5acb4f7 --- /dev/null +++ b/src/cpu/softfloat3e/f64_addsub.c @@ -0,0 +1,70 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +extern float64 softfloat_addMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *); +extern float64 softfloat_subMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *); + +float64 f64_add(float64 a, float64 b, struct softfloat_status_t *status) +{ + bool signA; + bool signB; + + signA = signF64UI(a); + signB = signF64UI(b); + if (signA == signB) { + return softfloat_addMagsF64(a, b, signA, status); + } else { + return softfloat_subMagsF64(a, b, signA, status); + } +} + +float64 f64_sub(float64 a, float64 b, struct softfloat_status_t *status) +{ + bool signA; + bool signB; + + signA = signF64UI(a); + signB = signF64UI(b); + if (signA == signB) { + return softfloat_subMagsF64(a, b, signA, status); + } else { + return softfloat_addMagsF64(a, b, signA, status); + } +} diff --git a/src/cpu/softfloat3e/f64_class.c b/src/cpu/softfloat3e/f64_class.c new file mode 100644 index 000000000..1d44a6351 --- /dev/null +++ b/src/cpu/softfloat3e/f64_class.c @@ -0,0 +1,64 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +softfloat_class_t f64_class(float64 a) +{ + bool signA; + int16_t expA; + uint64_t sigA; + + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + + if (expA == 0x7FF) { + if (sigA == 0) + return (signA) ? softfloat_negative_inf : softfloat_positive_inf; + + return (sigA & UINT64_C(0x0008000000000000)) ? softfloat_QNaN : softfloat_SNaN; + } + + if (expA == 0) { + if (sigA == 0) return softfloat_zero; + return softfloat_denormal; + } + + return softfloat_normalized; +} diff --git a/src/cpu/softfloat3e/f64_compare.c b/src/cpu/softfloat3e/f64_compare.c new file mode 100644 index 000000000..aed250768 --- /dev/null +++ b/src/cpu/softfloat3e/f64_compare.c @@ -0,0 +1,92 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two double precision floating point numbers. Returns +| 'float_relation_equal' if the operands are equal, 'float_relation_less' if +| the value 'a' is less than the corresponding value `b', +| 'float_relation_greater' if the value 'a' is greater than the corresponding +| value `b', or 'float_relation_unordered' otherwise. +*----------------------------------------------------------------------------*/ + +int f64_compare(float64 a, float64 b, bool quiet, struct softfloat_status_t *status) +{ + softfloat_class_t aClass; + softfloat_class_t bClass; + bool signA; + bool signB; + + aClass = f64_class(a); + bClass = f64_class(b); + + if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) { + if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid); + return softfloat_relation_unordered; + } + + if (aClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + a = a & UINT64_C(0x8000000000000000); + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if (bClass == softfloat_denormal) { + if (softfloat_denormalsAreZeros(status)) + b = b & UINT64_C(0x8000000000000000); + else + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + + if ((a == b) || ((uint64_t) ((a | b)<<1) == 0)) return softfloat_relation_equal; + + signA = signF64UI(a); + signB = signF64UI(b); + if (signA != signB) + return (signA) ? softfloat_relation_less : softfloat_relation_greater; + + if (signA ^ (a < b)) return softfloat_relation_less; + return softfloat_relation_greater; +} diff --git a/src/cpu/softfloat3e/f64_div.c b/src/cpu/softfloat3e/f64_div.c new file mode 100644 index 000000000..89f74f1b1 --- /dev/null +++ b/src/cpu/softfloat3e/f64_div.c @@ -0,0 +1,165 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f64_div(float64 a, float64 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + bool signB; + int16_t expB; + uint64_t sigB; + bool signZ; + struct exp16_sig64 normExpSig; + int16_t expZ; + uint32_t recip32, sig32Z, doubleTerm; + uint64_t rem; + uint32_t q; + uint64_t sigZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + signB = signF64UI(b); + expB = expF64UI(b); + sigB = fracF64UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FF) { + if (sigA) goto propagateNaN; + if (expB == 0x7FF) { + if (sigB) goto propagateNaN; + goto invalid; + } + if (sigB && !expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infinity; + } + if (expB == 0x7FF) { + if (sigB) goto propagateNaN; + if (sigA && !expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! sigB) { + if (! (expA | sigA)) goto invalid; + softfloat_raiseFlags(status, softfloat_flag_infinite); + goto infinity; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if (! expA) { + if (! sigA) goto zero; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x3FE; + sigA |= UINT64_C(0x0010000000000000); + sigB |= UINT64_C(0x0010000000000000); + if (sigA < sigB) { + --expZ; + sigA <<= 11; + } else { + sigA <<= 10; + } + sigB <<= 11; + recip32 = softfloat_approxRecip32_1(sigB>>32) - 2; + sig32Z = ((uint32_t) (sigA>>32) * (uint64_t) recip32)>>32; + doubleTerm = sig32Z<<1; + rem = + ((sigA - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) + - (uint64_t) doubleTerm * ((uint32_t) sigB>>4); + q = (((uint32_t) (rem>>32) * (uint64_t) recip32)>>32) + 4; + sigZ = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<4); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((sigZ & 0x1FF) < 4<<4) { + q &= ~7; + sigZ &= ~(uint64_t) 0x7F; + doubleTerm = q<<1; + rem = + ((rem - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) + - (uint64_t) doubleTerm * ((uint32_t) sigB>>4); + if (rem & UINT64_C(0x8000000000000000)) { + sigZ -= 1<<7; + } else { + if (rem) sigZ |= 1; + } + } + return softfloat_roundPackToF64(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF64UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + return packToF64UI(signZ, 0x7FF, 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF64UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f64_frc.c b/src/cpu/softfloat3e/f64_frc.c new file mode 100644 index 000000000..46c21ac4f --- /dev/null +++ b/src/cpu/softfloat3e/f64_frc.c @@ -0,0 +1,101 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the fractional portion of double-precision floating-point value `a', +| and returns the result as a double-precision floating-point value. The +| fractional results are precise. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 f64_frc(float64 a, struct softfloat_status_t *status) +{ + int roundingMode = softfloat_getRoundingMode(status); + + bool signA; + int16_t expA; + uint64_t sigA; + uint64_t lastBitMask; + uint64_t roundBitsMask; + + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + + if (expA == 0x7FF) { + if (sigA) return softfloat_propagateNaNF64UI(a, 0, status); + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + + if (expA >= 0x433) { + return packToF64UI(roundingMode == softfloat_round_down, 0, 0); + } + + if (expA < 0x3FF) { + if (! expA) { + if (! sigA || softfloat_denormalsAreZeros(status)) + return packToF64UI(roundingMode == softfloat_round_down, 0, 0); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) + softfloat_raiseFlags(status, softfloat_flag_underflow); + + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF64UI(signA, 0, 0); + } + } + return a; + } + + lastBitMask = UINT64_C(1) << (0x433 - expA); + roundBitsMask = lastBitMask - 1; + + sigA &= roundBitsMask; + sigA <<= 10; + expA--; + + if (! sigA) + return packToF64UI(roundingMode == softfloat_round_down, 0, 0); + + return softfloat_normRoundPackToF64(signA, expA, sigA, status); +} diff --git a/src/cpu/softfloat3e/f64_getExp.c b/src/cpu/softfloat3e/f64_getExp.c new file mode 100644 index 000000000..b76cc996d --- /dev/null +++ b/src/cpu/softfloat3e/f64_getExp.c @@ -0,0 +1,73 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the exponent portion of double-precision floating-point value 'a', +| and returns the result as a double-precision floating-point value +| representing unbiased integer exponent. The operation is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 f64_getExp(float64 a, struct softfloat_status_t *status) +{ + int16_t expA; + uint64_t sigA; + struct exp16_sig64 normExpSig; + + expA = expF64UI(a); + sigA = fracF64UI(a); + + if (expA == 0x7FF) { + if (sigA) return softfloat_propagateNaNF64UI(a, 0, status); + return packToF64UI(0, 0x7FF, 0); + } + + if (! expA) { + if (! sigA || softfloat_denormalsAreZeros(status)) + return packToF64UI(1, 0x7FF, 0); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + } + + return i32_to_f64((int32_t)(expA) - 0x3FF); +} diff --git a/src/cpu/softfloat3e/f64_getMant.c b/src/cpu/softfloat3e/f64_getMant.c new file mode 100644 index 000000000..84077e314 --- /dev/null +++ b/src/cpu/softfloat3e/f64_getMant.c @@ -0,0 +1,108 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Extracts the mantissa of double-precision floating-point value 'a' and +| returns the result as a double-precision floating-point after applying +| the mantissa interval normalization and sign control. The operation is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 f64_getMant(float64 a, struct softfloat_status_t *status, int sign_ctrl, int interv) +{ + bool signA; + int16_t expA; + uint64_t sigA; + struct exp16_sig64 normExpSig; + + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + + if (expA == 0x7FF) { + if (sigA) return softfloat_propagateNaNF64UI(a, 0, status); + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + } + return packToF64UI(~sign_ctrl & signA, 0x3FF, 0); + } + + if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) { + return packToF64UI(~sign_ctrl & signA, 0x3FF, 0); + } + + if (signA) { + if (sign_ctrl & 0x2) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + } + + if (expA == 0) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + sigA &= UINT64_C(0xFFFFFFFFFFFFF); + } + + switch(interv) { + case 0x0: // interval [1,2) + expA = 0x3FF; + break; + case 0x1: // interval [1/2,2) + expA -= 0x3FF; + expA = 0x3FF - (expA & 0x1); + break; + case 0x2: // interval [1/2,1) + expA = 0x3FE; + break; + case 0x3: // interval [3/4,3/2) + expA = 0x3FF - ((sigA >> 51) & 0x1); + break; + } + + return packToF64UI(~sign_ctrl & signA, expA, sigA); +} diff --git a/src/cpu/softfloat3e/f64_minmax.c b/src/cpu/softfloat3e/f64_minmax.c new file mode 100644 index 000000000..3c927410a --- /dev/null +++ b/src/cpu/softfloat3e/f64_minmax.c @@ -0,0 +1,69 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Compare between two double precision floating point numbers and return the +| smaller of them. +*----------------------------------------------------------------------------*/ + +float64 f64_min(float64 a, float64 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f64_denormal_to_zero(a); + b = f64_denormal_to_zero(b); + } + + return (f64_compare_normal(a, b, status) == softfloat_relation_less) ? a : b; +} + +/*---------------------------------------------------------------------------- +| Compare between two double precision floating point numbers and return the +| larger of them. +*----------------------------------------------------------------------------*/ + +float64 f64_max(float64 a, float64 b, struct softfloat_status_t *status) +{ + if (softfloat_denormalsAreZeros(status)) { + a = f64_denormal_to_zero(a); + b = f64_denormal_to_zero(b); + } + + return (f64_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b; +} diff --git a/src/cpu/softfloat3e/f64_mul.c b/src/cpu/softfloat3e/f64_mul.c new file mode 100644 index 000000000..c1e98f2b6 --- /dev/null +++ b/src/cpu/softfloat3e/f64_mul.c @@ -0,0 +1,139 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f64_mul(float64 a, float64 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + bool signB; + int16_t expB; + uint64_t sigB; + bool signZ; + uint64_t magBits; + struct exp16_sig64 normExpSig; + int16_t expZ; + struct uint128 sig128Z; + uint64_t sigZ, uiZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + signB = signF64UI(b); + expB = expF64UI(b); + sigB = fracF64UI(b); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FF) { + if (sigA || ((expB == 0x7FF) && sigB)) goto propagateNaN; + magBits = expB | sigB; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + if (expB == 0x7FF) { + if (sigB) goto propagateNaN; + magBits = expA | sigA; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) { + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + goto zero; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FF; + sigA = (sigA | UINT64_C(0x0010000000000000))<<10; + sigB = (sigB | UINT64_C(0x0010000000000000))<<11; + sig128Z = softfloat_mul64To128(sigA, sigB); + sigZ = sig128Z.v64 | (sig128Z.v0 != 0); + if (sigZ < UINT64_C(0x4000000000000000)) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF64(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF64UI(a, b, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if (! magBits) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ = defaultNaNF64UI; + } else { + uiZ = packToF64UI(signZ, 0x7FF, 0); + } + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + return packToF64UI(signZ, 0, 0); +} diff --git a/src/cpu/softfloat3e/f64_mulAdd.c b/src/cpu/softfloat3e/f64_mulAdd.c new file mode 100644 index 000000000..9623b4980 --- /dev/null +++ b/src/cpu/softfloat3e/f64_mulAdd.c @@ -0,0 +1,243 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" +#include "specialize.h" + +float64 f64_mulAdd(float64 a, float64 b, float64 c, uint8_t op, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + bool signB; + int16_t expB; + uint64_t sigB; + bool signC; + int16_t expC; + uint64_t sigC; + bool signZ; + uint64_t magBits, uiA, uiB, uiC, uiZ; + struct exp16_sig64 normExpSig; + int16_t expZ; + struct uint128 sig128Z; + uint64_t sigZ; + int16_t expDiff; + struct uint128 sig128C; + int8_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiA = a; + uiB = b; + uiC = c; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(uiA); + expA = expF64UI(uiA); + sigA = fracF64UI(uiA); + signB = signF64UI(uiB); + expB = expF64UI(uiB); + sigB = fracF64UI(uiB); + signC = signF64UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0); + expC = expF64UI(uiC); + sigC = fracF64UI(uiC); + signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + bool aisNaN = (expA == 0x7FF) && sigA; + bool bisNaN = (expB == 0x7FF) && sigB; + bool cisNaN = (expC == 0x7FF) && sigC; + if (aisNaN | bisNaN | cisNaN) { + uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF64UI(uiA, uiB, status) : 0; + return softfloat_propagateNaNF64UI(uiZ, uiC, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + if (!expC) sigC = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FF) { + magBits = expB | sigB; + goto infProdArg; + } + if (expB == 0x7FF) { + magBits = expA | sigA; + goto infProdArg; + } + if (expC == 0x7FF) { + if ((sigA && !expA) || (sigB && !expB)) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + return packToF64UI(signC, 0x7FF, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if (! expB) { + if (! sigB) goto zeroProd; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigB); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FE; + sigA = (sigA | UINT64_C(0x0010000000000000))<<10; + sigB = (sigB | UINT64_C(0x0010000000000000))<<10; + sig128Z = softfloat_mul64To128(sigA, sigB); + if (sig128Z.v64 < UINT64_C(0x2000000000000000)) { + --expZ; + sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0); + } + if (! expC) { + if (! sigC) { + --expZ; + sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0); + goto roundPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigC); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | UINT64_C(0x0010000000000000))<<9; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expZ - expC; + if (expDiff < 0) { + expZ = expC; + if ((signZ == signC) || (expDiff < -1)) { + sig128Z.v64 = softfloat_shiftRightJam64(sig128Z.v64, -expDiff); + } else { + sig128Z = softfloat_shortShiftRightJam128(sig128Z.v64, sig128Z.v0, 1); + } + } else if (expDiff) { + sig128C = softfloat_shiftRightJam128(sigC, 0, expDiff); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (signZ == signC) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff <= 0) { + sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0); + } else { + sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0); + sigZ = sig128Z.v64 | (sig128Z.v0 != 0); + } + if (sigZ < UINT64_C(0x4000000000000000)) { + --expZ; + sigZ <<= 1; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff < 0) { + signZ = signC; + sig128Z = softfloat_sub128(sigC, 0, sig128Z.v64, sig128Z.v0); + } else if (! expDiff) { + sig128Z.v64 = sig128Z.v64 - sigC; + if (! (sig128Z.v64 | sig128Z.v0)) goto completeCancellation; + if (sig128Z.v64 & UINT64_C(0x8000000000000000)) { + signZ = ! signZ; + sig128Z = softfloat_sub128(0, 0, sig128Z.v64, sig128Z.v0); + } + } else { + sig128Z = softfloat_sub128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0); + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (! sig128Z.v64) { + expZ -= 64; + sig128Z.v64 = sig128Z.v0; + sig128Z.v0 = 0; + } + shiftDist = softfloat_countLeadingZeros64(sig128Z.v64) - 1; + expZ -= shiftDist; + if (shiftDist < 0) { + sigZ = softfloat_shortShiftRightJam64(sig128Z.v64, -shiftDist); + } else { + sig128Z = softfloat_shortShiftLeft128(sig128Z.v64, sig128Z.v0, shiftDist); + sigZ = sig128Z.v64; + } + sigZ |= (sig128Z.v0 != 0); + } + roundPack: + return softfloat_roundPackToF64(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if (magBits) { + uiZ = packToF64UI(signZ, 0x7FF, 0); + if (signZ == signC || expC != 0x7FF) { + if ((sigA && !expA) || (sigB && !expB) || (sigC && !expC)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return uiZ; + } + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ = defaultNaNF64UI; + return softfloat_propagateNaNF64UI(uiZ, uiC, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ = packToF64UI(signC, expC, sigC); + if (!expC && sigC) { + /* Exact zero plus a denormal */ + softfloat_raiseFlags(status, softfloat_flag_denormal); + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF64UI(signC, 0, 0); + } + } + if (! (expC | sigC) && (signZ != signC)) { + completeCancellation: + uiZ = packToF64UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f64_range.c b/src/cpu/softfloat3e/f64_range.c new file mode 100644 index 000000000..6f01c84cc --- /dev/null +++ b/src/cpu/softfloat3e/f64_range.c @@ -0,0 +1,135 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f64_range(float64 a, float64 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + bool signB; + int16_t expB; + uint64_t sigB; + bool aIsNaN, bIsNaN; + uint64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + signB = signF64UI(b); + expB = expF64UI(b); + sigB = fracF64UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_isSigNaNF64UI(a)) { + return softfloat_propagateNaNF64UI(a, 0, status); + } + if (softfloat_isSigNaNF64UI(b)) { + return softfloat_propagateNaNF64UI(b, 0, status); + } + + aIsNaN = isNaNF64UI(a); + bIsNaN = isNaNF64UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA && sigA) { + if (softfloat_denormalsAreZeros(status)) { + a = packToF64UI(signA, 0, 0); + } + else if (! bIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + + if (! expB && sigB) { + if (softfloat_denormalsAreZeros(status)) { + b = packToF64UI(signB, 0, 0); + } + else if (! aIsNaN) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (bIsNaN) { + z = a; + } + else if (aIsNaN) { + z = b; + } + else if (signA != signB && ! is_abs) { + if (! is_max) { + z = signA ? a : b; + } else { + z = signA ? b : a; + } + } else { + float64 tmp_a = a, tmp_b = b; + if (is_abs) { + tmp_a = tmp_a & ~UINT64_C(0x8000000000000000); // clear the sign bit + tmp_b = tmp_b & ~UINT64_C(0x8000000000000000); + signA = 0; + } + + if (! is_max) { + z = (signA ^ (tmp_a < tmp_b)) ? a : b; + } else { + z = (signA ^ (tmp_a < tmp_b)) ? b : a; + } + } + + switch(sign_ctrl) { + case 0: + z = (z & ~UINT64_C(0x8000000000000000)) | (a & UINT64_C(0x8000000000000000)); // keep sign of a + break; + case 1: + break; // preserve sign of compare result + case 2: + z = z & ~UINT64_C(0x8000000000000000); // zero out the sign bit + break; + case 3: + z = z | UINT64_C(0x8000000000000000); // set the sign bit + break; + } + + return z; +} diff --git a/src/cpu/softfloat3e/f64_roundToInt.c b/src/cpu/softfloat3e/f64_roundToInt.c new file mode 100644 index 000000000..3c5f7fb8c --- /dev/null +++ b/src/cpu/softfloat3e/f64_roundToInt.c @@ -0,0 +1,112 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f64_roundToInt(float64 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + int64_t frac; + bool sign; + uint64_t uiZ, lastBitMask, roundBitsMask; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + scale &= 0xF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF64UI(a); + frac = fracF64UI(a); + sign = signF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x433 <= (exp + scale)) { + if ((exp == 0x7FF) && frac) { + return softfloat_propagateNaNF64UI(a, 0, status); + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!exp) { + frac = 0; + a = packToF64UI(sign, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((exp + scale) <= 0x3FE) { + if (!(exp | frac)) return a; + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + uiZ = packToF64UI(sign, 0, 0); + switch (roundingMode) { + case softfloat_round_near_even: + if (!frac) break; + case softfloat_round_near_maxMag: + if ((exp + scale) == 0x3FE) uiZ |= packToF64UI(0, 0x3FF - scale, 0); + break; + case softfloat_round_min: + if (uiZ) uiZ = packToF64UI(1, 0x3FF - scale, 0); + break; + case softfloat_round_max: + if (!uiZ) uiZ = packToF64UI(0, 0x3FF - scale, 0); + break; + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = a; + lastBitMask = (uint64_t) 1<<(0x433 - exp - scale); + roundBitsMask = lastBitMask - 1; + if (roundingMode == softfloat_round_near_maxMag) { + uiZ += lastBitMask>>1; + } else if (roundingMode == softfloat_round_near_even) { + uiZ += lastBitMask>>1; + if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask; + } else if (roundingMode == (signF64UI(uiZ) ? softfloat_round_min : softfloat_round_max)) { + uiZ += roundBitsMask; + } + uiZ &= ~roundBitsMask; + if (uiZ != a) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return uiZ; +} diff --git a/src/cpu/softfloat3e/f64_scalef.c b/src/cpu/softfloat3e/f64_scalef.c new file mode 100644 index 000000000..7a552ccc3 --- /dev/null +++ b/src/cpu/softfloat3e/f64_scalef.c @@ -0,0 +1,156 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Return the result of a floating point scale of the double-precision floating +| point value `a' by multiplying it by 2 power of the double-precision +| floating point value 'b' converted to integral value. If the result cannot +| be represented in double precision, then the proper overflow response (for +| positive scaling operand), or the proper underflow response (for negative +| scaling operand) is issued. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 f64_scalef(float64 a, float64 b, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + bool signB; + int16_t expB; + uint64_t sigB; + int shiftCount; + int scale = 0; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + signB = signF64UI(b); + expB = expF64UI(b); + sigB = fracF64UI(b); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB == 0x7FF) { + if (sigB) return softfloat_propagateNaNF64UI(a, b, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FF) { + if (sigA) { + int aIsSignalingNaN = (sigA & UINT64_C(0x0008000000000000)) == 0; + if (aIsSignalingNaN || expB != 0x7FF || sigB) + return softfloat_propagateNaNF64UI(a, b, status); + + return signB ? 0 : packToF64UI(0, 0x7FF, 0); + } + + if (expB == 0x7FF && signB) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (expB == 0x7FF && ! signB) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + return packToF64UI(signA, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((expB | sigB) == 0) return a; + + if (expB == 0x7FF) { + if (signB) return packToF64UI(signA, 0, 0); + return packToF64UI(signA, 0x7FF, 0); + } + + if (0x40F <= expB) { + // handle obvious overflow/underflow result + return softfloat_roundPackToF64(signA, signB ? -0x3FF : 0x7FF, sigA, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB < 0x3FF) { + if (expB == 0) + softfloat_raiseFlags(status, softfloat_flag_denormal); + scale = -signB; + } + else { + sigB |= UINT64_C(0x0010000000000000); + shiftCount = 0x433 - expB; + uint64_t prev_sigB = sigB; + sigB >>= shiftCount; + scale = (int32_t) sigB; + if (signB) { + if ((sigB< 0x1000) scale = 0x1000; + if (scale < -0x1000) scale = -0x1000; + } + + if (expA != 0) { + sigA |= UINT64_C(0x0010000000000000); + } else { + expA++; + } + + expA += scale - 1; + sigA <<= 10; + return softfloat_normRoundPackToF64(signA, expA, sigA, status); +} diff --git a/src/cpu/softfloat3e/f64_sqrt.c b/src/cpu/softfloat3e/f64_sqrt.c new file mode 100644 index 000000000..d3ea81af8 --- /dev/null +++ b/src/cpu/softfloat3e/f64_sqrt.c @@ -0,0 +1,130 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 f64_sqrt(float64 a, struct softfloat_status_t *status) +{ + bool signA; + int16_t expA; + uint64_t sigA; + struct exp16_sig64 normExpSig; + int16_t expZ; + uint32_t sig32A, recipSqrt32, sig32Z; + uint64_t rem; + uint32_t q; + uint64_t sigZ, shiftedSigZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI(a); + expA = expF64UI(a); + sigA = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FF) { + if (sigA) { + return softfloat_propagateNaNF64UI(a, 0, status); + } + if (! signA) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + a = packToF64UI(signA, 0, 0); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (signA) { + if (! (expA | sigA)) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) return a; + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(sigA); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + | (`sig32Z' is guaranteed to be a lower bound on the square root of + | `sig32A', which makes `sig32Z' also a lower bound on the square root of + | `sigA'.) + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x3FF)>>1) + 0x3FE; + expA &= 1; + sigA |= UINT64_C(0x0010000000000000); + sig32A = sigA>>21; + recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A); + sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32; + if (expA) { + sigA <<= 8; + sig32Z >>= 1; + } else { + sigA <<= 9; + } + rem = sigA - (uint64_t) sig32Z * sig32Z; + q = ((uint32_t) (rem>>2) * (uint64_t) recipSqrt32)>>32; + sigZ = ((uint64_t) sig32Z<<32 | 1<<5) + ((uint64_t) q<<3); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((sigZ & 0x1FF) < 0x22) { + sigZ &= ~(uint64_t) 0x3F; + shiftedSigZ = sigZ>>6; + rem = (sigA<<52) - shiftedSigZ * shiftedSigZ; + if (rem & UINT64_C(0x8000000000000000)) { + --sigZ; + } else { + if (rem) sigZ |= 1; + } + } + return softfloat_roundPackToF64(0, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; +} diff --git a/src/cpu/softfloat3e/f64_to_extF80.cc b/src/cpu/softfloat3e/f64_to_extF80.cc new file mode 100644 index 000000000..88b27f9d3 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_extF80.cc @@ -0,0 +1,88 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t f64_to_extF80(float64 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + uint16_t uiZ64; + uint64_t uiZ0; + struct exp16_sig64 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + frac = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FF) { + if (frac) { + softfloat_f64UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToExtF80UI(&commonNaN); + uiZ64 = uiZ.v64; + uiZ0 = uiZ.v0; + } else { + uiZ64 = packToExtF80UI64(sign, 0x7FFF); + uiZ0 = UINT64_C(0x8000000000000000); + } + return packToExtF80_twoargs(uiZ64, uiZ0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac) { + return packToExtF80(sign, 0, 0); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(frac); + exp = normExpSig.exp; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ64 = packToExtF80UI64(sign, exp + 0x3C00); + uiZ0 = (frac | UINT64_C(0x0010000000000000))<<11; + return packToExtF80_twoargs(uiZ64, uiZ0); +} diff --git a/src/cpu/softfloat3e/f64_to_f128.cc b/src/cpu/softfloat3e/f64_to_f128.cc new file mode 100644 index 000000000..cfae72824 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_f128.cc @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f64_to_f128(float64 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + struct exp16_sig64 normExpSig; + struct uint128 frac128; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + frac = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FF) { + if (frac) { + softfloat_f64UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF128UI(&commonNaN); + } else { + uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0); + uiZ.v0 = 0; + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! exp) { + if (! frac) { + uiZ.v64 = packToF128UI64(sign, 0, 0); + uiZ.v0 = 0; + return uiZ; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalF64Sig(frac); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac128 = softfloat_shortShiftLeft128(0, frac, 60); + uiZ.v64 = packToF128UI64(sign, exp + 0x3C00, frac128.v64); + uiZ.v0 = frac128.v0; + return uiZ; +} diff --git a/src/cpu/softfloat3e/f64_to_f16.c b/src/cpu/softfloat3e/f64_to_f16.c new file mode 100644 index 000000000..fe8dea057 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_f16.c @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float16 f64_to_f16(float64 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t frac; + struct commonNaN commonNaN; + uint16_t uiZ, frac16; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + frac = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FF) { + if (frac) { + softfloat_f64UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF16UI(&commonNaN); + } else { + uiZ = packToF16UI(sign, 0x1F, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (!exp && frac) { + if (softfloat_denormalsAreZeros(status)) + return packToF16UI(sign, 0, 0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac16 = softfloat_shortShiftRightJam64(frac, 38); + if (! (exp | frac16)) { + return packToF16UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF16(sign, exp - 0x3F1, frac16 | 0x4000, status); +} diff --git a/src/cpu/softfloat3e/f64_to_f32.c b/src/cpu/softfloat3e/f64_to_f32.c new file mode 100644 index 000000000..7ebbf428f --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_f32.c @@ -0,0 +1,83 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 f64_to_f32(float64 a, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t frac; + struct commonNaN commonNaN; + uint32_t uiZ, frac32; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + frac = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp == 0x7FF) { + if (frac) { + softfloat_f64UIToCommonNaN(a, &commonNaN, status); + uiZ = softfloat_commonNaNToF32UI(&commonNaN); + } else { + uiZ = packToF32UI(sign, 0xFF, 0); + } + return uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (!exp && frac) { + if (softfloat_denormalsAreZeros(status)) + return packToF32UI(sign, 0, 0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac32 = softfloat_shortShiftRightJam64(frac, 22); + if (! (exp | frac32)) { + return packToF32UI(sign, 0, 0); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF32(sign, exp - 0x381, frac32 | 0x40000000, status); +} diff --git a/src/cpu/softfloat3e/f64_to_i32.c b/src/cpu/softfloat3e/f64_to_i32.c new file mode 100644 index 000000000..c296e0bd5 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_i32.c @@ -0,0 +1,77 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f64_to_i32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t sig; + int16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + sig = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ((exp == 0x7FF) && sig) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= UINT64_C(0x0010000000000000); + else if (softfloat_denormalsAreZeros(status)) sig = 0; + shiftDist = 0x427 - exp; + if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist); + return softfloat_roundToI32(sign, sig, roundingMode, exact, status); +} + diff --git a/src/cpu/softfloat3e/f64_to_i32_r_minMag.c b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c new file mode 100644 index 000000000..80e2d6bc3 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c @@ -0,0 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t f64_to_i32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint64_t sig; + int16_t shiftDist; + bool sign; + int32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF64UI(a); + sig = fracF64UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if (53 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + if (shiftDist < 22) { + if (sign && (exp == 0x41E) && (sig < UINT64_C(0x0000000000200000))) { + if (exact && sig) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return -0x7FFFFFFF - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FF) && sig + ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= UINT64_C(0x0010000000000000); + absZ = sig>>shiftDist; + if (exact && ((uint64_t) (uint32_t) absZ< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f64_to_i64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t sig; + int16_t shiftDist; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + sig = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= UINT64_C(0x0010000000000000); + else if (softfloat_denormalsAreZeros(status)) sig = 0; + shiftDist = 0x433 - exp; + if (shiftDist <= 0) { + if (shiftDist < -11) goto invalid; + sigExtra.v = sig<<-shiftDist; + sigExtra.extra = 0; + } else { + sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist); + } + return softfloat_roundToI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FF) && fracF64UI(a) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; +} + diff --git a/src/cpu/softfloat3e/f64_to_i64_r_minMag.c b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c new file mode 100644 index 000000000..eb633eb22 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c @@ -0,0 +1,95 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t f64_to_i64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t sig; + int16_t shiftDist; + uint64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + sig = fracF64UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if (shiftDist <= 0) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (shiftDist < -10) { + if (a == packToF64UI(1, 0x43E, 0)) { + return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1; + } + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FF) && sig + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig |= UINT64_C(0x0010000000000000); + absZ = sig<<-shiftDist; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (53 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig |= UINT64_C(0x0010000000000000); + absZ = sig>>shiftDist; + if (exact && (absZ< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f64_to_ui32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t sig; + int16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + sig = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ((exp == 0x7FF) && sig) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags(status, softfloat_flag_invalid); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= UINT64_C(0x0010000000000000); + else if (softfloat_denormalsAreZeros(status)) sig = 0; + shiftDist = 0x427 - exp; + if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist); + return softfloat_roundToUI32(sign, sig, roundingMode, exact, status); +} diff --git a/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c new file mode 100644 index 000000000..7610d7c37 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c @@ -0,0 +1,83 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t f64_to_ui32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint64_t sig; + int16_t shiftDist; + bool sign; + uint32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF64UI(a); + sig = fracF64UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if (53 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + if (sign || (shiftDist < 21)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FF) && sig + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= UINT64_C(0x0010000000000000); + z = sig>>shiftDist; + if (exact && ((uint64_t) z< +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f64_to_ui64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + bool sign; + int16_t exp; + uint64_t sig; + int16_t shiftDist; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + exp = expF64UI(a); + sig = fracF64UI(a); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (exp) sig |= UINT64_C(0x0010000000000000); + else if (softfloat_denormalsAreZeros(status)) sig = 0; + shiftDist = 0x433 - exp; + if (shiftDist <= 0) { + if (shiftDist < -11) goto invalid; + sigExtra.v = sig<<-shiftDist; + sigExtra.extra = 0; + } else { + sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist); + } + return softfloat_roundToUI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return (exp == 0x7FF) && fracF64UI(a) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; +} diff --git a/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c new file mode 100644 index 000000000..e7bda4c67 --- /dev/null +++ b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c @@ -0,0 +1,87 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t f64_to_ui64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status) +{ + int16_t exp; + uint64_t sig; + int16_t shiftDist; + bool sign; + uint64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp = expF64UI(a); + sig = fracF64UI(a); + if (softfloat_denormalsAreZeros(status)) + if (!exp && sig) sig = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if (53 <= shiftDist) { + if (exact && (exp | sig)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI(a); + if (sign) goto invalid; + if (shiftDist <= 0) { + if (shiftDist < -11) goto invalid; + z = (sig | UINT64_C(0x0010000000000000))<<-shiftDist; + } else { + sig |= UINT64_C(0x0010000000000000); + z = sig>>shiftDist; + if (exact && (uint64_t) (sig<<(-shiftDist & 63))) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return + (exp == 0x7FF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; +} diff --git a/src/cpu/softfloat/fpatan.cc b/src/cpu/softfloat3e/fpatan.cc similarity index 59% rename from src/cpu/softfloat/fpatan.cc rename to src/cpu/softfloat3e/fpatan.cc index f33a3ff66..207dc320a 100644 --- a/src/cpu/softfloat/fpatan.cc +++ b/src/cpu/softfloat3e/fpatan.cc @@ -25,27 +25,31 @@ these four paragraphs for those parts of this code that are retained. #define FLOAT128 -#include "softfloatx80.h" -#include "softfloat-round-pack.h" +#include "config.h" +#include "softfloat.h" +#include "specialize.h" + +#include "fpu_trans.h" #include "fpu_constant.h" +#include "poly.h" #define FPATAN_ARR_SIZE 11 -static const float128 float128_one = +static const float128_t float128_one = packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000)); -static const float128 float128_sqrt3 = +static const float128_t float128_sqrt3 = packFloat128(BX_CONST64(0x3fffbb67ae8584ca), BX_CONST64(0xa73b25742d7078b8)); static const floatx80 floatx80_pi = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235)); -static const float128 float128_pi2 = +static const float128_t float128_pi2 = packFloat128(BX_CONST64(0x3fff921fb54442d1), BX_CONST64(0x8469898CC5170416)); -static const float128 float128_pi4 = +static const float128_t float128_pi4 = packFloat128(BX_CONST64(0x3ffe921fb54442d1), BX_CONST64(0x8469898CC5170416)); -static const float128 float128_pi6 = +static const float128_t float128_pi6 = packFloat128(BX_CONST64(0x3ffe0c152382d736), BX_CONST64(0x58465BB32E0F580F)); -static float128 atan_arr[FPATAN_ARR_SIZE] = +static float128_t atan_arr[FPATAN_ARR_SIZE] = { PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */ @@ -60,10 +64,10 @@ static float128 atan_arr[FPATAN_ARR_SIZE] = PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */ }; -extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status); +extern float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status); /* |x| < 1/4 */ -static float128 poly_atan(float128 x1, struct float_status_t *status) +static float128_t poly_atan(float128_t x1, softfloat_status_t &status) { /* // 3 5 7 9 11 13 15 17 @@ -86,12 +90,11 @@ static float128 poly_atan(float128 x1, struct float_status_t *status) // atan(x) ~ x * [ p(x) + x * q(x) ] // */ - return OddPoly(x1, atan_arr, FPATAN_ARR_SIZE, status); + return OddPoly(x1, (const float128_t*) atan_arr, FPATAN_ARR_SIZE, status); } // ================================================= -// FPATAN Compute y * log (x) -// 2 +// FPATAN Compute arctan(y/x) // ================================================= // @@ -134,125 +137,129 @@ static float128 poly_atan(float128 x1, struct float_status_t *status) // 3 5 7 9 2n+1 // -floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status) +floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) { - float_raise(status, float_flag_invalid); + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { + softfloat_raiseFlags(&status, softfloat_flag_invalid); return floatx80_default_nan; } - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - Bit64u bSig = extractFloatx80Frac(b); - Bit32s bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); + uint64_t aSig = extF80_fraction(a); + int32_t aExp = extF80_exp(a); + int aSign = extF80_sign(a); + uint64_t bSig = extF80_fraction(b); + int32_t bExp = extF80_exp(b); + int bSign = extF80_sign(b); int zSign = aSign ^ bSign; if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) - return propagateFloatx80NaN(a, b, status); + if (bSig<<1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - return propagateFloatx80NaN(a, b, status); + if (aSig<<1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); - if (aSign) { /* return 3PI/4 */ - return roundAndPackFloatx80(80, bSign, - FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status); - } - else { /* return PI/4 */ - return roundAndPackFloatx80(80, bSign, - FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); - } + if (aSign) /* return 3PI/4 */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status); + else /* return PI/4 */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); } - if (aSig && (aExp == 0)) - float_raise(status, float_flag_denormal); + if (aSig && ! aExp) + softfloat_raiseFlags(&status, softfloat_flag_denormal); /* return PI/2 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); } if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - return propagateFloatx80NaN(a, b, status); + if (aSig<<1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); - if (bSig && (bExp == 0)) - float_raise(status, float_flag_denormal); + if (bSig && ! bExp) + softfloat_raiseFlags(&status, softfloat_flag_denormal); return_PI_or_ZERO: - if (aSign) { /* return PI */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); - } else { /* return 0 */ - return packFloatx80(bSign, 0, 0); - } + if (aSign) /* return PI */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); + else /* return 0 */ + return packToExtF80(bSign, 0, 0); } - if (bExp == 0) + if (! bExp) { - if (bSig == 0) { - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); + if (! bSig) { + if (aSig && ! aExp) softfloat_raiseFlags(&status, softfloat_flag_denormal); goto return_PI_or_ZERO; } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig); + bExp = normExpSig.exp + 1; + bSig = normExpSig.sig; } - if (aExp == 0) + if (! aExp) { - if (aSig == 0) /* return PI/2 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + if (! aSig) /* return PI/2 */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig); + aExp = normExpSig.exp + 1; + aSig = normExpSig.sig; } - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); /* |a| = |b| ==> return PI/4 */ - if (aSig == bSig && aExp == bExp) - return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + if (aSig == bSig && aExp == bExp) { + if (aSign) + return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status); + else + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); + } /* ******************************** */ /* using float128 for approximation */ /* ******************************** */ - float128 a128 = normalizeRoundAndPackFloat128(0, aExp-0x10, aSig, 0, status); - float128 b128 = normalizeRoundAndPackFloat128(0, bExp-0x10, bSig, 0, status); - float128 x; + float128_t a128 = softfloat_normRoundPackToF128(0, aExp-0x10, aSig, 0, &status); + float128_t b128 = softfloat_normRoundPackToF128(0, bExp-0x10, bSig, 0, &status); + float128_t x; int swap = 0, add_pi6 = 0, add_pi4 = 0; if (aExp > bExp || (aExp == bExp && aSig > bSig)) { - x = float128_div(b128, a128, status); + x = f128_div(b128, a128, &status); } else { - x = float128_div(a128, b128, status); + x = f128_div(a128, b128, &status); swap = 1; } - Bit32s xExp = extractFloat128Exp(x); + int32_t xExp = expF128UI64(x.v64); if (xExp <= FLOATX80_EXP_BIAS-40) goto approximation_completed; - if (x.hi >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1 + if (x.v64 >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1 { /* arctan(x) = arctan((x-1)/(x+1)) + pi/4 */ - float128 t1 = float128_sub(x, float128_one, status); - float128 t2 = float128_add(x, float128_one, status); - x = float128_div(t1, t2, status); + float128_t t1 = f128_sub(x, float128_one, &status); + float128_t t2 = f128_add(x, float128_one, &status); + x = f128_div(t1, t2, &status); add_pi4 = 1; } else @@ -263,26 +270,26 @@ return_PI_or_ZERO: /* arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6 */ - float128 t1 = float128_mul(x, float128_sqrt3, status); - float128 t2 = float128_add(x, float128_sqrt3, status); - x = float128_sub(t1, float128_one, status); - x = float128_div(x, t2, status); + float128_t t1 = f128_mul(x, float128_sqrt3, &status); + float128_t t2 = f128_add(x, float128_sqrt3, &status); + x = f128_sub(t1, float128_one, &status); + x = f128_div(x, t2, &status); add_pi6 = 1; } } x = poly_atan(x, status); - if (add_pi6) x = float128_add(x, float128_pi6, status); - if (add_pi4) x = float128_add(x, float128_pi4, status); + if (add_pi6) x = f128_add(x, float128_pi6, &status); + if (add_pi4) x = f128_add(x, float128_pi4, &status); approximation_completed: - if (swap) x = float128_sub(float128_pi2, x, status); - floatx80 result = float128_to_floatx80(x, status); + if (swap) x = f128_sub(float128_pi2, x, &status); + floatx80 result = f128_to_extF80(x, &status); if (zSign) floatx80_chs(result); - int rSign = extractFloatx80Sign(result); + int rSign = extF80_sign(result); if (!bSign && rSign) - return floatx80_add(result, floatx80_pi, status); + return extF80_add(result, floatx80_pi, &status); if (bSign && !rSign) - return floatx80_sub(result, floatx80_pi, status); + return extF80_sub(result, floatx80_pi, &status); return result; } diff --git a/src/cpu/softfloat/fprem.cc b/src/cpu/softfloat3e/fprem.cc similarity index 53% rename from src/cpu/softfloat/fprem.cc rename to src/cpu/softfloat3e/fprem.cc index 26637c5c5..2252f1230 100644 --- a/src/cpu/softfloat/fprem.cc +++ b/src/cpu/softfloat3e/fprem.cc @@ -23,100 +23,109 @@ these four paragraphs for those parts of this code that are retained. * Stanislav Shwartsman [sshwarts at sourceforge net] * ==========================================================================*/ -#include "softfloatx80.h" -#include "softfloat-round-pack.h" +#include "fpu_trans.h" #define USE_estimateDiv128To64 -#include "softfloat-macros.h" +#include "softfloat-helpers.h" + +#include "specialize.h" // for softfloat_propagateNaNExtF80UI /* executes single exponent reduction cycle */ -static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1) +static uint64_t remainder_kernel(uint64_t aSig0, uint64_t bSig, int expDiff, uint64_t *zSig0, uint64_t *zSig1) { - Bit64u term0, term1; - Bit64u aSig1 = 0; - + uint128 term, z; + uint64_t aSig1 = 0; shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0); - Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig); - mul64To128(bSig, q, &term0, &term1); - sub128(aSig1, aSig0, term0, term1, zSig1, zSig0); - while ((Bit64s)(*zSig1) < 0) { + uint64_t q = estimateDiv128To64(aSig1, aSig0, bSig); + term = softfloat_mul64To128(bSig, q); + z = softfloat_sub128(aSig1, aSig0, term.v64, term.v0); + while ((int64_t) z.v64 < 0) { --q; - add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0); + z = softfloat_add128(z.v64, z.v0, 0, bSig); } + *zSig0 = z.v0; + *zSig1 = z.v64; return q; } -static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding_mode, struct float_status_t *status) +static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, int rounding_mode, struct softfloat_status_t *status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + static const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - Bit32s aExp, bExp, zExp, expDiff; - Bit64u aSig0, aSig1, bSig; + int32_t aExp, bExp, zExp, expDiff; + uint64_t aSig0, aSig1 = 0, bSig; int aSign; + struct exp32_sig64 normExpSig; + uint128 term; + *q = 0; // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); *r = floatx80_default_nan; return -1; } - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); + aSig0 = extF80_fraction(a); + aExp = extF80_exp(a); + aSign = extF80_sign(a); + bSig = extF80_fraction(b); + bExp = extF80_exp(b); if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) { - *r = propagateFloatx80NaN(a, b, status); + if ((aSig0<<1) || ((bExp == 0x7FFF) && (bSig<<1))) { + *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status); return -1; } - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(status, softfloat_flag_invalid); *r = floatx80_default_nan; return -1; } if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) { - *r = propagateFloatx80NaN(a, b, status); + if (bSig << 1) { + *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status); return -1; } - if (aExp == 0 && aSig0) { - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - *r = (a.fraction & BX_CONST64(0x8000000000000000)) ? - packFloatx80(aSign, aExp, aSig0) : a; + if (! aExp && aSig0) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; + *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a; return 0; } *r = a; return 0; } - if (bExp == 0) { - if (bSig == 0) { - float_raise(status, float_flag_invalid); + if (! bExp) { + if (! bSig) { + softfloat_raiseFlags(status, softfloat_flag_invalid); *r = floatx80_default_nan; return -1; } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(bSig); + bExp = normExpSig.exp + 1; + bSig = normExpSig.sig; } - if (aExp == 0) { - if (aSig0 == 0) { + if (! aExp) { + if (! aSig0) { *r = a; return 0; } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; } - expDiff = aExp - bExp; - aSig1 = 0; - Bit32u overflow = 0; + expDiff = aExp - bExp; + int overflow = 0; if (expDiff >= 64) { int n = (expDiff & 0x1f) | 0x20; @@ -129,11 +138,10 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding if (expDiff < 0) { if (expDiff < -1) { - *r = (a.fraction & BX_CONST64(0x8000000000000000)) ? - packFloatx80(aSign, aExp, aSig0) : a; + *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a; return 0; } - shift128Right(aSig0, 0, 1, &aSig0, &aSig1); + shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1); expDiff = 0; } @@ -147,26 +155,28 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding } } - if (rounding_mode == float_round_nearest_even) - { - Bit64u term0, term1; - shift128Right(bSig, 0, 1, &term0, &term1); + if (rounding_mode == softfloat_round_near_even) { + uint64_t term0, term1; + shortShift128Right(bSig, 0, 1, &term0, &term1); - if (! lt128(aSig0, aSig1, term0, term1)) - { - int lt = lt128(term0, term1, aSig0, aSig1); - int eq = eq128(aSig0, aSig1, term0, term1); + if (! softfloat_lt128(aSig0, aSig1, term0, term1)) { + int lt = softfloat_lt128(term0, term1, aSig0, aSig1); + int eq = softfloat_eq128(aSig0, aSig1, term0, term1); - if ((eq && ((*q) & 1)) || lt) { - aSign = !aSign; - ++(*q); - } - if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1); + if ((eq && ((*q) & 1)) || lt) { + aSign = !aSign; + ++(*q); + } + if (lt) { + term = softfloat_sub128(bSig, 0, aSig0, aSig1); + aSig0 = term.v64; + aSig1 = term.v0; + } } } } - *r = normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1, status); + *r = softfloat_normRoundPackToExtF80(aSign, zExp, aSig0, aSig1, 80, status); return overflow; } @@ -176,9 +186,9 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status) +int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status) { - return do_fprem(a, b, r, q, float_round_nearest_even, status); + return do_fprem(a, b, r, q, softfloat_round_near_even, status); } /*---------------------------------------------------------------------------- @@ -190,7 +200,7 @@ int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, s | quotient of 'a' divided by 'b' to an integer. *----------------------------------------------------------------------------*/ -int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status) +int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status) { - return do_fprem(a, b, r, q, float_round_to_zero, status); + return do_fprem(a, b, r, q, softfloat_round_to_zero, status); } diff --git a/src/cpu/softfloat/fpu_constant.h b/src/cpu/softfloat3e/fpu_constant.h similarity index 98% rename from src/cpu/softfloat/fpu_constant.h rename to src/cpu/softfloat3e/fpu_constant.h index 7a7fc6f1a..d7d44ee3c 100644 --- a/src/cpu/softfloat/fpu_constant.h +++ b/src/cpu/softfloat3e/fpu_constant.h @@ -24,7 +24,7 @@ these four paragraphs for those parts of this code that are retained. #include "config.h" // Pentium CPU uses only 68-bit precision M_PI approximation -//#define BETTER_THAN_PENTIUM +// #define BETTER_THAN_PENTIUM /*============================================================================ * Written for Bochs (x86 achitecture simulator) by diff --git a/src/cpu/softfloat3e/fpu_trans.h b/src/cpu/softfloat3e/fpu_trans.h new file mode 100644 index 000000000..bd3d3cecb --- /dev/null +++ b/src/cpu/softfloat3e/fpu_trans.h @@ -0,0 +1,117 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003-2018 Stanislav Shwartsman +// Written by Stanislav Shwartsman [sshwarts at sourceforge net] +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// +///////////////////////////////////////////////////////////////////////// + +#ifndef _FPU_TRANS_H_ +#define _FPU_TRANS_H_ + +#include "softfloat.h" +#include "softfloat-specialize.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision operations. +*----------------------------------------------------------------------------*/ + +int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status); +int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status); + +floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status); +#ifdef __cplusplus +floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status); +floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status); +floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status); + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision trigonometric functions. +*----------------------------------------------------------------------------*/ + +int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status); +int fsin(floatx80 &a, softfloat_status_t &status); +int fcos(floatx80 &a, softfloat_status_t &status); +int ftan(floatx80 &a, softfloat_status_t &status); +#else +floatx80 fyl2x(floatx80 a, floatx80 b, struct softfloat_status_t *status); +floatx80 fyl2xp1(floatx80 a, floatx80 b, struct softfloat_status_t *status); +floatx80 fpatan(floatx80 a, floatx80 b, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision trigonometric functions. +*----------------------------------------------------------------------------*/ + +int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct softfloat_status_t *status); +int fsin(floatx80 *a, struct softfloat_status_t *status); +int fcos(floatx80 *a, struct softfloat_status_t *status); +int ftan(floatx80 *a, struct softfloat_status_t *status); +#endif + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------- +| Calculates the absolute value of the extended double-precision floating-point +| value `a'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +static __inline floatx80 &floatx80_abs(floatx80 ®) +#else +static __inline floatx80 floatx80_abs(floatx80 reg) +#endif +{ + reg.signExp &= 0x7FFF; + return reg; +} + +/*----------------------------------------------------------------------------- +| Changes the sign of the extended double-precision floating-point value 'a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +static __inline floatx80 &floatx80_chs(floatx80 ®) +#else +static __inline floatx80 floatx80_chs(floatx80 reg) +#endif +{ + reg.signExp ^= 0x8000; + return reg; +} + +#ifdef __cplusplus +static __inline floatx80 FPU_round_const(const floatx80 &a, int adj) +#else +static __inline floatx80 FPU_round_const(const floatx80 a, int adj) +#endif +{ + floatx80 result = a; + result.signif += adj; + return result; +} + +#endif diff --git a/src/cpu/softfloat/fsincos.cc b/src/cpu/softfloat3e/fsincos.cc similarity index 68% rename from src/cpu/softfloat/fsincos.cc rename to src/cpu/softfloat3e/fsincos.cc index f5b33a823..1a2a018de 100644 --- a/src/cpu/softfloat/fsincos.cc +++ b/src/cpu/softfloat3e/fsincos.cc @@ -26,24 +26,29 @@ these four paragraphs for those parts of this code that are retained. #define FLOAT128 #define USE_estimateDiv128To64 -#include "softfloatx80.h" -#include "softfloat-round-pack.h" +#include "config.h" +#include "specialize.h" + +#include "fpu_trans.h" +#include "softfloat-helpers.h" #include "fpu_constant.h" +#include "poly.h" + static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000)); /* reduce trigonometric function argument using 128-bit precision M_PI approximation */ -static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1) +static uint64_t argument_reduction_kernel(uint64_t aSig0, int Exp, uint64_t *zSig0, uint64_t *zSig1) { - Bit64u term0, term1, term2; - Bit64u aSig1 = 0; + uint64_t term0, term1, term2; + uint64_t aSig1 = 0; shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0); - Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI); + uint64_t q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI); mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2); sub128(aSig1, aSig0, term0, term1, zSig1, zSig0); - while ((Bit64s)(*zSig1) < 0) { + while ((int64_t)(*zSig1) < 0) { --q; add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2); } @@ -51,35 +56,35 @@ static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bi return q; } -static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1) +static int reduce_trig_arg(int expDiff, int &zSign, uint64_t &aSig0, uint64_t &aSig1) { - Bit64u term0, term1, q = 0; + uint64_t term0, term1, q = 0; if (expDiff < 0) { - shift128Right(*aSig0, 0, 1, aSig0, aSig1); + shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1); expDiff = 0; } if (expDiff > 0) { - q = argument_reduction_kernel(*aSig0, expDiff, aSig0, aSig1); + q = argument_reduction_kernel(aSig0, expDiff, &aSig0, &aSig1); } else { - if (FLOAT_PI_HI <= *aSig0) { - *aSig0 -= FLOAT_PI_HI; + if (FLOAT_PI_HI <= aSig0) { + aSig0 -= FLOAT_PI_HI; q = 1; } } - shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1); - if (! lt128(*aSig0, *aSig1, term0, term1)) + shortShift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1); + if (! softfloat_lt128(aSig0, aSig1, term0, term1)) { - int lt = lt128(term0, term1, *aSig0, *aSig1); - int eq = eq128(*aSig0, *aSig1, term0, term1); + int lt = softfloat_lt128(term0, term1, aSig0, aSig1); + int eq = softfloat_eq128(aSig0, aSig1, term0, term1); if ((eq && (q & 1)) || lt) { - *zSign = !(*zSign); + zSign = !zSign; ++q; } - if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, *aSig0, *aSig1, aSig0, aSig1); + if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, aSig0, aSig1, &aSig0, &aSig1); } return (int)(q & 3); @@ -88,7 +93,7 @@ static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1 #define SIN_ARR_SIZE 11 #define COS_ARR_SIZE 11 -static float128 sin_arr[SIN_ARR_SIZE] = +static float128_t sin_arr[SIN_ARR_SIZE] = { PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */ @@ -103,7 +108,7 @@ static float128 sin_arr[SIN_ARR_SIZE] = PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */ }; -static float128 cos_arr[COS_ARR_SIZE] = +static float128_t cos_arr[COS_ARR_SIZE] = { PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */ PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */ @@ -118,10 +123,8 @@ static float128 cos_arr[COS_ARR_SIZE] = PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */ }; -extern float128 OddPoly (float128 x, float128 *arr, int n, struct float_status_t *status); - /* 0 <= x <= pi/4 */ -BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status) +static __inline float128_t poly_sin(float128_t x, softfloat_status_t &status) { // 3 5 7 9 11 13 15 // x x x x x x x @@ -143,13 +146,11 @@ BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status) // sin(x) ~ x * [ p(x) + x * q(x) ] // - return OddPoly(x, sin_arr, SIN_ARR_SIZE, status); + return OddPoly(x, (const float128_t*) sin_arr, SIN_ARR_SIZE, status); } -extern float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status); - /* 0 <= x <= pi/4 */ -BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status) +static __inline float128_t poly_cos(float128_t x, softfloat_status_t &status) { // 2 4 6 8 10 12 14 // x x x x x x x @@ -166,22 +167,22 @@ BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status) // cos(x) ~ [ p(x) + x * q(x) ] // - return EvenPoly(x, cos_arr, COS_ARR_SIZE, status); + return EvenPoly(x, (const float128_t*) cos_arr, COS_ARR_SIZE, status); } -BX_CPP_INLINE void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) +static __inline void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) { if (sin_a) *sin_a = a; if (cos_a) *cos_a = a; } -BX_CPP_INLINE void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) +static __inline void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) { if (sin_a) *sin_a = a; if (cos_a) *cos_a = floatx80_one; } -static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struct float_status_t *status) +static floatx80 sincos_approximation(int neg, float128_t r, uint64_t quotient, softfloat_status_t &status) { if (quotient & 0x1) { r = poly_cos(r, status); @@ -190,7 +191,7 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc r = poly_sin(r, status); } - floatx80 result = float128_to_floatx80(r, status); + floatx80 result = f128_to_extF80(r, &status); if (quotient & 0x2) neg = ! neg; @@ -220,59 +221,62 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc // sin(x+2pi) = sin(x) // -int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status) +int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - Bit64u aSig0, aSig1 = 0; - Bit32s aExp, zExp, expDiff; + uint64_t aSig0, aSig1 = 0; + int32_t aExp, zExp, expDiff; int aSign, zSign; int q = 0; // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) { + if (extF80_isUnsupported(a)) { goto invalid; } - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); + aSig0 = extF80_fraction(a); + aExp = extF80_exp(a); + aSign = extF80_sign(a); /* invalid argument */ if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1)) { - sincos_invalid(sin_a, cos_a, propagateFloatx80NaNOne(a, status)); + if (aSig0 << 1) { + sincos_invalid(sin_a, cos_a, softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status)); return 0; } invalid: - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(&status, softfloat_flag_invalid); sincos_invalid(sin_a, cos_a, floatx80_default_nan); return 0; } - if (aExp == 0) { - if (aSig0 == 0) { + if (! aExp) { + if (! aSig0) { sincos_tiny_argument(sin_a, cos_a, a); return 0; } - float_raise(status, float_flag_denormal); + softfloat_raiseFlags(&status, softfloat_flag_denormal); /* handle pseudo denormals */ if (! (aSig0 & BX_CONST64(0x8000000000000000))) { - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); if (sin_a) - float_raise(status, float_flag_underflow); + softfloat_raiseFlags(&status, softfloat_flag_underflow); sincos_tiny_argument(sin_a, cos_a, a); return 0; } - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; } zSign = aSign; @@ -283,7 +287,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t if (expDiff >= 63) return -1; - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); if (expDiff < -1) { // doesn't require reduction if (expDiff <= -68) { @@ -294,7 +298,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t zExp = aExp; } else { - q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1); + q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); } /* **************************** */ @@ -302,7 +306,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t /* **************************** */ /* using float128 for approximation */ - float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status); + float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status); if (aSign) q = -q; if (sin_a) *sin_a = sincos_approximation(zSign, r, q, status); @@ -311,14 +315,14 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t return 0; } -int fsin(floatx80 *a, struct float_status_t *status) +int fsin(floatx80 &a, softfloat_status_t &status) { - return fsincos(*a, a, 0, status); + return fsincos(a, &a, 0, status); } -int fcos(floatx80 *a, struct float_status_t *status) +int fcos(floatx80 &a, softfloat_status_t &status) { - return fsincos(*a, 0, a, status); + return fsincos(a, 0, &a, status); } // ================================================= @@ -348,51 +352,55 @@ int fcos(floatx80 *a, struct float_status_t *status) // cos(x) // -int ftan(floatx80 *a, struct float_status_t *status) +int ftan(floatx80 &a, softfloat_status_t &status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - Bit64u aSig0, aSig1 = 0; - Bit32s aExp, zExp, expDiff; + uint64_t aSig0, aSig1 = 0; + int32_t aExp, zExp, expDiff; int aSign, zSign; int q = 0; // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(*a)) { + if (extF80_isUnsupported(a)) { goto invalid; } - aSig0 = extractFloatx80Frac(*a); - aExp = extractFloatx80Exp(*a); - aSign = extractFloatx80Sign(*a); + aSig0 = extF80_fraction(a); + aExp = extF80_exp(a); + aSign = extF80_sign(a); /* invalid argument */ if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1)) + if (aSig0 << 1) { - *a = propagateFloatx80NaNOne(*a, status); + a = softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status); return 0; } invalid: - float_raise(status, float_flag_invalid); - *a = floatx80_default_nan; + softfloat_raiseFlags(&status, softfloat_flag_invalid); + a = floatx80_default_nan; return 0; } - if (aExp == 0) { - if (aSig0 == 0) return 0; - float_raise(status, float_flag_denormal); + if (! aExp) { + if (! aSig0) return 0; + softfloat_raiseFlags(&status, softfloat_flag_denormal); /* handle pseudo denormals */ if (! (aSig0 & BX_CONST64(0x8000000000000000))) { - float_raise(status, float_flag_inexact | float_flag_underflow); + softfloat_raiseFlags(&status, softfloat_flag_inexact | softfloat_flag_underflow); return 0; } - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); + + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; } zSign = aSign; @@ -403,17 +411,17 @@ int ftan(floatx80 *a, struct float_status_t *status) if (expDiff >= 63) return -1; - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); if (expDiff < -1) { // doesn't require reduction if (expDiff <= -68) { - *a = packFloatx80(aSign, aExp, aSig0); + a = packFloatx80(aSign, aExp, aSig0); return 0; } zExp = aExp; } else { - q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1); + q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); } /* **************************** */ @@ -421,21 +429,21 @@ int ftan(floatx80 *a, struct float_status_t *status) /* **************************** */ /* using float128 for approximation */ - float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status); + float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status); - float128 sin_r = poly_sin(r, status); - float128 cos_r = poly_cos(r, status); + float128_t sin_r = poly_sin(r, status); + float128_t cos_r = poly_cos(r, status); if (q & 0x1) { - r = float128_div(cos_r, sin_r, status); + r = f128_div(cos_r, sin_r, &status); zSign = ! zSign; } else { - r = float128_div(sin_r, cos_r, status); + r = f128_div(sin_r, cos_r, &status); } - *a = float128_to_floatx80(r, status); + a = f128_to_extF80(r, &status); if (zSign) - floatx80_chs(*a); + floatx80_chs(a); return 0; } diff --git a/src/cpu/softfloat/fyl2x.cc b/src/cpu/softfloat3e/fyl2x.cc similarity index 61% rename from src/cpu/softfloat/fyl2x.cc rename to src/cpu/softfloat3e/fyl2x.cc index 875f866a9..7c90e6207 100644 --- a/src/cpu/softfloat/fyl2x.cc +++ b/src/cpu/softfloat3e/fyl2x.cc @@ -24,29 +24,28 @@ these four paragraphs for those parts of this code that are retained. * ==========================================================================*/ #define FLOAT128 - -#include "softfloatx80.h" -#include "softfloat-round-pack.h" +#include "config.h" +#include "fpu_trans.h" +#include "specialize.h" +#include "softfloat-helpers.h" #include "fpu_constant.h" +#include "poly.h" -static const floatx80 floatx80_one = - packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000)); +static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000)); -static const float128 float128_one = +static const float128_t float128_one = packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000)); -static const float128 float128_two = +static const float128_t float128_two = packFloat128(BX_CONST64(0x4000000000000000), BX_CONST64(0x0000000000000000)); -static const float128 float128_ln2inv2 = +static const float128_t float128_ln2inv2 = packFloat128(BX_CONST64(0x400071547652b82f), BX_CONST64(0xe1777d0ffda0d23a)); #define SQRT2_HALF_SIG BX_CONST64(0xb504f333f9de6484) -extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status); - #define L2_ARR_SIZE 9 -static float128 ln_arr[L2_ARR_SIZE] = +static float128_t ln_arr[L2_ARR_SIZE] = { PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */ @@ -59,7 +58,7 @@ static float128 ln_arr[L2_ARR_SIZE] = PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */ }; -static float128 poly_ln(float128 x1, struct float_status_t *status) +static float128_t poly_ln(float128_t x1, softfloat_status_t &status) { /* // @@ -84,28 +83,28 @@ static float128 poly_ln(float128 x1, struct float_status_t *status) // 1-u // */ - return OddPoly(x1, ln_arr, L2_ARR_SIZE, status); + return OddPoly(x1, (const float128_t*) ln_arr, L2_ARR_SIZE, status); } /* required sqrt(2)/2 < x < sqrt(2) */ -static float128 poly_l2(float128 x, struct float_status_t *status) +static float128_t poly_l2(float128_t x, softfloat_status_t &status) { /* using float128 for approximation */ - float128 x_p1 = float128_add(x, float128_one, status); - float128 x_m1 = float128_sub(x, float128_one, status); - x = float128_div(x_m1, x_p1, status); + float128_t x_p1 = f128_add(x, float128_one, &status); + float128_t x_m1 = f128_sub(x, float128_one, &status); + x = f128_div(x_m1, x_p1, &status); x = poly_ln(x, status); - x = float128_mul(x, float128_ln2inv2, status); + x = f128_mul(x, float128_ln2inv2, &status); return x; } -static float128 poly_l2p1(float128 x, struct float_status_t *status) +static float128_t poly_l2p1(float128_t x, softfloat_status_t &status) { /* using float128 for approximation */ - float128 x_p2 = float128_add(x, float128_two, status); - x = float128_div(x, x_p2, status); + float128_t x_plus2 = f128_add(x, float128_two, &status); + x = f128_div(x, x_plus2, &status); x = poly_ln(x, status); - x = float128_mul(x, float128_ln2inv2, status); + x = f128_mul(x, float128_ln2inv2, &status); return x; } @@ -134,7 +133,7 @@ static float128 poly_l2p1(float128 x, struct float_status_t *status) // 1-u 3 5 7 2n+1 // -floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status) +floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status) { /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. @@ -142,71 +141,73 @@ floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status) const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) { + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { invalid: - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(&status, softfloat_flag_invalid); return floatx80_default_nan; } - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - Bit64u bSig = extractFloatx80Frac(b); - Bit32s bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); + uint64_t aSig = extF80_fraction(a); + int32_t aExp = extF80_exp(a); + int aSign = extF80_sign(a); + uint64_t bSig = extF80_fraction(b); + int32_t bExp = extF80_exp(b); + int bSign = extF80_sign(b); int zSign = bSign ^ 1; if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) - || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) - { - return propagateFloatx80NaN(a, b, status); + if ((aSig<<1) || ((bExp == 0x7FFF) && (bSig<<1))) { + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); } if (aSign) goto invalid; else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(status, float_flag_denormal); + if (! bExp) { + if (! bSig) goto invalid; + softfloat_raiseFlags(&status, softfloat_flag_denormal); } return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } } - if (bExp == 0x7FFF) - { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aSign && (Bit64u)(aExp | aSig)) goto invalid; - if (aSig && (aExp == 0)) - float_raise(status, float_flag_denormal); + if (bExp == 0x7FFF) { + if (bSig << 1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); + if (aSign && (uint64_t)(aExp | aSig)) goto invalid; + if (aSig && ! aExp) + softfloat_raiseFlags(&status, softfloat_flag_denormal); if (aExp < 0x3FFF) { return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } - if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid; + if (aExp == 0x3FFF && ! (aSig<<1)) goto invalid; return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } - if (aExp == 0) { - if (aSig == 0) { + if (! aExp) { + if (! aSig) { if ((bExp | bSig) == 0) goto invalid; - float_raise(status, float_flag_divbyzero); + softfloat_raiseFlags(&status, softfloat_flag_divbyzero); return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } if (aSign) goto invalid; - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig); + aExp = normExpSig.exp + 1; + aSig = normExpSig.sig; } if (aSign) goto invalid; - if (bExp == 0) { - if (bSig == 0) { + if (! bExp) { + if (! bSig) { if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0); return packFloatx80(bSign, 0, 0); } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig); + bExp = normExpSig.exp + 1; + bSig = normExpSig.sig; } - if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) + if (aExp == 0x3FFF && ! (aSig<<1)) return packFloatx80(bSign, 0, 0); - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); int ExpDiff = aExp - 0x3FFF; aExp = 0; @@ -219,12 +220,15 @@ invalid: /* using float128 for approximation */ /* ******************************** */ - Bit64u zSig0, zSig1; - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128Four(0, aExp+0x3FFF, zSig0, zSig1); + float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status); + + uint64_t zSig0, zSig1; + shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); + float128_t x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1); x = poly_l2(x, status); - x = float128_add(x, int64_to_float128((Bit64s) ExpDiff), status); - return floatx80_128_mul(b, x, status); + x = f128_add(x, i32_to_f128(ExpDiff), &status); + x = f128_mul(x, b128, &status); + return f128_to_extF80(x, &status); } // ================================================= @@ -252,112 +256,117 @@ invalid: // 1-u 3 5 7 2n+1 // -floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status) +floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status) { + int32_t aExp, bExp; + uint64_t aSig, bSig, zSig0, zSig1, zSig2; + int aSign, bSign; + /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - Bit32s aExp, bExp; - Bit64u aSig, bSig, zSig0, zSig1, zSig2; - int aSign, bSign; - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) { + if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { invalid: - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(&status, softfloat_flag_invalid); return floatx80_default_nan; } - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); + + aSig = extF80_fraction(a); + aExp = extF80_exp(a); + aSign = extF80_sign(a); + bSig = extF80_fraction(b); + bExp = extF80_exp(b); + bSign = extF80_sign(b); int zSign = aSign ^ bSign; if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) - || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) - { - return propagateFloatx80NaN(a, b, status); + if ((aSig<<1) != 0 || ((bExp == 0x7FFF) && (bSig<<1) != 0)) { + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); } if (aSign) goto invalid; else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(status, float_flag_denormal); + if (! bExp) { + if (! bSig) goto invalid; + softfloat_raiseFlags(&status, softfloat_flag_denormal); } return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } } if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) - return propagateFloatx80NaN(a, b, status); + if (bSig << 1) + return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status); - if (aExp == 0) { - if (aSig == 0) goto invalid; - float_raise(status, float_flag_denormal); + if (! aExp) { + if (! aSig) goto invalid; + softfloat_raiseFlags(&status, softfloat_flag_denormal); } return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); + if (! aExp) { + if (! aSig) { + if (bSig && ! bExp) softfloat_raiseFlags(&status, softfloat_flag_denormal); return packFloatx80(zSign, 0, 0); } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig); + aExp = normExpSig.exp + 1; + aSig = normExpSig.sig; } - if (bExp == 0) { - if (bSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + if (! bExp) { + if (! bSig) return packFloatx80(zSign, 0, 0); + softfloat_raiseFlags(&status, softfloat_flag_denormal); + struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig); + bExp = normExpSig.exp + 1; + bSig = normExpSig.sig; } - float_raise(status, float_flag_inexact); + softfloat_raiseFlags(&status, softfloat_flag_inexact); if (aSign && aExp >= 0x3FFF) return a; if (aExp >= 0x3FFC) // big argument { - return fyl2x(floatx80_add(a, floatx80_one, status), b, status); + return fyl2x(extF80_add(a, floatx80_one, &status), b, status); } // handle tiny argument if (aExp < FLOATX80_EXP_BIAS-70) { // first order approximation, return (a*b)/ln(2) - Bit32s zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; + int32_t zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; - mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2); - if (0 < (Bit64s) zSig0) { + mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2); + if (0 < (int64_t) zSig0) { shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); --zExp; } zExp = zExp + bExp - 0x3FFE; - mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2); - if (0 < (Bit64s) zSig0) { + mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2); + if (0 < (int64_t) zSig0) { shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); --zExp; } - return - roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1, status); + return softfloat_roundPackToExtF80(aSign ^ bSign, zExp, zSig0, zSig1, 80, &status); } /* ******************************** */ /* using float128 for approximation */ /* ******************************** */ - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128Four(aSign, aExp, zSig0, zSig1); + float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status); + + shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); + float128_t x = packFloat128(aSign, aExp, zSig0, zSig1); x = poly_l2p1(x, status); - return floatx80_128_mul(b, x, status); + x = f128_mul(x, b128, &status); + return f128_to_extF80(x, &status); } diff --git a/src/cpu/softfloat3e/i32_to_extF80.cc b/src/cpu/softfloat3e/i32_to_extF80.cc new file mode 100644 index 000000000..edd92ced0 --- /dev/null +++ b/src/cpu/softfloat3e/i32_to_extF80.cc @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +extFloat80_t i32_to_extF80(int32_t a) +{ + uint16_t uiZ64; + uint32_t absA; + bool sign; + int8_t shiftDist; + extFloat80_t z; + + uiZ64 = 0; + absA = 0; + if (a) { + sign = (a < 0); + absA = sign ? -(uint32_t) a : (uint32_t) a; + shiftDist = softfloat_countLeadingZeros32(absA); + uiZ64 = packToExtF80UI64(sign, 0x401E - shiftDist); + absA <<= shiftDist; + } + z.signExp = uiZ64; + z.signif = (uint64_t) absA<<32; + return z; +} diff --git a/src/cpu/softfloat3e/i32_to_f128.cc b/src/cpu/softfloat3e/i32_to_f128.cc new file mode 100644 index 000000000..1ae64e46b --- /dev/null +++ b/src/cpu/softfloat3e/i32_to_f128.cc @@ -0,0 +1,59 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float128_t i32_to_f128(int32_t a) +{ + uint64_t uiZ64; + bool sign; + uint32_t absA; + int8_t shiftDist; + float128_t z; + + uiZ64 = 0; + if (a) { + sign = (a < 0); + absA = sign ? -(uint32_t) a : (uint32_t) a; + shiftDist = softfloat_countLeadingZeros32(absA) + 17; + uiZ64 = packToF128UI64(sign, 0x402E - shiftDist, (uint64_t) absA< +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float16 i32_to_f16(int32_t a, struct softfloat_status_t *status) +{ + bool sign; + uint32_t absA; + int8_t shiftDist; + uint16_t sig; + + sign = (a < 0); + absA = sign ? -(uint32_t) a : (uint32_t) a; + shiftDist = softfloat_countLeadingZeros32(absA) - 21; + if (0 <= shiftDist) { + return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA<>(-shiftDist) | ((uint32_t) (absA<<(shiftDist & 31)) != 0) + : (uint16_t) absA< +#include +#include "internals.h" +#include "softfloat.h" + +float32 i32_to_f32(int32_t a, struct softfloat_status_t *status) +{ + bool sign; + uint32_t absA; + + sign = (a < 0); + if (! (a & 0x7FFFFFFF)) { + return sign ? packToF32UI(1, 0x9E, 0) : 0; + } + absA = sign ? -(uint32_t) a : (uint32_t) a; + return softfloat_normRoundPackToF32(sign, 0x9C, absA, status); +} diff --git a/src/cpu/softfloat3e/i32_to_f64.c b/src/cpu/softfloat3e/i32_to_f64.c new file mode 100644 index 000000000..7aaa4e1c2 --- /dev/null +++ b/src/cpu/softfloat3e/i32_to_f64.c @@ -0,0 +1,56 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float64 i32_to_f64(int32_t a) +{ + bool sign; + uint32_t absA; + int8_t shiftDist; + + if (! a) { + return 0; + } else { + sign = (a < 0); + absA = sign ? -(uint32_t) a : (uint32_t) a; + shiftDist = softfloat_countLeadingZeros32(absA) + 21; + return packToF64UI(sign, 0x432 - shiftDist, (uint64_t) absA< +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +extFloat80_t i64_to_extF80(int64_t a) +{ + uint16_t uiZ64; + uint64_t absA; + bool sign; + int8_t shiftDist; + extFloat80_t z; + + uiZ64 = 0; + absA = 0; + if (a) { + sign = (a < 0); + absA = sign ? -(uint64_t) a : (uint64_t) a; + shiftDist = softfloat_countLeadingZeros64(absA); + uiZ64 = packToExtF80UI64(sign, 0x403E - shiftDist); + absA <<= shiftDist; + } + z.signExp = uiZ64; + z.signif = absA; + return z; +} diff --git a/src/cpu/softfloat3e/i64_to_f128.cc b/src/cpu/softfloat3e/i64_to_f128.cc new file mode 100644 index 000000000..4d80a9e7a --- /dev/null +++ b/src/cpu/softfloat3e/i64_to_f128.cc @@ -0,0 +1,69 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float128_t i64_to_f128(int64_t a) +{ + uint64_t uiZ64, uiZ0; + bool sign; + uint64_t absA; + int8_t shiftDist; + struct uint128 zSig; + float128_t z; + + if (! a) { + uiZ64 = 0; + uiZ0 = 0; + } else { + sign = (a < 0); + absA = sign ? -(uint64_t) a : (uint64_t) a; + shiftDist = softfloat_countLeadingZeros64(absA) + 49; + if (64 <= shiftDist) { + zSig.v64 = absA<<(shiftDist - 64); + zSig.v0 = 0; + } else { + zSig = softfloat_shortShiftLeft128(0, absA, shiftDist); + } + uiZ64 = packToF128UI64(sign, 0x406E - shiftDist, zSig.v64); + uiZ0 = zSig.v0; + } + z.v64 = uiZ64; + z.v0 = uiZ0; + return z; +} diff --git a/src/cpu/softfloat3e/i64_to_f16.c b/src/cpu/softfloat3e/i64_to_f16.c new file mode 100644 index 000000000..43873610a --- /dev/null +++ b/src/cpu/softfloat3e/i64_to_f16.c @@ -0,0 +1,61 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float16 i64_to_f16(int64_t a, struct softfloat_status_t *status) +{ + bool sign; + uint64_t absA; + int8_t shiftDist; + uint16_t sig; + + sign = (a < 0); + absA = sign ? -(uint64_t) a : (uint64_t) a; + shiftDist = softfloat_countLeadingZeros64(absA) - 53; + if (0 <= shiftDist) { + return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA< +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float32 i64_to_f32(int64_t a, struct softfloat_status_t *status) +{ + bool sign; + uint64_t absA; + int8_t shiftDist; + uint32_t sig; + + sign = (a < 0); + absA = sign ? -(uint64_t) a : (uint64_t) a; + shiftDist = softfloat_countLeadingZeros64(absA) - 40; + if (0 <= shiftDist) { + return a ? packToF32UI(sign, 0x95 - shiftDist, (uint32_t) absA< +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float64 i64_to_f64(int64_t a, struct softfloat_status_t *status) +{ + bool sign; + uint64_t absA; + + sign = (a < 0); + if (! (a & UINT64_C(0x7FFFFFFFFFFFFFFF))) { + return sign ? packToF64UI(1, 0x43E, 0) : 0; + } + absA = sign ? -(uint64_t) a : (uint64_t) a; + return softfloat_normRoundPackToF64(sign, 0x43C, absA, status); +} diff --git a/src/cpu/softfloat3e/internals.h b/src/cpu/softfloat3e/internals.h new file mode 100644 index 000000000..3b5d7aa4d --- /dev/null +++ b/src/cpu/softfloat3e/internals.h @@ -0,0 +1,150 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef _INTERNALS_H_ +#define _INTERNALS_H_ + +#include +#include +//#include "primitives.h" +#include "softfloat_types.h" + +struct softfloat_status_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +uint32_t softfloat_roundToUI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *); +uint64_t softfloat_roundToUI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *); + +int32_t softfloat_roundToI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *); +int64_t softfloat_roundToI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + + +#define signF16UI(a) ((bool) ((uint16_t) (a)>>15)) +#define expF16UI(a) ((int8_t) ((a)>>10) & 0x1F) +#define fracF16UI(a) ((a) & 0x03FF) +#define packToF16UI(sign, exp, sig) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig)) + +#define isNaNF16UI(a) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF)) + +struct exp8_sig16 { int8_t exp; uint16_t sig; }; +struct exp8_sig16 softfloat_normSubnormalF16Sig(uint16_t); + +float16 softfloat_roundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *); +float16 softfloat_normRoundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF32UI(a) ((bool) ((uint32_t) (a)>>31)) +#define expF32UI(a) ((int16_t) ((a)>>23) & 0xFF) +#define fracF32UI(a) ((a) & 0x007FFFFF) +#define packToF32UI(sign, exp, sig) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) + +#define isNaNF32UI(a) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) + +struct exp16_sig32 { int16_t exp; uint32_t sig; }; +struct exp16_sig32 softfloat_normSubnormalF32Sig(uint32_t); + +float32 softfloat_roundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *); +float32 softfloat_normRoundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF64UI(a) ((bool) ((uint64_t) (a)>>63)) +#define expF64UI(a) ((int16_t) ((a)>>52) & 0x7FF) +#define fracF64UI(a) ((a) & UINT64_C(0x000FFFFFFFFFFFFF)) +#define packToF64UI(sign, exp, sig) ((uint64_t) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<52) + (sig))) + +#define isNaNF64UI(a) (((~(a) & UINT64_C(0x7FF0000000000000)) == 0) && ((a) & UINT64_C(0x000FFFFFFFFFFFFF))) + +struct exp16_sig64 { int16_t exp; uint64_t sig; }; +struct exp16_sig64 softfloat_normSubnormalF64Sig(uint64_t); + +float64 softfloat_roundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *); +float64 softfloat_normRoundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status); +extFloat80_t softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status); + +#define signExtF80UI64(a64) ((bool) ((uint16_t) (a64)>>15)) +#define expExtF80UI64(a64) ((a64) & 0x7FFF) +#define packToExtF80UI64(sign, exp) ((uint16_t) (sign)<<15 | (exp)) + +#define isNaNExtF80UI(a64, a0) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C(0x7FFFFFFFFFFFFFFF))) + +extFloat80_t packToExtF80(bool, uint16_t, uint64_t); +extFloat80_t packToExtF80_twoargs(uint16_t, uint64_t); +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +struct exp32_sig64 { int32_t exp; uint64_t sig; }; +struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint64_t); + +extFloat80_t + softfloat_roundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *); +extFloat80_t + softfloat_normRoundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF128UI64(a64) ((bool) ((uint64_t) (a64)>>63)) +#define expF128UI64(a64) ((int32_t) ((a64)>>48) & 0x7FFF) +#define fracF128UI64(a64) ((a64) & UINT64_C(0x0000FFFFFFFFFFFF)) +#define packToF128UI64(sign, exp, sig64) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<48) + (sig64)) + +#define isNaNF128UI(a64, a0) (((~(a64) & UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64) & UINT64_C(0x0000FFFFFFFFFFFF)))) + +struct exp32_sig128 { int32_t exp; struct uint128 sig; }; +struct exp32_sig128 softfloat_normSubnormalF128Sig(uint64_t, uint64_t); + +float128_t + softfloat_roundPackToF128(bool, int32_t, uint64_t, uint64_t, uint64_t, struct softfloat_status_t *); +float128_t + softfloat_normRoundPackToF128(bool, int32_t, uint64_t, uint64_t, struct softfloat_status_t *); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpu/softfloat3e/isNaN.cc b/src/cpu/softfloat3e/isNaN.cc new file mode 100644 index 000000000..8c0bd1912 --- /dev/null +++ b/src/cpu/softfloat3e/isNaN.cc @@ -0,0 +1,63 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_isNaN(float16 a) +{ + return isNaNF16UI(a); +} + +bool f32_isNaN(float32 a) +{ + return isNaNF32UI(a); +} + +bool f64_isNaN(float64 a) +{ + return isNaNF64UI(a); +} + +bool extF80_isNaN(extFloat80_t a) +{ + return isNaNExtF80UI(a.signExp, a.signif); +} + +bool f128_isNaN(float128_t a) +{ + return isNaNF128UI(a.v64, a.v0); +} diff --git a/src/cpu/softfloat3e/isSignalingNaN.cc b/src/cpu/softfloat3e/isSignalingNaN.cc new file mode 100644 index 000000000..994ac3784 --- /dev/null +++ b/src/cpu/softfloat3e/isSignalingNaN.cc @@ -0,0 +1,63 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_isSignalingNaN(float16 a) +{ + return softfloat_isSigNaNF16UI(a); +} + +bool f32_isSignalingNaN(float32 a) +{ + return softfloat_isSigNaNF32UI(a); +} + +bool f64_isSignalingNaN(float64 a) +{ + return softfloat_isSigNaNF64UI(a); +} + +bool extF80_isSignalingNaN(extFloat80_t a) +{ + return softfloat_isSigNaNExtF80UI(a.signExp, a.signif); +} + +bool f128_isSignalingNaN(float128_t a) +{ + return softfloat_isSigNaNF128UI(a.v64, a.v0); +} diff --git a/src/cpu/softfloat3e/opts-GCC.h b/src/cpu/softfloat3e/opts-GCC.h new file mode 100644 index 000000000..dd6c0ab64 --- /dev/null +++ b/src/cpu/softfloat3e/opts-GCC.h @@ -0,0 +1,110 @@ + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2017 The Regents of the University of California. All rights +reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef _OPTS_GCC_H_ +#define _OPTS_GCC_H_ + +#include +#include "primitiveTypes.h" + +#ifdef SOFTFLOAT_BUILTIN_CLZ + +static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a) + { return a ? __builtin_clz(a) - 16 : 16; } +#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 + +static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a) + { return a ? __builtin_clz(a) : 32; } +#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 + +static __inline uint8_t softfloat_countLeadingZeros64(uint64_t a) + { return a ? __builtin_clzll(a) : 64; } +#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 + +#endif + +#ifdef SOFTFLOAT_INTRINSIC_INT128 + +static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) +{ + union { unsigned __int128 ui; struct uint128 s; } uZ; + uZ.ui = (unsigned __int128) a * ((uint64_t) b<<32); + return uZ.s; +} +#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128 + +static __inline struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b) +{ + union { unsigned __int128 ui; struct uint128 s; } uZ; + uZ.ui = (unsigned __int128) a * b; + return uZ.s; +} +#define softfloat_mul64To128 softfloat_mul64To128 + +static __inline +struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) +{ + union { unsigned __int128 ui; struct uint128 s; } uZ; + uZ.ui = ((unsigned __int128) a64<<64 | a0) * b; + return uZ.s; +} +#define softfloat_mul128By32 softfloat_mul128By32 + +static __inline +void + softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr) +{ + unsigned __int128 z0, mid1, mid, z128; + z0 = (unsigned __int128) a0 * b0; + mid1 = (unsigned __int128) a64 * b0; + mid = mid1 + (unsigned __int128) a0 * b64; + z128 = (unsigned __int128) a64 * b64; + z128 += (unsigned __int128) (mid < mid1)<<64 | mid>>64; + mid <<= 64; + z0 += mid; + z128 += (z0 < mid); + zPtr[indexWord(4, 0)] = z0; + zPtr[indexWord(4, 1)] = z0>>64; + zPtr[indexWord(4, 2)] = z128; + zPtr[indexWord(4, 3)] = z128>>64; +} +#define softfloat_mul128To256M softfloat_mul128To256M + +#endif + +#endif + +#endif diff --git a/src/cpu/softfloat/softfloat_poly.cc b/src/cpu/softfloat3e/poly.cc similarity index 84% rename from src/cpu/softfloat/softfloat_poly.cc rename to src/cpu/softfloat3e/poly.cc index 5c7079353..a89d7f03f 100644 --- a/src/cpu/softfloat/softfloat_poly.cc +++ b/src/cpu/softfloat3e/poly.cc @@ -23,10 +23,10 @@ these four paragraphs for those parts of this code that are retained. * Stanislav Shwartsman [sshwarts at sourceforge net] * ==========================================================================*/ -#define FLOAT128 - #include + #include "softfloat.h" +#include "poly.h" // 2 3 4 n // f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x) @@ -39,13 +39,15 @@ these four paragraphs for those parts of this code that are retained. // f(x) ~ [ p(x) + x * q(x) ] // -float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status) +float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status) { - float128 r = arr[--n]; + float128_t r = arr[--n]; do { - r = float128_mul(r, x, status); - r = float128_add(r, arr[--n], status); + r = f128_mulAdd(r, x, arr[--n], 0, status); +// r = f128_mul(r, x, &status); +// r = f128_add(r, arr[--n], &status); + } while (n > 0); return r; @@ -63,9 +65,9 @@ float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *statu // f(x) ~ [ p(x) + x * q(x) ] // -float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status) +float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status) { - return EvalPoly(float128_mul(x, x, status), arr, n, status); + return EvalPoly(f128_mul(x, x, &status), arr, n, &status); } // 3 5 7 9 2n+1 @@ -83,7 +85,7 @@ float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *statu // f(x) ~ x * [ p(x) + x * q(x) ] // -float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status) +float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status) { - return float128_mul(x, EvenPoly(x, arr, n, status), status); + return f128_mul(x, EvenPoly(x, arr, n, status), &status); } diff --git a/src/cpu/softfloat3e/poly.h b/src/cpu/softfloat3e/poly.h new file mode 100644 index 000000000..1d6c3170c --- /dev/null +++ b/src/cpu/softfloat3e/poly.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003-2018 Stanislav Shwartsman +// Written by Stanislav Shwartsman [sshwarts at sourceforge net] +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// +///////////////////////////////////////////////////////////////////////// + +#ifndef _POLY_H_ +#define _POLY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status); +float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status); +#else +float128_t EvenPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status); +float128_t OddPoly(float128_t x, const float128_t *arr, int n, struct float_status_t *status); +#endif // __cplusplus + +#ifdef __cplusplus +} +#endif + +#endif // _POLY_H_ diff --git a/src/cpu/softfloat3e/primitiveTypes.h b/src/cpu/softfloat3e/primitiveTypes.h new file mode 100644 index 000000000..67751372f --- /dev/null +++ b/src/cpu/softfloat3e/primitiveTypes.h @@ -0,0 +1,54 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef primitiveTypes_h +#define primitiveTypes_h + +/*---------------------------------------------------------------------------- +| These macros are used to isolate the differences in word order between big- +| endian and little-endian platforms. +*----------------------------------------------------------------------------*/ +#define wordIncr 1 +#define indexWord(total, n) (n) +#define indexWordHi(total) ((total) - 1) +#define indexWordLo(total) 0 +#define indexMultiword(total, m, n) (n) +#define indexMultiwordHi(total, n) ((total) - (n)) +#define indexMultiwordLo(total, n) 0 +#define indexMultiwordHiBut(total, n) (n) +#define indexMultiwordLoBut(total, n) 0 +#define INIT_UINTM4(v3, v2, v1, v0) { v0, v1, v2, v3 } + +#endif diff --git a/src/cpu/softfloat3e/primitives.h b/src/cpu/softfloat3e/primitives.h new file mode 100644 index 000000000..993067996 --- /dev/null +++ b/src/cpu/softfloat3e/primitives.h @@ -0,0 +1,535 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef _PRIMITIVES_H_ +#define _PRIMITIVES_H_ + +#include +#include +#include "softfloat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SOFTFLOAT_FAST_DIV64TO32 + +#ifndef softfloat_shortShiftRightJam64 +/*---------------------------------------------------------------------------- +| Shifts 'a' right by the number of bits given in 'dist', which must be in +| the range 1 to 63. If any nonzero bits are shifted off, they are "jammed" +| into the least-significant bit of the shifted value by setting the least- +| significant bit to 1. This shifted-and-jammed value is returned. +*----------------------------------------------------------------------------*/ +static __inline +uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint8_t dist) +{ + return a>>dist | ((a & (((uint64_t) 1<>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); +} +#endif + +#ifndef softfloat_shiftRightJam64 +/*---------------------------------------------------------------------------- +| Shifts 'a' right by the number of bits given in 'dist', which must not +| be zero. If any nonzero bits are shifted off, they are "jammed" into the +| least-significant bit of the shifted value by setting the least-significant +| bit to 1. This shifted-and-jammed value is returned. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than 64, the result will be either 0 or 1, depending on whether 'a' +| is zero or nonzero. +*----------------------------------------------------------------------------*/ +static __inline uint64_t softfloat_shiftRightJam64(uint64_t a, uint32_t dist) +{ + return (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); +} +#endif + +/*---------------------------------------------------------------------------- +| A constant table that translates an 8-bit unsigned integer (the array index) +| into the number of leading 0 bits before the most-significant 1 of that +| integer. For integer zero (index 0), the corresponding table element is 8. +*----------------------------------------------------------------------------*/ +extern const uint_least8_t softfloat_countLeadingZeros8[256]; + +#ifndef softfloat_countLeadingZeros16 +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| 'a'. If 'a' is zero, 16 is returned. +*----------------------------------------------------------------------------*/ +static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a) +{ + uint8_t count = 8; + if (0x100 <= a) { + count = 0; + a >>= 8; + } + count += softfloat_countLeadingZeros8[a]; + return count; +} +#endif + +#ifndef softfloat_countLeadingZeros32 +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| 'a'. If 'a' is zero, 32 is returned. +*----------------------------------------------------------------------------*/ +static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a) +{ + uint8_t count = 0; + if (a < 0x10000) { + count = 16; + a <<= 16; + } + if (a < 0x1000000) { + count += 8; + a <<= 8; + } + count += softfloat_countLeadingZeros8[a>>24]; + return count; +} +#endif + +#ifndef softfloat_countLeadingZeros64 +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| 'a'. If 'a' is zero, 64 is returned. +*----------------------------------------------------------------------------*/ +uint8_t softfloat_countLeadingZeros64(uint64_t a); +#endif + +extern const uint16_t softfloat_approxRecip_1k0s[16]; +extern const uint16_t softfloat_approxRecip_1k1s[16]; + +#ifndef softfloat_approxRecip32_1 +/*---------------------------------------------------------------------------- +| Returns an approximation to the reciprocal of the number represented by 'a', +| where 'a' is interpreted as an unsigned fixed-point number with one integer +| bit and 31 fraction bits. The 'a' input must be "normalized", meaning that +| its most-significant bit (bit 31) must be 1. Thus, if A is the value of +| the fixed-point interpretation of 'a', then 1 <= A < 2. The returned value +| is interpreted as a pure unsigned fraction, having no integer bits and 32 +| fraction bits. The approximation returned is never greater than the true +| reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp +| (units in the last place). +*----------------------------------------------------------------------------*/ +#ifdef SOFTFLOAT_FAST_DIV64TO32 +#define softfloat_approxRecip32_1(a) ((uint32_t) (UINT64_C(0x7FFFFFFFFFFFFFFF) / (uint32_t) (a))) +#endif +#endif + +extern const uint16_t softfloat_approxRecipSqrt_1k0s[16]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[16]; + +/*---------------------------------------------------------------------------- +| Returns an approximation to the reciprocal of the square root of the number +| represented by 'a', where 'a' is interpreted as an unsigned fixed-point +| number either with one integer bit and 31 fraction bits or with two integer +| bits and 30 fraction bits. The format of 'a' is determined by 'oddExpA', +| which must be either 0 or 1. If 'oddExpA' is 1, 'a' is interpreted as +| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having +| two integer bits. The 'a' input must be "normalized", meaning that its +| most-significant bit (bit 31) must be 1. Thus, if A is the value of the +| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA' +| is 1, and 2 <= A < 4 when 'oddExpA' is 0. +| The returned value is interpreted as a pure unsigned fraction, having +| no integer bits and 32 fraction bits. The approximation returned is never +| greater than the true reciprocal 1/sqrt(A), and it differs from the true +| reciprocal by at most 2.06 ulp (units in the last place). The approximation +| returned is also always within the range 0.5 to 1; thus, the most- +| significant bit of the result is always set. +*----------------------------------------------------------------------------*/ +uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a); + +/*---------------------------------------------------------------------------- +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating +| 'b64' and 'b0'. +*----------------------------------------------------------------------------*/ +static __inline +bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 == b64) && (a0 == b0); +} + +/*---------------------------------------------------------------------------- +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is less than or equal to the 128-bit unsigned integer formed by +| concatenating 'b64' and 'b0'. +*----------------------------------------------------------------------------*/ +static __inline +bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); +} + +/*---------------------------------------------------------------------------- +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is less than the 128-bit unsigned integer formed by concatenating +| 'b64' and 'b0'. +*----------------------------------------------------------------------------*/ +static __inline +bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 < b64) || ((a64 == b64) && (a0 < b0)); +} + +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the +| number of bits given in 'dist', which must be in the range 1 to 63. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint8_t dist) +{ + struct uint128 z; + z.v64 = a64<>(-dist & 63); + z.v0 = a0<>dist; + z.v0 = a64<<(-dist & 63) | a0>>dist; + return z; +} + +/*---------------------------------------------------------------------------- +| This function is the same as 'softfloat_shiftRightJam64Extra' (below), +| except that 'dist' must be in the range 1 to 63. +*----------------------------------------------------------------------------*/ +static __inline +struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint8_t dist) +{ + struct uint64_extra z; + z.v = a>>dist; + z.extra = a<<(-dist & 63) | (extra != 0); + return z; +} + +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the +| number of bits given in 'dist', which must be in the range 1 to 63. If any +| nonzero bits are shifted off, they are "jammed" into the least-significant +| bit of the shifted value by setting the least-significant bit to 1. This +| shifted-and-jammed value is returned. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint8_t dist) +{ + uint8_t negDist = -dist; + struct uint128 z; + z.v64 = a64>>dist; + z.v0 = + a64<<(negDist & 63) | a0>>dist + | ((uint64_t) (a0<<(negDist & 63)) != 0); + return z; +} + +/*---------------------------------------------------------------------------- +| This function is the same as 'softfloat_shiftRightJam128Extra' (below), +| except that 'dist' must be in the range 1 to 63. +*----------------------------------------------------------------------------*/ +struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist) +{ + uint8_t negDist = -dist; + struct uint128_extra z; + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(negDist & 63) | a0>>dist; + z.extra = a0<<(negDist & 63) | (extra != 0); + return z; +} + +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64 +| _plus_ the number of bits given in 'dist', which must not be zero. This +| shifted value is at most 64 nonzero bits and is returned in the 'v' field +| of the 'struct uint64_extra' result. The 64-bit 'extra' field of the result +| contains a value formed as follows from the bits that were shifted off: The +| _last_ bit shifted off is the most-significant bit of the 'extra' field, and +| the other 63 bits of the 'extra' field are all zero if and only if _all_but_ +| _the_last_ bits shifted off were all zero. +| (This function makes more sense if 'a' and 'extra' are considered to form +| an unsigned fixed-point number with binary point between 'a' and 'extra'. +| This fixed-point value is shifted right by the number of bits given in +| 'dist', and the integer part of this shifted value is returned in the 'v' +| field of the result. The fractional part of the shifted value is modified +| as described above and returned in the 'extra' field of the result.) +*----------------------------------------------------------------------------*/ +static __inline +struct uint64_extra + softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint32_t dist) +{ + struct uint64_extra z; + if (dist < 64) { + z.v = a>>dist; + z.extra = a<<(-dist & 63); + } else { + z.v = 0; + z.extra = (dist == 64) ? a : (a != 0); + } + z.extra |= (extra != 0); + return z; +} + +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the +| number of bits given in 'dist', which must not be zero. If any nonzero bits +| are shifted off, they are "jammed" into the least-significant bit of the +| shifted value by setting the least-significant bit to 1. This shifted-and- +| jammed value is returned. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than 128, the result will be either 0 or 1, depending on whether the +| original 128 bits are all zeros. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 + softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint32_t dist) +{ + uint8_t u8NegDist; + struct uint128 z; + + if (dist < 64) { + u8NegDist = -dist; + z.v64 = a64>>dist; + z.v0 = + a64<<(u8NegDist & 63) | a0>>dist + | ((uint64_t) (a0<<(u8NegDist & 63)) != 0); + } else { + z.v64 = 0; + z.v0 = + (dist < 127) + ? a64>>(dist & 63) + | (((a64 & (((uint64_t) 1<<(dist & 63)) - 1)) | a0) + != 0) + : ((a64 | a0) != 0); + } + return z; +} + +/*---------------------------------------------------------------------------- +| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right +| by 64 _plus_ the number of bits given in 'dist', which must not be zero. +| This shifted value is at most 128 nonzero bits and is returned in the 'v' +| field of the 'struct uint128_extra' result. The 64-bit 'extra' field of the +| result contains a value formed as follows from the bits that were shifted +| off: The _last_ bit shifted off is the most-significant bit of the 'extra' +| field, and the other 63 bits of the 'extra' field are all zero if and only +| if _all_but_the_last_ bits shifted off were all zero. +| (This function makes more sense if 'a64', 'a0', and 'extra' are considered +| to form an unsigned fixed-point number with binary point between 'a0' and +| 'extra'. This fixed-point value is shifted right by the number of bits +| given in 'dist', and the integer part of this shifted value is returned +| in the 'v' field of the result. The fractional part of the shifted value +| is modified as described above and returned in the 'extra' field of the +| result.) +*----------------------------------------------------------------------------*/ +static __inline +struct uint128_extra + softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint32_t dist) +{ + uint8_t u8NegDist; + struct uint128_extra z; + + u8NegDist = -dist; + if (dist < 64) { + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist; + z.extra = a0<<(u8NegDist & 63); + } else { + z.v.v64 = 0; + if (dist == 64) { + z.v.v0 = a64; + z.extra = a0; + } else { + extra |= a0; + if (dist < 128) { + z.v.v0 = a64>>(dist & 63); + z.extra = a64<<(u8NegDist & 63); + } else { + z.v.v0 = 0; + z.extra = (dist == 128) ? a64 : (a64 != 0); + } + } + } + z.extra |= (extra != 0); + return z; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', which must not be zero. If any nonzero bits are +| shifted off, they are "jammed" into the least-significant bit of the shifted +| value by setting the least-significant bit to 1. This shifted-and-jammed +| value is stored at the location pointed to by 'zPtr'. Each of 'aPtr' and +| 'zPtr' points to an array of four 64-bit elements that concatenate in the +| platform's normal endian order to form a 256-bit integer. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' +| is greater than 256, the stored result will be either 0 or 1, depending on +| whether the original 256 bits are all zeros. +*----------------------------------------------------------------------------*/ +void + softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *zPtr); + +#ifndef softfloat_add128 +/*---------------------------------------------------------------------------- +| Returns the sum of the 128-bit integer formed by concatenating 'a64' and +| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. The +| addition is modulo 2^128, so any carry out is lost. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + struct uint128 z; + z.v0 = a0 + b0; + z.v64 = a64 + b64 + (z.v0 < a0); + return z; +} +#endif + +#ifndef softfloat_add256M +/*---------------------------------------------------------------------------- +| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'. The addition +| is modulo 2^256, so any carry out is lost. The sum is stored at the +| location pointed to by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to +| an array of four 64-bit elements that concatenate in the platform's normal +| endian order to form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr); +#endif + +#ifndef softfloat_sub128 +/*---------------------------------------------------------------------------- +| Returns the difference of the 128-bit integer formed by concatenating 'a64' +| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. +| The subtraction is modulo 2^128, so any borrow out (carry out) is lost. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + struct uint128 z; + z.v0 = a0 - b0; + z.v64 = a64 - b64; + z.v64 -= (a0 < b0); + return z; +} +#endif + +#ifndef softfloat_sub256M +/*---------------------------------------------------------------------------- +| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer +| pointed to by 'aPtr'. The addition is modulo 2^256, so any borrow out +| (carry out) is lost. The difference is stored at the location pointed to +| by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four +| 64-bit elements that concatenate in the platform's normal endian order to +| form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_sub256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr); +#endif + +/*---------------------------------------------------------------------------- +| Returns the 128-bit product of 'a', 'b', and 2^32. +*----------------------------------------------------------------------------*/ +static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) +{ + uint64_t mid; + struct uint128 z; + mid = (uint64_t) (uint32_t) a * b; + z.v0 = mid<<32; + z.v64 = (uint64_t) (uint32_t) (a>>32) * b + (mid>>32); + return z; +} + +/*---------------------------------------------------------------------------- +| Returns the 128-bit product of 'a' and 'b'. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b); + +/*---------------------------------------------------------------------------- +| Returns the product of the 128-bit integer formed by concatenating 'a64' and +| 'a0', multiplied by 'b'. The multiplication is modulo 2^128; any overflow +| bits are discarded. +*----------------------------------------------------------------------------*/ +static __inline +struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) +{ + struct uint128 z; + uint64_t mid; + uint32_t carry; + z.v0 = a0 * b; + mid = (uint64_t) (uint32_t) (a0>>32) * b; + carry = (uint32_t) ((uint32_t) (z.v0>>32) - (uint32_t) mid); + z.v64 = a64 * b + (uint32_t) ((mid + carry)>>32); + return z; +} + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and +| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and +| 'b0'. The 256-bit product is stored at the location pointed to by 'zPtr'. +| Argument 'zPtr' points to an array of four 64-bit elements that concatenate +| in the platform's normal endian order to form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr); +#ifdef __cplusplus +} +#endif + +#endif // _PRIMITIVES_H_ diff --git a/src/cpu/softfloat3e/s_add128.cc b/src/cpu/softfloat3e/s_add128.cc new file mode 100644 index 000000000..8efabb850 --- /dev/null +++ b/src/cpu/softfloat3e/s_add128.cc @@ -0,0 +1,51 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_add128 + +struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + struct uint128 z; + + z.v0 = a0 + b0; + z.v64 = a64 + b64 + (z.v0 < a0); + return z; +} + +#endif + diff --git a/src/cpu/softfloat3e/s_add256M.c b/src/cpu/softfloat3e/s_add256M.c new file mode 100644 index 000000000..32fdf122f --- /dev/null +++ b/src/cpu/softfloat3e/s_add256M.c @@ -0,0 +1,60 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitiveTypes.h" + +#ifndef softfloat_add256M + +void softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr) +{ + unsigned int index; + uint8_t carry; + uint64_t wordA, wordZ; + + index = indexWordLo(4); + carry = 0; + for (;;) { + wordA = aPtr[index]; + wordZ = wordA + bPtr[index] + carry; + zPtr[index] = wordZ; + if (index == indexWordHi(4)) break; + if (wordZ != wordA) carry = (wordZ < wordA); + index += wordIncr; + } +} + +#endif + diff --git a/src/cpu/softfloat3e/s_addMagsExtF80.cc b/src/cpu/softfloat3e/s_addMagsExtF80.cc new file mode 100644 index 000000000..5cc969198 --- /dev/null +++ b/src/cpu/softfloat3e/s_addMagsExtF80.cc @@ -0,0 +1,146 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status) +{ + int32_t expA; + uint64_t sigA; + int32_t expB; + uint64_t sigB; + int32_t expDiff; + uint64_t sigZ, sigZExtra; + struct exp32_sig64 normExpSig; + int32_t expZ; + struct uint64_extra sig64Extra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expExtF80UI64(uiA64); + sigA = uiA0; + expB = expExtF80UI64(uiB64); + sigB = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA << 1) || ((expB == 0x7FFF) && (sigB << 1))) + goto propagateNaN; + if (sigB && ! expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80_twoargs(uiA64, uiA0); + } + if (expB == 0x7FFF) { + if (sigB << 1) goto propagateNaN; + if (sigA && ! expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (! expB && sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + expZ = expB; + sigZ = sigB; + sigZExtra = 0; + goto roundAndPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB == 0) { + if (sigB == 0) { + expZ = expA; + sigZ = sigA; + sigZExtra = 0; + goto roundAndPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + sigZ = sigA + sigB; + sigZExtra = 0; + expZ = expA; + goto shiftRight1; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expDiff < 0) { + expZ = expB; + sig64Extra = softfloat_shiftRightJam64Extra(sigA, 0, -expDiff); + sigA = sig64Extra.v; + sigZExtra = sig64Extra.extra; + } else { + expZ = expA; + sig64Extra = softfloat_shiftRightJam64Extra(sigB, 0, expDiff); + sigB = sig64Extra.v; + sigZExtra = sig64Extra.extra; + } + sigZ = sigA + sigB; + if (sigZ & UINT64_C(0x8000000000000000)) goto roundAndPack; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftRight1: + sig64Extra = softfloat_shortShiftRightJam64Extra(sigZ, sigZExtra, 1); + sigZ = sig64Extra.v | UINT64_C(0x8000000000000000); + sigZExtra = sig64Extra.extra; + ++expZ; + roundAndPack: + return softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); +} diff --git a/src/cpu/softfloat3e/s_addMagsF128.cc b/src/cpu/softfloat3e/s_addMagsF128.cc new file mode 100644 index 000000000..b831796cc --- /dev/null +++ b/src/cpu/softfloat3e/s_addMagsF128.cc @@ -0,0 +1,138 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" + +float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status) +{ + int32_t expA; + struct uint128 sigA; + int32_t expB; + struct uint128 sigB; + int32_t expDiff; + struct uint128 uiZ, sigZ; + int32_t expZ; + uint64_t sigZExtra; + struct uint128_extra sig128Extra; + + expA = expF128UI64(uiA64); + sigA.v64 = fracF128UI64(uiA64); + sigA.v0 = uiA0; + expB = expF128UI64(uiB64); + sigB.v64 = fracF128UI64(uiB64); + sigB.v0 = uiB0; + expDiff = expA - expB; + if (! expDiff) { + if (expA == 0x7FFF) { + if (sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + return uiZ; + } + sigZ = softfloat_add128(sigA.v64, sigA.v0, sigB.v64, sigB.v0); + if (! expA) { + uiZ.v64 = packToF128UI64(signZ, 0, sigZ.v64); + uiZ.v0 = sigZ.v0; + return uiZ; + } + expZ = expA; + sigZ.v64 |= UINT64_C(0x0002000000000000); + sigZExtra = 0; + goto shiftRight1; + } + if (expDiff < 0) { + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN; + uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); + uiZ.v0 = 0; + return uiZ; + } + expZ = expB; + if (expA) { + sigA.v64 |= UINT64_C(0x0001000000000000); + } else { + ++expDiff; + sigZExtra = 0; + if (! expDiff) goto newlyAligned; + } + sig128Extra = + softfloat_shiftRightJam128Extra(sigA.v64, sigA.v0, 0, -expDiff); + sigA = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } else { + if (expA == 0x7FFF) { + if (sigA.v64 | sigA.v0) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + return uiZ; + } + expZ = expA; + if (expB) { + sigB.v64 |= UINT64_C(0x0001000000000000); + } else { + --expDiff; + sigZExtra = 0; + if (! expDiff) goto newlyAligned; + } + sig128Extra = softfloat_shiftRightJam128Extra(sigB.v64, sigB.v0, 0, expDiff); + sigB = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } + newlyAligned: + sigZ = + softfloat_add128( + sigA.v64 | UINT64_C(0x0001000000000000), + sigA.v0, + sigB.v64, + sigB.v0 + ); + --expZ; + if (sigZ.v64 < UINT64_C(0x0002000000000000)) goto roundAndPack; + ++expZ; + shiftRight1: + sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1); + sigZ = sig128Extra.v; + sigZExtra = sig128Extra.extra; + roundAndPack: + return + softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status); + propagateNaN: + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); + return uiZ; +} diff --git a/src/cpu/softfloat3e/s_addMagsF16.c b/src/cpu/softfloat3e/s_addMagsF16.c new file mode 100644 index 000000000..022f254a8 --- /dev/null +++ b/src/cpu/softfloat3e/s_addMagsF16.c @@ -0,0 +1,192 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16 softfloat_addMagsF16(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status) +{ + int8_t expA; + uint16_t sigA; + int8_t expB; + uint16_t sigB; + int8_t expDiff; + uint16_t uiZ; + bool signZ; + int8_t expZ; + uint16_t sigZ; + uint16_t sigX, sigY; + int8_t shiftDist; + uint32_t sig32Z; + int8_t roundingMode; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF16UI(uiA); + sigA = fracF16UI(uiA); + expB = expF16UI(uiB); + sigB = fracF16UI(uiB); + signZ = signF16UI(uiA); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + uiA = packToF16UI(signZ, 0, 0); + } + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (! expA) { + uiZ = uiA + sigB; + if (sigA | sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + bool isTiny = (expF16UI(uiZ) == 0); + if (isTiny) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF16UI(signZ, 0, 0); + } + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + } + return uiZ; + } + if (expA == 0x1F) { + if (sigA | sigB) goto propagateNaN; + return uiA; + } + expZ = expA; + sigZ = 0x0800 + sigA + sigB; + if (! (sigZ & 1) && (expZ < 0x1E)) { + sigZ >>= 1; + goto pack; + } + sigZ <<= 3; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expDiff < 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + if (expB == 0x1F) { + if (sigB) goto propagateNaN; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToF16UI(signZ, 0x1F, 0); + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + if (expDiff <= -13) { + uiZ = packToF16UI(signZ, expB, sigB); + if (expA | sigA) goto addEpsilon; + return uiZ; + } + expZ = expB; + sigX = sigB | 0x0400; + sigY = sigA + (expA ? 0x0400 : sigA); + shiftDist = 19 + expDiff; + } else { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + uiZ = uiA; + if (expA == 0x1F) { + if (sigA) goto propagateNaN; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + return uiZ; + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + if (13 <= expDiff) { + if (expB | sigB) goto addEpsilon; + return uiZ; + } + expZ = expA; + sigX = sigA | 0x0400; + sigY = sigB + (expB ? 0x0400 : sigB); + shiftDist = 19 - expDiff; + } + sig32Z = ((uint32_t) sigX<<19) + ((uint32_t) sigY<>16; + if (sig32Z & 0xFFFF) { + sigZ |= 1; + } else { + if (! (sigZ & 0xF) && (expZ < 0x1E)) { + sigZ >>= 4; + goto pack; + } + } + } + return softfloat_roundPackToF16(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF16UI(uiA, uiB, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + addEpsilon: + roundingMode = softfloat_getRoundingMode(status); + if (roundingMode != softfloat_round_near_even) { + if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) { + ++uiZ; + if ((uint16_t) (uiZ<<1) == 0xF800) { + softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact); + } + } + } + softfloat_raiseFlags(status, softfloat_flag_inexact); + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + pack: + return packToF16UI(signZ, expZ, sigZ); +} diff --git a/src/cpu/softfloat3e/s_addMagsF32.c b/src/cpu/softfloat3e/s_addMagsF32.c new file mode 100644 index 000000000..df902348a --- /dev/null +++ b/src/cpu/softfloat3e/s_addMagsF32.c @@ -0,0 +1,147 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" + +float32 softfloat_addMagsF32(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status) +{ + int16_t expA; + uint32_t sigA; + int16_t expB; + uint32_t sigB; + int16_t expDiff; + uint32_t uiZ; + bool signZ; + int16_t expZ; + uint32_t sigZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF32UI(uiA); + sigA = fracF32UI(uiA); + expB = expF32UI(uiB); + sigB = fracF32UI(uiB); + signZ = signF32UI(uiA); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + uiA = packToF32UI(signZ, 0, 0); + } + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (! expA) { + uiZ = uiA + sigB; + if (sigA | sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + bool isTiny = (expF32UI(uiZ) == 0); + if (isTiny) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF32UI(signZ, 0, 0); + } + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + } + return uiZ; + } + if (expA == 0xFF) { + if (sigA | sigB) goto propagateNaN; + return uiA; + } + expZ = expA; + sigZ = 0x01000000 + sigA + sigB; + if (! (sigZ & 1) && (expZ < 0xFE)) { + return packToF32UI(signZ, expZ, sigZ>>1); + } + sigZ <<= 6; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + signZ = signF32UI(uiA); + sigA <<= 6; + sigB <<= 6; + if (expDiff < 0) { + if (expB == 0xFF) { + if (sigB) goto propagateNaN; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToF32UI(signZ, 0xFF, 0); + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + expZ = expB; + sigA += expA ? 0x20000000 : sigA; + sigA = softfloat_shiftRightJam32(sigA, -expDiff); + } else { + if (expA == 0xFF) { + if (sigA) goto propagateNaN; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + return uiA; + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + expZ = expA; + sigB += expB ? 0x20000000 : sigB; + sigB = softfloat_shiftRightJam32(sigB, expDiff); + } + sigZ = 0x20000000 + sigA + sigB; + if (sigZ < 0x40000000) { + --expZ; + sigZ <<= 1; + } + } + return softfloat_roundPackToF32(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF32UI(uiA, uiB, status); +} diff --git a/src/cpu/softfloat3e/s_addMagsF64.c b/src/cpu/softfloat3e/s_addMagsF64.c new file mode 100644 index 000000000..a315860f6 --- /dev/null +++ b/src/cpu/softfloat3e/s_addMagsF64.c @@ -0,0 +1,149 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" + +float64 softfloat_addMagsF64(uint64_t uiA, uint64_t uiB, bool signZ, struct softfloat_status_t *status) +{ + int16_t expA; + uint64_t sigA; + int16_t expB; + uint64_t sigB; + int16_t expDiff; + uint64_t uiZ; + int16_t expZ; + uint64_t sigZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF64UI(uiA); + sigA = fracF64UI(uiA); + expB = expF64UI(uiB); + sigB = fracF64UI(uiB); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) { + sigA = 0; + uiA = packToF64UI(signZ, 0, 0); + } + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (! expA) { + uiZ = uiA + sigB; + if (sigA | sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + bool isTiny = (expF64UI(uiZ) == 0); + if (isTiny) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF64UI(signZ, 0, 0); + } + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + } + return uiZ; + } + if (expA == 0x7FF) { + if (sigA | sigB) goto propagateNaN; + return uiA; + } + expZ = expA; + sigZ = UINT64_C(0x0020000000000000) + sigA + sigB; + sigZ <<= 9; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigA <<= 9; + sigB <<= 9; + if (expDiff < 0) { + if (expB == 0x7FF) { + if (sigB) goto propagateNaN; + if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToF64UI(signZ, 0x7FF, 0); + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + expZ = expB; + if (expA) { + sigA += UINT64_C(0x2000000000000000); + } else { + sigA <<= 1; + } + sigA = softfloat_shiftRightJam64(sigA, -expDiff); + } else { + if (expA == 0x7FF) { + if (sigA) goto propagateNaN; + if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal); + return uiA; + } + + if ((!expA && sigA) || (!expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); + + expZ = expA; + if (expB) { + sigB += UINT64_C(0x2000000000000000); + } else { + sigB <<= 1; + } + sigB = softfloat_shiftRightJam64(sigB, expDiff); + } + sigZ = UINT64_C(0x2000000000000000) + sigA + sigB; + if (sigZ < UINT64_C(0x4000000000000000)) { + --expZ; + sigZ <<= 1; + } + } + return softfloat_roundPackToF64(signZ, expZ, sigZ, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF64UI(uiA, uiB, status); +} diff --git a/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c new file mode 100644 index 000000000..776c146ef --- /dev/null +++ b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c @@ -0,0 +1,63 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" + +extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; + +uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a) +{ + int index; + uint16_t eps, r0; + uint32_t ESqrR0; + uint32_t sigma0; + uint32_t r; + uint32_t sqrSigma0; + + index = (a>>27 & 0xE) + oddExpA; + eps = (uint16_t) (a>>12); + r0 = softfloat_approxRecipSqrt_1k0s[index] - ((softfloat_approxRecipSqrt_1k1s[index] * (uint32_t) eps) >>20); + ESqrR0 = (uint32_t) r0 * r0; + if (! oddExpA) ESqrR0 <<= 1; + sigma0 = ~(uint32_t) (((uint32_t) ESqrR0 * (uint64_t) a)>>23); + r = ((uint32_t) r0<<16) + ((r0 * (uint64_t) sigma0)>>25); + sqrSigma0 = ((uint64_t) sigma0 * sigma0)>>32; + r += ((uint32_t) ((r>>1) + (r>>3) - ((uint32_t) r0<<14)) * (uint64_t) sqrSigma0) >>48; + if (! (r & 0x80000000)) r = 0x80000000; + return r; +} + diff --git a/src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c b/src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c new file mode 100644 index 000000000..56965c541 --- /dev/null +++ b/src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" + +const uint16_t softfloat_approxRecipSqrt_1k0s[16] = { + 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, + 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 +}; +const uint16_t softfloat_approxRecipSqrt_1k1s[16] = { + 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, + 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD +}; diff --git a/src/cpu/softfloat3e/s_approxRecip_1Ks.c b/src/cpu/softfloat3e/s_approxRecip_1Ks.c new file mode 100644 index 000000000..aadcd235c --- /dev/null +++ b/src/cpu/softfloat3e/s_approxRecip_1Ks.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" + +const uint16_t softfloat_approxRecip_1k0s[16] = { + 0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201, + 0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417 +}; +const uint16_t softfloat_approxRecip_1k1s[16] = { + 0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA, + 0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211 +}; diff --git a/src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc b/src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc new file mode 100644 index 000000000..7afca6270 --- /dev/null +++ b/src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc @@ -0,0 +1,69 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into an 80-bit extended +| floating-point NaN, and returns the bit pattern of this value as an unsigned +| integer. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN *aPtr) +{ + struct uint128 uiZ; + + uiZ.v64 = (uint16_t) aPtr->sign<<15 | 0x7FFF; + uiZ.v0 = UINT64_C(0xC000000000000000) | aPtr->v64>>1; + return uiZ; +} + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' +| has the bit pattern of an 80-bit extended floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_extF80UIToCommonNaN(uint16_t uiA64, uint64_t uiA0, struct commonNaN *zPtr, struct softfloat_status_t *status) +{ + if (softfloat_isSigNaNExtF80UI(uiA64, uiA0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + } + zPtr->sign = uiA64>>15; + zPtr->v64 = uiA0<<1; + zPtr->v0 = 0; +} diff --git a/src/cpu/softfloat3e/s_commonNaNToF128UI.cc b/src/cpu/softfloat3e/s_commonNaNToF128UI.cc new file mode 100644 index 000000000..a0bb93dd3 --- /dev/null +++ b/src/cpu/softfloat3e/s_commonNaNToF128UI.cc @@ -0,0 +1,72 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN *aPtr) +{ + struct uint128 uiZ; + + uiZ = softfloat_shortShiftRight128(aPtr->v64, aPtr->v0, 16); + uiZ.v64 |= (uint64_t) aPtr->sign<<63 | UINT64_C(0x7FFF800000000000); + return uiZ; +} + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' +| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to +| the common NaN form, and stores the resulting common NaN at the location +| pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception +| is raised. +*----------------------------------------------------------------------------*/ +void + softfloat_f128UIToCommonNaN(uint64_t uiA64, uint64_t uiA0, struct commonNaN *zPtr, struct softfloat_status_t *status) +{ + struct uint128 NaNSig; + + if (softfloat_isSigNaNF128UI(uiA64, uiA0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + } + NaNSig = softfloat_shortShiftLeft128(uiA64, uiA0, 16); + zPtr->sign = uiA64>>63; + zPtr->v64 = NaNSig.v64; + zPtr->v0 = NaNSig.v0; +} diff --git a/src/cpu/softfloat3e/s_commonNaNToF16UI.c b/src/cpu/softfloat3e/s_commonNaNToF16UI.c new file mode 100644 index 000000000..20da6a04f --- /dev/null +++ b/src/cpu/softfloat3e/s_commonNaNToF16UI.c @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint16_t softfloat_commonNaNToF16UI(const struct commonNaN *aPtr) +{ + return (uint16_t) aPtr->sign<<15 | 0x7E00 | aPtr->v64>>54; +} + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f16UIToCommonNaN(uint16_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status) +{ + if (softfloat_isSigNaNF16UI(uiA)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + } + zPtr->sign = uiA>>15; + zPtr->v64 = (uint64_t) uiA<<54; + zPtr->v0 = 0; +} diff --git a/src/cpu/softfloat3e/s_commonNaNToF32UI.c b/src/cpu/softfloat3e/s_commonNaNToF32UI.c new file mode 100644 index 000000000..866ebb8f8 --- /dev/null +++ b/src/cpu/softfloat3e/s_commonNaNToF32UI.c @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint32_t softfloat_commonNaNToF32UI(const struct commonNaN *aPtr) +{ + return (uint32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41; +} + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f32UIToCommonNaN(uint32_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status) +{ + if (softfloat_isSigNaNF32UI(uiA)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + } + zPtr->sign = uiA>>31; + zPtr->v64 = (uint64_t) uiA<<41; + zPtr->v0 = 0; +} diff --git a/src/cpu/softfloat3e/s_commonNaNToF64UI.c b/src/cpu/softfloat3e/s_commonNaNToF64UI.c new file mode 100644 index 000000000..8e73f68f4 --- /dev/null +++ b/src/cpu/softfloat3e/s_commonNaNToF64UI.c @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint64_t softfloat_commonNaNToF64UI(const struct commonNaN *aPtr) +{ + return (uint64_t) aPtr->sign<<63 | UINT64_C(0x7FF8000000000000) | aPtr->v64>>12; +} + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f64UIToCommonNaN(uint64_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status) +{ + if (softfloat_isSigNaNF64UI(uiA)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + } + zPtr->sign = uiA>>63; + zPtr->v64 = uiA<<12; + zPtr->v0 = 0; +} diff --git a/src/cpu/softfloat3e/s_countLeadingZeros16.c b/src/cpu/softfloat3e/s_countLeadingZeros16.c new file mode 100644 index 000000000..ffbb9c943 --- /dev/null +++ b/src/cpu/softfloat3e/s_countLeadingZeros16.c @@ -0,0 +1,56 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_countLeadingZeros16 + +#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 +#include "primitives.h" + +uint8_t softfloat_countLeadingZeros16(uint16_t a) +{ + uint8_t count; + + count = 8; + if (0x100 <= a) { + count = 0; + a >>= 8; + } + count += softfloat_countLeadingZeros8[a]; + return count; +} + +#endif diff --git a/src/cpu/softfloat3e/s_countLeadingZeros32.c b/src/cpu/softfloat3e/s_countLeadingZeros32.c new file mode 100644 index 000000000..3f594137f --- /dev/null +++ b/src/cpu/softfloat3e/s_countLeadingZeros32.c @@ -0,0 +1,61 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_countLeadingZeros32 + +#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 +#include "primitives.h" + +uint8_t softfloat_countLeadingZeros32(uint32_t a) +{ + uint8_t count; + + count = 0; + if (a < 0x10000) { + count = 16; + a <<= 16; + } + if (a < 0x1000000) { + count += 8; + a <<= 8; + } + count += softfloat_countLeadingZeros8[a>>24]; + return count; +} + +#endif diff --git a/src/cpu/softfloat3e/s_countLeadingZeros64.c b/src/cpu/softfloat3e/s_countLeadingZeros64.c new file mode 100644 index 000000000..c96c4ec8c --- /dev/null +++ b/src/cpu/softfloat3e/s_countLeadingZeros64.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_countLeadingZeros64 + +#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 +#include "primitives.h" + +uint8_t softfloat_countLeadingZeros64(uint64_t a) +{ + uint8_t count; + uint32_t a32; + + count = 0; + a32 = a>>32; + if (! a32) { + count = 32; + a32 = a; + } + /*------------------------------------------------------------------------ + | From here, result is current count + count leading zeros of `a32'. + *------------------------------------------------------------------------*/ + if (a32 < 0x10000) { + count += 16; + a32 <<= 16; + } + if (a32 < 0x1000000) { + count += 8; + a32 <<= 8; + } + count += softfloat_countLeadingZeros8[a32>>24]; + return count; +} + +#endif diff --git a/src/cpu/softfloat3e/s_countLeadingZeros8.c b/src/cpu/softfloat3e/s_countLeadingZeros8.c new file mode 100644 index 000000000..873ab81ef --- /dev/null +++ b/src/cpu/softfloat3e/s_countLeadingZeros8.c @@ -0,0 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitives.h" + +const uint_least8_t softfloat_countLeadingZeros8[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + diff --git a/src/cpu/softfloat3e/s_eq128.c b/src/cpu/softfloat3e/s_eq128.c new file mode 100644 index 000000000..45495dd92 --- /dev/null +++ b/src/cpu/softfloat3e/s_eq128.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include + +#ifndef softfloat_eq128 + +bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 == b64) && (a0 == b0); +} + +#endif diff --git a/src/cpu/softfloat3e/s_le128.c b/src/cpu/softfloat3e/s_le128.c new file mode 100644 index 000000000..d299b5e92 --- /dev/null +++ b/src/cpu/softfloat3e/s_le128.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include + +#ifndef softfloat_le128 + +bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); +} + +#endif diff --git a/src/cpu/softfloat3e/s_lt128.c b/src/cpu/softfloat3e/s_lt128.c new file mode 100644 index 000000000..225c23356 --- /dev/null +++ b/src/cpu/softfloat3e/s_lt128.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include + +#ifndef softfloat_lt128 + +bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + return (a64 < b64) || ((a64 == b64) && (a0 < b0)); +} + +#endif diff --git a/src/cpu/softfloat3e/s_mul128By32.cc b/src/cpu/softfloat3e/s_mul128By32.cc new file mode 100644 index 000000000..920ad5733 --- /dev/null +++ b/src/cpu/softfloat3e/s_mul128By32.cc @@ -0,0 +1,54 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_mul128By32 + +struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) +{ + struct uint128 z; + uint64_t mid; + uint32_t carry; + + z.v0 = a0 * b; + mid = (uint64_t) (uint32_t) (a0>>32) * b; + carry = (uint32_t) ((uint32_t) (z.v0>>32) - (uint32_t) mid); + z.v64 = a64 * b + (uint32_t) ((mid + carry)>>32); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_mul128To256M.cc b/src/cpu/softfloat3e/s_mul128To256M.cc new file mode 100644 index 000000000..04b25a575 --- /dev/null +++ b/src/cpu/softfloat3e/s_mul128To256M.cc @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#include "primitives.h" +#include "primitiveTypes.h" + +void softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr) +{ + struct uint128 p0, p64, p128; + uint64_t z64, z128, z192; + + p0 = softfloat_mul64To128(a0, b0); + zPtr[indexWord(4, 0)] = p0.v0; + p64 = softfloat_mul64To128(a64, b0); + z64 = p64.v0 + p0.v64; + z128 = p64.v64 + (z64 < p64.v0); + p128 = softfloat_mul64To128(a64, b64); + z128 += p128.v0; + z192 = p128.v64 + (z128 < p128.v0); + p64 = softfloat_mul64To128(a0, b64); + z64 += p64.v0; + zPtr[indexWord(4, 1)] = z64; + p64.v64 += (z64 < p64.v0); + z128 += p64.v64; + zPtr[indexWord(4, 2)] = z128; + zPtr[indexWord(4, 3)] = z192 + (z128 < p64.v64); +} + diff --git a/src/cpu/softfloat3e/s_mul64ByShifted32To128.cc b/src/cpu/softfloat3e/s_mul64ByShifted32To128.cc new file mode 100644 index 000000000..90938ac79 --- /dev/null +++ b/src/cpu/softfloat3e/s_mul64ByShifted32To128.cc @@ -0,0 +1,52 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_mul64ByShifted32To128 + +struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) +{ + uint64_t mid; + struct uint128 z; + + mid = (uint64_t) (uint32_t) a * b; + z.v0 = mid<<32; + z.v64 = (uint64_t) (uint32_t) (a>>32) * b + (mid>>32); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_mul64To128.cc b/src/cpu/softfloat3e/s_mul64To128.cc new file mode 100644 index 000000000..d1ab9296a --- /dev/null +++ b/src/cpu/softfloat3e/s_mul64To128.cc @@ -0,0 +1,63 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" +#include "primitives.h" + +#ifndef softfloat_mul64To128 + +struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b) +{ + uint32_t a32, a0, b32, b0; + struct uint128 z; + uint64_t mid1, mid; + + a32 = a>>32; + a0 = a; + b32 = b>>32; + b0 = b; + z.v0 = (uint64_t) a0 * b0; + mid1 = (uint64_t) a32 * b0; + mid = mid1 + (uint64_t) a0 * b32; + z.v64 = (uint64_t) a32 * b32; + z.v64 += (uint64_t) (mid < mid1)<<32 | mid>>32; + mid <<= 32; + z.v0 += mid; + z.v64 += (z.v0 < mid); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_normRoundPackToExtF80.cc b/src/cpu/softfloat3e/s_normRoundPackToExtF80.cc new file mode 100644 index 000000000..753f76184 --- /dev/null +++ b/src/cpu/softfloat3e/s_normRoundPackToExtF80.cc @@ -0,0 +1,62 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" + +extFloat80_t softfloat_normRoundPackToExtF80(bool sign, int32_t exp, + uint64_t sig, + uint64_t sigExtra, + uint8_t roundingPrecision, + struct softfloat_status_t *status) +{ + int8_t shiftDist; + struct uint128 sig128; + + if (! sig) { + exp -= 64; + sig = sigExtra; + sigExtra = 0; + } + shiftDist = softfloat_countLeadingZeros64(sig); + exp -= shiftDist; + if (shiftDist) { + sig128 = softfloat_shortShiftLeft128(sig, sigExtra, shiftDist); + sig = sig128.v64; + sigExtra = sig128.v0; + } + return softfloat_roundPackToExtF80(sign, exp, sig, sigExtra, roundingPrecision, status); +} diff --git a/src/cpu/softfloat3e/s_normRoundPackToF128.cc b/src/cpu/softfloat3e/s_normRoundPackToF128.cc new file mode 100644 index 000000000..14db1ce9b --- /dev/null +++ b/src/cpu/softfloat3e/s_normRoundPackToF128.cc @@ -0,0 +1,75 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" + +float128_t softfloat_normRoundPackToF128(bool sign, int32_t exp, uint64_t sig64, uint64_t sig0, struct softfloat_status_t *status) +{ + int8_t shiftDist; + struct uint128 sig128; + uint64_t sigExtra; + struct uint128_extra sig128Extra; + float128_t z; + + if (! sig64) { + exp -= 64; + sig64 = sig0; + sig0 = 0; + } + shiftDist = softfloat_countLeadingZeros64(sig64) - 15; + exp -= shiftDist; + if (0 <= shiftDist) { + if (shiftDist) { + sig128 = softfloat_shortShiftLeft128(sig64, sig0, shiftDist); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + if ((uint32_t) exp < 0x7FFD) { + z.v64 = packToF128UI64(sign, sig64 | sig0 ? exp : 0, sig64); + z.v0 = sig0; + return z; + } + sigExtra = 0; + } else { + sig128Extra = softfloat_shortShiftRightJam128Extra(sig64, sig0, 0, -shiftDist); + sig64 = sig128Extra.v.v64; + sig0 = sig128Extra.v.v0; + sigExtra = sig128Extra.extra; + } + return softfloat_roundPackToF128(sign, exp, sig64, sig0, sigExtra, status); +} diff --git a/src/cpu/softfloat3e/s_normRoundPackToF16.c b/src/cpu/softfloat3e/s_normRoundPackToF16.c new file mode 100644 index 000000000..36ae237fa --- /dev/null +++ b/src/cpu/softfloat3e/s_normRoundPackToF16.c @@ -0,0 +1,49 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" + +float16 softfloat_normRoundPackToF16(bool sign, int16_t exp, uint16_t sig, struct softfloat_status_t *status) +{ + int8_t shiftDist = softfloat_countLeadingZeros16(sig) - 1; + exp -= shiftDist; + if ((4 <= shiftDist) && ((unsigned int) exp < 0x1D)) { + return packToF16UI(sign, sig ? exp : 0, sig<<(shiftDist - 4)); + } else { + return softfloat_roundPackToF16(sign, exp, sig< +#include "internals.h" +#include "primitives.h" + +float32 softfloat_normRoundPackToF32(bool sign, int16_t exp, uint32_t sig, struct softfloat_status_t *status) +{ + int8_t shiftDist = softfloat_countLeadingZeros32(sig) - 1; + exp -= shiftDist; + if ((7 <= shiftDist) && ((unsigned int) exp < 0xFD)) { + return packToF32UI(sign, sig ? exp : 0, sig<<(shiftDist - 7)); + } else { + return softfloat_roundPackToF32(sign, exp, sig< +#include "internals.h" +#include "primitives.h" + +float64 softfloat_normRoundPackToF64(bool sign, int16_t exp, uint64_t sig, struct softfloat_status_t *status) +{ + int8_t shiftDist = softfloat_countLeadingZeros64(sig) - 1; + exp -= shiftDist; + if ((10 <= shiftDist) && ((unsigned int) exp < 0x7FD)) { + return packToF64UI(sign, sig ? exp : 0, sig<<(shiftDist - 10)); + } else { + return softfloat_roundPackToF64(sign, exp, sig< +#include "internals.h" +#include "primitives.h" + +struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint64_t sig) +{ + int8_t shiftDist; + struct exp32_sig64 z; + + shiftDist = softfloat_countLeadingZeros64(sig); + z.exp = -shiftDist; + z.sig = sig< +#include "internals.h" +#include "primitives.h" + +struct exp32_sig128 softfloat_normSubnormalF128Sig(uint64_t sig64, uint64_t sig0) +{ + int8_t shiftDist; + struct exp32_sig128 z; + + if (! sig64) { + shiftDist = softfloat_countLeadingZeros64(sig0) - 15; + z.exp = -63 - shiftDist; + if (shiftDist < 0) { + z.sig.v64 = sig0>>-shiftDist; + z.sig.v0 = sig0<<(shiftDist & 63); + } else { + z.sig.v64 = sig0< +#include "internals.h" +#include "primitives.h" + +struct exp8_sig16 softfloat_normSubnormalF16Sig(uint16_t sig) +{ + int8_t shiftDist; + struct exp8_sig16 z; + + shiftDist = softfloat_countLeadingZeros16(sig) - 5; + z.exp = 1 - shiftDist; + z.sig = sig< +#include "internals.h" +#include "primitives.h" + +struct exp16_sig32 softfloat_normSubnormalF32Sig(uint32_t sig) +{ + int8_t shiftDist; + struct exp16_sig32 z; + + shiftDist = softfloat_countLeadingZeros32(sig) - 8; + z.exp = 1 - shiftDist; + z.sig = sig< +#include "internals.h" +#include "primitives.h" + +struct exp16_sig64 softfloat_normSubnormalF64Sig(uint64_t sig) +{ + int8_t shiftDist; + struct exp16_sig64 z; + + shiftDist = softfloat_countLeadingZeros64(sig) - 11; + z.exp = 1 - shiftDist; + z.sig = sig< +#include "internals.h" +#include "softfloat.h" + +extFloat80_t packToExtF80_twoargs(uint16_t signExp, uint64_t sig) +{ + extFloat80_t z; + z.signExp = signExp; + z.signif = sig; + return z; +} + +extFloat80_t packToExtF80(bool sign, uint16_t exp, uint64_t sig) +{ + extFloat80_t z; + z.signExp = packToExtF80UI64(sign, exp); + z.signif = sig; + return z; +} diff --git a/src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc b/src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc new file mode 100644 index 000000000..77d699bb0 --- /dev/null +++ b/src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc @@ -0,0 +1,96 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating 'uiA64' and +| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting +| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another +| 80-bit extended floating-point value, and assuming at least on of these +| floating-point values is a NaN, returns the bit pattern of the combined NaN +| result. If either original floating-point value is a signaling NaN, the +| invalid exception is raised. +*----------------------------------------------------------------------------*/ +extFloat80_t +softfloat_propagateNaNExtF80UI(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, struct softfloat_status_t *status) +{ + bool isSigNaNA, isSigNaNB; + uint64_t uiNonsigA0, uiNonsigB0; + uint16_t uiMagA64, uiMagB64; + extFloat80_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + isSigNaNA = softfloat_isSigNaNExtF80UI(uiA64, uiA0); + isSigNaNB = softfloat_isSigNaNExtF80UI(uiB64, uiB0); + /*------------------------------------------------------------------------ + | Make NaNs non-signaling. + *------------------------------------------------------------------------*/ + uiNonsigA0 = uiA0 | UINT64_C(0xC000000000000000); + uiNonsigB0 = uiB0 | UINT64_C(0xC000000000000000); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (isSigNaNA | isSigNaNB) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + if (isSigNaNA) { + if (isSigNaNB) goto returnLargerMag; + if (isNaNExtF80UI(uiB64, uiB0)) goto returnB; + goto returnA; + } else { + if (isNaNExtF80UI(uiA64, uiA0)) goto returnA; + goto returnB; + } + } + returnLargerMag: + uiMagA64 = uiA64 & 0x7FFF; + uiMagB64 = uiB64 & 0x7FFF; + if (uiMagA64 < uiMagB64) goto returnB; + if (uiMagB64 < uiMagA64) goto returnA; + if (uiA0 < uiB0) goto returnB; + if (uiB0 < uiA0) goto returnA; + if (uiA64 < uiB64) goto returnA; + returnB: + z.signExp = uiB64; + z.signif = uiNonsigB0; + return z; + returnA: + z.signExp = uiA64; + z.signif = uiNonsigA0; + return z; +} diff --git a/src/cpu/softfloat3e/s_propagateNaNF128UI.cc b/src/cpu/softfloat3e/s_propagateNaNF128UI.cc new file mode 100644 index 000000000..83a7c2413 --- /dev/null +++ b/src/cpu/softfloat3e/s_propagateNaNF128UI.cc @@ -0,0 +1,78 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating `uiA64' and +| `uiA0' as a 128-bit floating-point value, and likewise interpreting the +| unsigned integer formed from concatenating `uiB64' and `uiB0' as another +| 128-bit floating-point value, and assuming at least on of these floating- +| point values is a NaN, returns the bit pattern of the combined NaN result. +| If either original floating-point value is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_propagateNaNF128UI( + uint64_t uiA64, + uint64_t uiA0, + uint64_t uiB64, + uint64_t uiB0, + struct softfloat_status_t *status +) +{ + bool isSigNaNA; + struct uint128 uiZ; + + isSigNaNA = softfloat_isSigNaNF128UI(uiA64, uiA0); + if (isSigNaNA || softfloat_isSigNaNF128UI(uiB64, uiB0)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + if (isSigNaNA) goto returnNonsigA; + } + if (isNaNF128UI(uiA64, uiA0)) { + returnNonsigA: + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + } else { + uiZ.v64 = uiB64; + uiZ.v0 = uiB0; + } + uiZ.v64 |= UINT64_C(0x0000800000000000); + return uiZ; +} diff --git a/src/cpu/softfloat3e/s_propagateNaNF16UI.c b/src/cpu/softfloat3e/s_propagateNaNF16UI.c new file mode 100644 index 000000000..0a92c57f0 --- /dev/null +++ b/src/cpu/softfloat3e/s_propagateNaNF16UI.c @@ -0,0 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint16_t softfloat_propagateNaNF16UI(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status) +{ + bool isSigNaNA; + + isSigNaNA = softfloat_isSigNaNF16UI(uiA); + if (isSigNaNA || softfloat_isSigNaNF16UI(uiB)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + if (isSigNaNA) return uiA | 0x0200; + } + return (isNaNF16UI(uiA) ? uiA : uiB) | 0x0200; +} diff --git a/src/cpu/softfloat3e/s_propagateNaNF32UI.c b/src/cpu/softfloat3e/s_propagateNaNF32UI.c new file mode 100644 index 000000000..d5db3d24e --- /dev/null +++ b/src/cpu/softfloat3e/s_propagateNaNF32UI.c @@ -0,0 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint32_t softfloat_propagateNaNF32UI(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status) +{ + bool isSigNaNA; + + isSigNaNA = softfloat_isSigNaNF32UI(uiA); + if (isSigNaNA || softfloat_isSigNaNF32UI(uiB)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + if (isSigNaNA) return uiA | 0x00400000; + } + return (isNaNF32UI(uiA) ? uiA : uiB) | 0x00400000; +} diff --git a/src/cpu/softfloat3e/s_propagateNaNF64UI.c b/src/cpu/softfloat3e/s_propagateNaNF64UI.c new file mode 100644 index 000000000..3bb2ead86 --- /dev/null +++ b/src/cpu/softfloat3e/s_propagateNaNF64UI.c @@ -0,0 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint64_t softfloat_propagateNaNF64UI(uint64_t uiA, uint64_t uiB, struct softfloat_status_t *status) +{ + bool isSigNaNA; + + isSigNaNA = softfloat_isSigNaNF64UI(uiA); + if (isSigNaNA || softfloat_isSigNaNF64UI(uiB)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); + if (isSigNaNA) return uiA | UINT64_C(0x0008000000000000); + } + return (isNaNF64UI(uiA) ? uiA : uiB) | UINT64_C(0x0008000000000000); +} diff --git a/src/cpu/softfloat3e/s_roundPackToExtF80.cc b/src/cpu/softfloat3e/s_roundPackToExtF80.cc new file mode 100644 index 000000000..ec63283e1 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundPackToExtF80.cc @@ -0,0 +1,224 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +extFloat80_t + softfloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status) +{ + uint8_t roundingMode; + bool roundNearEven; + uint64_t roundIncrement, roundMask, roundBits; + bool isTiny, doIncrement; + struct uint64_extra sig64Extra; + uint64_t sigExact; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_getRoundingMode(status); + roundNearEven = (roundingMode == softfloat_round_near_even); + if (roundingPrecision == 80) goto precision80; + if (roundingPrecision == 64) { + roundIncrement = UINT64_C(0x0000000000000400); + roundMask = UINT64_C(0x00000000000007FF); + } else if (roundingPrecision == 32) { + roundIncrement = UINT64_C(0x0000008000000000); + roundMask = UINT64_C(0x000000FFFFFFFFFF); + } else { + goto precision80; + } + sig |= (sigExtra != 0); + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + roundIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) ? roundMask : 0; + } + roundBits = sig & roundMask; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x7FFD <= (uint32_t) (exp - 1)) { + if (exp <= 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < 0) || (sig <= (uint64_t) (sig + roundIncrement)); + if (isTiny && sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + exp += 0x6000; + } + else { + sig = softfloat_shiftRightJam64(sig, 1 - exp); + roundBits = sig & roundMask; + sigExact = sig; + sig += roundIncrement; + exp = ((sig & UINT64_C(0x8000000000000000)) != 0); + roundIncrement = roundMask + 1; + if (roundNearEven && (roundBits<<1 == roundIncrement)) { + roundMask |= roundIncrement; + } + sig &= ~roundMask; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > sigExact) softfloat_setRoundingUp(status); + if (isTiny) + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + return packToExtF80(sign, exp, sig); + } + } + if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) { + if (! softfloat_isMaskedException(status, softfloat_flag_overflow)) { + softfloat_raiseFlags(status, softfloat_flag_overflow); + exp -= 0x6000; + } + if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) { + goto overflow; + } + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigExact = sig; + sig = (uint64_t) (sig + roundIncrement); + if (sig < roundIncrement) { + ++exp; + sig = UINT64_C(0x8000000000000000); + sigExact >>= 1; // must scale also, or else later tests will fail + } + roundIncrement = roundMask + 1; + if (roundNearEven && (roundBits<<1 == roundIncrement)) { + roundMask |= roundIncrement; + } + sig &= ~roundMask; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > sigExact) softfloat_setRoundingUp(status); + } + return packToExtF80(sign, exp, sig); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + precision80: + doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra); + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + doIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) && sigExtra; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x7FFD <= (uint32_t) (exp - 1)) { + if (exp <= 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < 0) || ! doIncrement || (sig < UINT64_C(0xFFFFFFFFFFFFFFFF)); + if (isTiny && sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + exp += 0x6000; + } + else { + sig64Extra = softfloat_shiftRightJam64Extra(sig, sigExtra, 1 - exp); + exp = 0; + sig = sig64Extra.v; + sigExtra = sig64Extra.extra; + if (sigExtra) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (isTiny) + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra); + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + doIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) && sigExtra; + } + if (doIncrement) { + sigExact = sig; + ++sig; + sig &= ~(uint64_t) (! (sigExtra & UINT64_C(0x7FFFFFFFFFFFFFFF)) & roundNearEven); + exp = ((sig & UINT64_C(0x8000000000000000)) != 0); + if (sig > sigExact) + softfloat_setRoundingUp(status); + } + return packToExtF80(sign, exp, sig); + } + } + if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) { + if (! softfloat_isMaskedException(status, softfloat_flag_overflow)) { + softfloat_raiseFlags(status, softfloat_flag_overflow); + exp -= 0x6000; + } + if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + roundMask = 0; + overflow: + softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact); + if (roundNearEven + || (roundingMode == softfloat_round_near_maxMag) + || (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) + ) { + exp = 0x7FFF; + sig = UINT64_C(0x8000000000000000); + softfloat_setRoundingUp(status); + } else { + exp = 0x7FFE; + sig = ~roundMask; + } + return packToExtF80(sign, exp, sig); + } + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (sigExtra) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + if (doIncrement) { + sigExact = sig; + ++sig; + if (! sig) { + ++exp; + sig = UINT64_C(0x8000000000000000); + sigExact >>= 1; // must scale also, or else later tests will fail + } else { + sig &= ~(uint64_t) (! (sigExtra & UINT64_C(0x7FFFFFFFFFFFFFFF)) & roundNearEven); + } + if (sig > sigExact) + softfloat_setRoundingUp(status); + } + else { + if (! sig) exp = 0; + } + return packToExtF80(sign, exp, sig); +} diff --git a/src/cpu/softfloat3e/s_roundPackToF128.cc b/src/cpu/softfloat3e/s_roundPackToF128.cc new file mode 100644 index 000000000..46741e5e9 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundPackToF128.cc @@ -0,0 +1,102 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +// trimmed for Bochs to support only 'softfloat_round_nearest_even' rounding mode +float128_t + softfloat_roundPackToF128(bool sign, int32_t exp, uint64_t sig64, uint64_t sig0, uint64_t sigExtra, struct softfloat_status_t *status) +{ + bool doIncrement, isTiny; + struct uint128_extra sig128Extra; + struct uint128 sig128; + float128_t z; + + sigExtra = 0; // artificially reduce precision to match hardware x86 which uses only 67-bit + sig0 &= UINT64_C(0xFFFFFFFF00000000); // do 80 bits for now + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x7FFD <= (uint32_t) exp) { + if (exp < 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < -1) || ! doIncrement || + softfloat_lt128(sig64, sig0, UINT64_C(0x0001FFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF)); + sig128Extra = softfloat_shiftRightJam128Extra(sig64, sig0, sigExtra, -exp); + sig64 = sig128Extra.v.v64; + sig0 = sig128Extra.v.v0; + sigExtra = sig128Extra.extra; + exp = 0; + if (isTiny && sigExtra) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra); + } else if ((0x7FFD < exp) || ((exp == 0x7FFD) + && softfloat_eq128(sig64, sig0, UINT64_C(0x0001FFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF)) + && doIncrement) + ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact); + z.v64 = packToF128UI64(sign, 0x7FFF, 0); + z.v0 = 0; + return z; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (sigExtra) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + } + if (doIncrement) { + sig128 = softfloat_add128(sig64, sig0, 0, 1); + sig64 = sig128.v64; + sig0 = sig128.v0 & ~(uint64_t) (! (sigExtra & UINT64_C(0x7FFFFFFFFFFFFFFF))); + } else { + if (! (sig64 | sig0)) exp = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + z.v64 = packToF128UI64(sign, exp, sig64); + z.v0 = sig0; + return z; +} diff --git a/src/cpu/softfloat3e/s_roundPackToF16.c b/src/cpu/softfloat3e/s_roundPackToF16.c new file mode 100644 index 000000000..c262d00b1 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundPackToF16.c @@ -0,0 +1,104 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float16 softfloat_roundPackToF16(bool sign, int16_t exp, uint16_t sig, struct softfloat_status_t *status) +{ + uint8_t roundingMode; + bool roundNearEven; + uint8_t roundIncrement, roundBits; + bool isTiny; + uint16_t uiZ; + uint16_t sigRef; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_getRoundingMode(status); + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x8; + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + roundIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) ? 0xF : 0; + } + roundBits = sig & 0xF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x1D <= (unsigned int) exp) { + if (exp < 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < -1) || (sig + roundIncrement < 0x8000); + sig = softfloat_shiftRightJam32(sig, -exp); + exp = 0; + roundBits = sig & 0xF; + if (isTiny) { + if (! softfloat_isMaskedException(status, softfloat_flag_underflow) || roundBits) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF16UI(sign, 0, 0); + } + } + } else if ((0x1D < exp) || (0x8000 <= sig + roundIncrement)) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags(status, softfloat_flag_overflow); + if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); + } + uiZ = packToF16UI(sign, 0x1F, 0) - ! roundIncrement; + return uiZ; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigRef = sig; + sig = (sig + roundIncrement)>>4; + sig &= ~(uint16_t) (! (roundBits ^ 8) & roundNearEven); + if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 4) > sigRef) softfloat_setRoundingUp(status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF16UI(sign, exp, sig); +} diff --git a/src/cpu/softfloat3e/s_roundPackToF32.c b/src/cpu/softfloat3e/s_roundPackToF32.c new file mode 100644 index 000000000..03a4e36a0 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundPackToF32.c @@ -0,0 +1,108 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float32 softfloat_roundPackToF32(bool sign, int16_t exp, uint32_t sig, struct softfloat_status_t *status) +{ + uint8_t roundingMode; + bool roundNearEven; + uint8_t roundIncrement, roundBits; + bool isTiny; + uint32_t uiZ; + uint32_t sigRef; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_getRoundingMode(status); + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x40; + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + roundIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) ? 0x7F : 0; + } + roundBits = sig & 0x7F; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0xFD <= (unsigned int) exp) { + if (exp < 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < -1) || (sig + roundIncrement < 0x80000000); + if (isTiny && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + exp += 192; + } + else { + sig = softfloat_shiftRightJam32(sig, -exp); + exp = 0; + roundBits = sig & 0x7F; + if (isTiny) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF32UI(sign, 0, 0); + } + if (roundBits) softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + } else if ((0xFD < exp) || (0x80000000 <= sig + roundIncrement)) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags(status, softfloat_flag_overflow); + if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); + } + uiZ = packToF32UI(sign, 0xFF, 0) - ! roundIncrement; + return uiZ; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigRef = sig; + sig = (sig + roundIncrement)>>7; + sig &= ~(uint32_t) (! (roundBits ^ 0x40) & roundNearEven); + if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 7) > sigRef) softfloat_setRoundingUp(status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF32UI(sign, exp, sig); +} diff --git a/src/cpu/softfloat3e/s_roundPackToF64.c b/src/cpu/softfloat3e/s_roundPackToF64.c new file mode 100644 index 000000000..713fd6940 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundPackToF64.c @@ -0,0 +1,108 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float64 softfloat_roundPackToF64(bool sign, int16_t exp, uint64_t sig, struct softfloat_status_t *status) +{ + uint8_t roundingMode; + bool roundNearEven; + uint16_t roundIncrement, roundBits; + bool isTiny; + uint64_t uiZ; + uint64_t sigRef; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_getRoundingMode(status); + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x200; + if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { + roundIncrement = + (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) ? 0x3FF : 0; + } + roundBits = sig & 0x3FF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (0x7FD <= (uint16_t) exp) { + if (exp < 0) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = (exp < -1) || (sig + roundIncrement < UINT64_C(0x8000000000000000)); + if (isTiny && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + exp += 1536; + } + else { + sig = softfloat_shiftRightJam64(sig, -exp); + exp = 0; + roundBits = sig & 0x3FF; + if (isTiny) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF64UI(sign, 0, 0); + } + if (roundBits) softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + } else if ((0x7FD < exp) || (UINT64_C(0x8000000000000000) <= sig + roundIncrement)) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags(status, softfloat_flag_overflow); + if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); + } + uiZ = packToF64UI(sign, 0x7FF, 0) - ! roundIncrement; + return uiZ; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigRef = sig; + sig = (sig + roundIncrement)>>10; + sig &= ~(uint64_t) (! (roundBits ^ 0x200) & roundNearEven); + if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 10) > sigRef) softfloat_setRoundingUp(status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return packToF64UI(sign, exp, sig); +} diff --git a/src/cpu/softfloat3e/s_roundToI32.c b/src/cpu/softfloat3e/s_roundToI32.c new file mode 100644 index 000000000..a7a0b13d7 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundToI32.c @@ -0,0 +1,79 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int32_t softfloat_roundToI32(bool sign, uint64_t sig, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t roundIncrement, roundBits; + uint32_t sig32; + union { uint32_t ui; int32_t i; } uZ; + int32_t z; + uint64_t absSigExact = sig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundIncrement = 0x800; + if ((roundingMode != softfloat_round_near_maxMag) && (roundingMode != softfloat_round_near_even)) { + roundIncrement = 0; + if (sign ? (roundingMode == softfloat_round_min) : (roundingMode == softfloat_round_max)) { + roundIncrement = 0xFFF; + } + } + roundBits = sig & 0xFFF; + sig += roundIncrement; + if (sig & UINT64_C(0xFFFFF00000000000)) goto invalid; + sig32 = sig>>12; + if ((roundBits == 0x800) && (roundingMode == softfloat_round_near_even)) { + sig32 &= ~(uint32_t) 1; + } + uZ.ui = sign ? -sig32 : sig32; + z = uZ.i; + if (z && ((z < 0) ^ sign)) goto invalid; + if (roundBits) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (((uint64_t)sig32 << 12) > absSigExact) + softfloat_setRoundingUp(status); + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return sign ? i32_fromNegOverflow : i32_fromPosOverflow; +} diff --git a/src/cpu/softfloat3e/s_roundToI64.c b/src/cpu/softfloat3e/s_roundToI64.c new file mode 100644 index 000000000..72d421889 --- /dev/null +++ b/src/cpu/softfloat3e/s_roundToI64.c @@ -0,0 +1,77 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int64_t + softfloat_roundToI64(bool sign, uint64_t sig, uint64_t sigExtra, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + union { uint64_t ui; int64_t i; } uZ; + int64_t z; + uint64_t absSigExact = sig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((roundingMode == softfloat_round_near_maxMag) || (roundingMode == softfloat_round_near_even)) { + if (UINT64_C(0x8000000000000000) <= sigExtra) goto increment; + } else { + if (sigExtra + && (sign ? (roundingMode == softfloat_round_min) : (roundingMode == softfloat_round_max))) { + increment: + ++sig; + if (!sig) goto invalid; + if ((sigExtra == UINT64_C(0x8000000000000000)) && (roundingMode == softfloat_round_near_even)) { + sig &= ~(uint64_t) 1; + } + } + } + uZ.ui = sign ? -sig : sig; + z = uZ.i; + if (z && ((z < 0) ^ sign)) goto invalid; + if (sigExtra) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > absSigExact) + softfloat_setRoundingUp(status); + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; +} diff --git a/src/cpu/softfloat3e/s_roundToUI32.c b/src/cpu/softfloat3e/s_roundToUI32.c new file mode 100644 index 000000000..d2956b0ac --- /dev/null +++ b/src/cpu/softfloat3e/s_roundToUI32.c @@ -0,0 +1,79 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint32_t + softfloat_roundToUI32(bool sign, uint64_t sig, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint16_t roundIncrement, roundBits; + uint32_t z; + uint64_t absSigExact = sig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundIncrement = 0x800; + if ((roundingMode != softfloat_round_near_maxMag) && (roundingMode != softfloat_round_near_even)) { + roundIncrement = 0; + if (sign) { + if (!sig) return 0; + if (roundingMode == softfloat_round_min) goto invalid; + } else { + if (roundingMode == softfloat_round_max) roundIncrement = 0xFFF; + } + } + roundBits = sig & 0xFFF; + sig += roundIncrement; + if (sig & UINT64_C(0xFFFFF00000000000)) goto invalid; + z = sig>>12; + if ((roundBits == 0x800) && (roundingMode == softfloat_round_near_even)) { + z &= ~(uint32_t) 1; + } + if (sign && z) goto invalid; + if (roundBits) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (((uint64_t)z << 12) > absSigExact) + softfloat_setRoundingUp(status); + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; +} diff --git a/src/cpu/softfloat3e/s_roundToUI64.c b/src/cpu/softfloat3e/s_roundToUI64.c new file mode 100644 index 000000000..75120a7fe --- /dev/null +++ b/src/cpu/softfloat3e/s_roundToUI64.c @@ -0,0 +1,76 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint64_t + softfloat_roundToUI64(bool sign, uint64_t sig, uint64_t sigExtra, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) +{ + uint64_t absSigExact = sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ((roundingMode == softfloat_round_near_maxMag) || (roundingMode == softfloat_round_near_even)) { + if (UINT64_C(0x8000000000000000) <= sigExtra) goto increment; + } else { + if (sign) { + if (!(sig | sigExtra)) return 0; + if (roundingMode == softfloat_round_min) goto invalid; + } else { + if ((roundingMode == softfloat_round_max) && sigExtra) { + increment: + ++sig; + if (!sig) goto invalid; + if ((sigExtra == UINT64_C(0x8000000000000000)) && (roundingMode == softfloat_round_near_even)) { + sig &= ~(uint64_t) 1; + } + } + } + } + if (sign && sig) goto invalid; + if (sigExtra) { + if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > absSigExact) + softfloat_setRoundingUp(status); + } + return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags(status, softfloat_flag_invalid); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; +} diff --git a/src/cpu/softfloat3e/s_shiftRightJam128.cc b/src/cpu/softfloat3e/s_shiftRightJam128.cc new file mode 100644 index 000000000..11fb26abf --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam128.cc @@ -0,0 +1,65 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_shiftRightJam128 + +struct uint128 + softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint32_t dist) +{ + uint8_t u8NegDist; + struct uint128 z; + + if (dist < 64) { + u8NegDist = -dist; + z.v64 = a64>>dist; + z.v0 = + a64<<(u8NegDist & 63) | a0>>dist + | ((uint64_t) (a0<<(u8NegDist & 63)) != 0); + } else { + z.v64 = 0; + z.v0 = + (dist < 127) + ? a64>>(dist & 63) + | (((a64 & (((uint64_t) 1<<(dist & 63)) - 1)) | a0) + != 0) + : ((a64 | a0) != 0); + } + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_shiftRightJam128Extra.cc b/src/cpu/softfloat3e/s_shiftRightJam128Extra.cc new file mode 100644 index 000000000..7f4b3fa82 --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam128Extra.cc @@ -0,0 +1,73 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_shiftRightJam128Extra + +struct uint128_extra + softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint32_t dist) +{ + uint8_t u8NegDist; + struct uint128_extra z; + + u8NegDist = -dist; + if (dist < 64) { + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist; + z.extra = a0<<(u8NegDist & 63); + } else { + z.v.v64 = 0; + if (dist == 64) { + z.v.v0 = a64; + z.extra = a0; + } else { + extra |= a0; + if (dist < 128) { + z.v.v0 = a64>>(dist & 63); + z.extra = a64<<(u8NegDist & 63); + } else { + z.v.v0 = 0; + z.extra = (dist == 128) ? a64 : (a64 != 0); + } + } + } + z.extra |= (extra != 0); + return z; + +} + +#endif diff --git a/src/cpu/softfloat3e/s_shiftRightJam256M.c b/src/cpu/softfloat3e/s_shiftRightJam256M.c new file mode 100644 index 000000000..654e01234 --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam256M.c @@ -0,0 +1,113 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitiveTypes.h" + +#ifndef softfloat_shiftRightJam256M + +static void softfloat_shortShiftRightJamM(uint8_t size_words, const uint64_t *aPtr, uint8_t dist, uint64_t *zPtr) +{ + uint8_t uNegDist; + unsigned int index, lastIndex; + uint64_t partWordZ, wordA; + + uNegDist = -dist; + index = indexWordLo(size_words); + lastIndex = indexWordHi(size_words); + wordA = aPtr[index]; + partWordZ = wordA>>dist; + if (partWordZ<>dist; + } + zPtr[index] = partWordZ; + +} + +void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *zPtr) +{ + uint64_t wordJam; + uint32_t wordDist; + uint64_t *ptr; + uint8_t i, innerDist; + + wordJam = 0; + wordDist = dist>>6; + if (wordDist) { + if (4 < wordDist) wordDist = 4; + ptr = (uint64_t *) (aPtr + indexMultiwordLo(4, wordDist)); + i = wordDist; + do { + wordJam = *ptr++; + if (wordJam) break; + --i; + } while (i); + ptr = zPtr; + } + if (wordDist < 4) { + aPtr += indexMultiwordHiBut(4, wordDist); + innerDist = dist & 63; + if (innerDist) { + softfloat_shortShiftRightJamM( + 4 - wordDist, + aPtr, + innerDist, + zPtr + indexMultiwordLoBut(4, wordDist) + ); + if (! wordDist) goto wordJam; + } else { + aPtr += indexWordLo(4 - wordDist); + ptr = zPtr + indexWordLo(4); + for (i = 4 - wordDist; i; --i) { + *ptr = *aPtr; + aPtr += wordIncr; + ptr += wordIncr; + } + } + ptr = zPtr + indexMultiwordHi(4, wordDist); + } + do { + *ptr++ = 0; + --wordDist; + } while (wordDist); + wordJam: + if (wordJam) zPtr[indexWordLo(4)] |= 1; +} + +#endif diff --git a/src/cpu/softfloat3e/s_shiftRightJam32.c b/src/cpu/softfloat3e/s_shiftRightJam32.c new file mode 100644 index 000000000..638aa0294 --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam32.c @@ -0,0 +1,45 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_shiftRightJam32 + +uint32_t softfloat_shiftRightJam32(uint32_t a, uint16_t dist) +{ + return (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); +} + +#endif diff --git a/src/cpu/softfloat3e/s_shiftRightJam64.c b/src/cpu/softfloat3e/s_shiftRightJam64.c new file mode 100644 index 000000000..03cf5e692 --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam64.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_shiftRightJam64 + +uint64_t softfloat_shiftRightJam64(uint64_t a, uint32_t dist) +{ + return (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); +} + +#endif + diff --git a/src/cpu/softfloat3e/s_shiftRightJam64Extra.c b/src/cpu/softfloat3e/s_shiftRightJam64Extra.c new file mode 100644 index 000000000..a80bafb35 --- /dev/null +++ b/src/cpu/softfloat3e/s_shiftRightJam64Extra.c @@ -0,0 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_shiftRightJam64Extra + +struct uint64_extra + softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint32_t dist) +{ + struct uint64_extra z; + + if (dist < 64) { + z.v = a>>dist; + z.extra = a<<(-dist & 63); + } else { + z.v = 0; + z.extra = (dist == 64) ? a : (a != 0); + } + z.extra |= (extra != 0); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_shortShiftLeft128.cc b/src/cpu/softfloat3e/s_shortShiftLeft128.cc new file mode 100644 index 000000000..dc24172cd --- /dev/null +++ b/src/cpu/softfloat3e/s_shortShiftLeft128.cc @@ -0,0 +1,51 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_shortShiftLeft128 + +struct uint128 + softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint8_t dist) +{ + struct uint128 z; + + z.v64 = a64<>(-dist & 63); + z.v0 = a0< +#include "softfloat_types.h" + +#ifndef softfloat_shortShiftRight128 + +struct uint128 + softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint8_t dist) +{ + struct uint128 z; + + z.v64 = a64>>dist; + z.v0 = a64<<(-dist & 63) | a0>>dist; + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_shortShiftRightJam64.c b/src/cpu/softfloat3e/s_shortShiftRightJam64.c new file mode 100644 index 000000000..cfee2a679 --- /dev/null +++ b/src/cpu/softfloat3e/s_shortShiftRightJam64.c @@ -0,0 +1,46 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include + +#ifndef softfloat_shortShiftRightJam64 + +uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint8_t dist) +{ + return a>>dist | ((a & (((uint64_t) 1< +#include "softfloat_types.h" + +#ifndef softfloat_shortShiftRightJam64Extra + +struct uint64_extra + softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint8_t dist) +{ + struct uint64_extra z; + + z.v = a>>dist; + z.extra = a<<(-dist & 63) | (extra != 0); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_sub128.cc b/src/cpu/softfloat3e/s_sub128.cc new file mode 100644 index 000000000..d5d5f941b --- /dev/null +++ b/src/cpu/softfloat3e/s_sub128.cc @@ -0,0 +1,50 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "softfloat_types.h" + +#ifndef softfloat_sub128 + +struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) +{ + struct uint128 z; + + z.v0 = a0 - b0; + z.v64 = a64 - b64 - (a0 < b0); + return z; +} + +#endif diff --git a/src/cpu/softfloat3e/s_sub256M.c b/src/cpu/softfloat3e/s_sub256M.c new file mode 100644 index 000000000..8b2f6e2fd --- /dev/null +++ b/src/cpu/softfloat3e/s_sub256M.c @@ -0,0 +1,59 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "primitiveTypes.h" + +#ifndef softfloat_sub256M + +void softfloat_sub256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr) +{ + unsigned int index; + uint8_t borrow; + uint64_t wordA, wordB; + + index = indexWordLo(4); + borrow = 0; + for (;;) { + wordA = aPtr[index]; + wordB = bPtr[index]; + zPtr[index] = wordA - wordB - borrow; + if (index == indexWordHi(4)) break; + borrow = borrow ? (wordA <= wordB) : (wordA < wordB); + index += wordIncr; + } +} + +#endif diff --git a/src/cpu/softfloat3e/s_subMagsExtF80.cc b/src/cpu/softfloat3e/s_subMagsExtF80.cc new file mode 100644 index 000000000..3a75cd768 --- /dev/null +++ b/src/cpu/softfloat3e/s_subMagsExtF80.cc @@ -0,0 +1,154 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +extFloat80_t + softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status) +{ + int32_t expA; + uint64_t sigA; + int32_t expB; + uint64_t sigB; + int32_t expDiff; + int32_t expZ; + uint64_t sigExtra; + struct uint128 sig128; + struct exp32_sig64 normExpSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expExtF80UI64(uiA64); + sigA = uiA0; + expB = expExtF80UI64(uiB64); + sigB = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA<<1)) goto propagateNaN; + if (expB == 0x7FFF) { + if ((sigB<<1)) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + } + if (sigB && ! expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80_twoargs(uiA64, uiA0); + } + if (expB == 0x7FFF) { + if ((sigB<<1)) goto propagateNaN; + if (sigA && ! expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ ^ 1, 0x7FFF, UINT64_C(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (! expB) { + if (sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + return softfloat_roundPackToExtF80(signZ ^ 1, expB, sigB, 0, softfloat_extF80_roundingPrecision(status), status); + } + return packToExtF80((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + return softfloat_roundPackToExtF80(signZ ^ 1, expB, sigB, 0, softfloat_extF80_roundingPrecision(status), status); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! sigB) + return softfloat_roundPackToExtF80(signZ, expA, sigA, 0, softfloat_extF80_roundingPrecision(status), status); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (0 < expDiff) goto expABigger; + if (expDiff < 0) goto expBBigger; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA; + sigExtra = 0; + if (sigB < sigA) goto aBigger; + if (sigA < sigB) goto bBigger; + return packToExtF80((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expBBigger: + sig128 = softfloat_shiftRightJam128(sigA, 0, -expDiff); + sigA = sig128.v64; + sigExtra = sig128.v0; + expZ = expB; + bBigger: + signZ = ! signZ; + sig128 = softfloat_sub128(sigB, 0, sigA, sigExtra); + goto normRoundPack; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expABigger: + sig128 = softfloat_shiftRightJam128(sigB, 0, expDiff); + sigB = sig128.v64; + sigExtra = sig128.v0; + expZ = expA; + aBigger: + sig128 = softfloat_sub128(sigA, 0, sigB, sigExtra); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + normRoundPack: + return + softfloat_normRoundPackToExtF80( + signZ, expZ, sig128.v64, sig128.v0, softfloat_extF80_roundingPrecision(status), status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); +} diff --git a/src/cpu/softfloat3e/s_subMagsF128.cc b/src/cpu/softfloat3e/s_subMagsF128.cc new file mode 100644 index 000000000..f39e6c02d --- /dev/null +++ b/src/cpu/softfloat3e/s_subMagsF128.cc @@ -0,0 +1,131 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t + softfloat_subMagsF128( + uint64_t uiA64, + uint64_t uiA0, + uint64_t uiB64, + uint64_t uiB0, + bool signZ, + struct softfloat_status_t *status +) +{ + int32_t expA; + struct uint128 sigA; + int32_t expB; + struct uint128 sigB, sigZ; + int32_t expDiff, expZ; + struct uint128 uiZ; + + expA = expF128UI64(uiA64); + sigA.v64 = fracF128UI64(uiA64); + sigA.v0 = uiA0; + expB = expF128UI64(uiB64); + sigB.v64 = fracF128UI64(uiB64); + sigB.v0 = uiB0; + sigA = softfloat_shortShiftLeft128(sigA.v64, sigA.v0, 4); + sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 4); + expDiff = expA - expB; + if (0 < expDiff) goto expABigger; + if (expDiff < 0) goto expBBigger; + if (expA == 0x7FFF) { + if (sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + } + expZ = expA; + if (! expZ) expZ = 1; + if (sigB.v64 < sigA.v64) goto aBigger; + if (sigA.v64 < sigB.v64) goto bBigger; + if (sigB.v0 < sigA.v0) goto aBigger; + if (sigA.v0 < sigB.v0) goto bBigger; + uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + uiZ.v0 = 0; + return uiZ; + expBBigger: + if (expB == 0x7FFF) { + if (sigB.v64 | sigB.v0) goto propagateNaN; + uiZ.v64 = packToF128UI64(signZ ^ 1, 0x7FFF, 0); + uiZ.v0 = 0; + return uiZ; + } + if (expA) { + sigA.v64 |= UINT64_C(0x0010000000000000); + } else { + ++expDiff; + if (! expDiff) goto newlyAlignedBBigger; + } + sigA = softfloat_shiftRightJam128(sigA.v64, sigA.v0, -expDiff); + newlyAlignedBBigger: + expZ = expB; + sigB.v64 |= UINT64_C(0x0010000000000000); + bBigger: + signZ = ! signZ; + sigZ = softfloat_sub128(sigB.v64, sigB.v0, sigA.v64, sigA.v0); + goto normRoundPack; + expABigger: + if (expA == 0x7FFF) { + if (sigA.v64 | sigA.v0) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + return uiZ; + } + if (expB) { + sigB.v64 |= UINT64_C(0x0010000000000000); + } else { + --expDiff; + if (! expDiff) goto newlyAlignedABigger; + } + sigB = softfloat_shiftRightJam128(sigB.v64, sigB.v0, expDiff); + newlyAlignedABigger: + expZ = expA; + sigA.v64 |= UINT64_C(0x0010000000000000); + aBigger: + sigZ = softfloat_sub128(sigA.v64, sigA.v0, sigB.v64, sigB.v0); + normRoundPack: + return softfloat_normRoundPackToF128(signZ, expZ - 5, sigZ.v64, sigZ.v0, status); + propagateNaN: + uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); + return uiZ; +} diff --git a/src/cpu/softfloat3e/s_subMagsF16.c b/src/cpu/softfloat3e/s_subMagsF16.c new file mode 100644 index 000000000..6241d0ee5 --- /dev/null +++ b/src/cpu/softfloat3e/s_subMagsF16.c @@ -0,0 +1,190 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float16 softfloat_subMagsF16(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status) +{ + int8_t expA; + uint16_t sigA; + int8_t expB; + uint16_t sigB; + int8_t expDiff; + uint16_t uiZ; + int16_t sigDiff; + bool signZ; + int8_t shiftDist, expZ; + uint16_t sigZ, sigX, sigY; + uint32_t sig32Z; + int8_t roundingMode; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF16UI(uiA); + sigA = fracF16UI(uiA); + expB = expF16UI(uiB); + sigB = fracF16UI(uiB); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expA == 0x1F) { + if (sigA | sigB) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF16UI; + } + if (!expA && (sigA | sigB)) softfloat_raiseFlags(status, softfloat_flag_denormal); + sigDiff = sigA - sigB; + if (! sigDiff) { + return packToF16UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + if (expA) --expA; + signZ = signF16UI(uiA); + if (sigDiff < 0) { + signZ = ! signZ; + sigDiff = -sigDiff; + } + shiftDist = softfloat_countLeadingZeros16(sigDiff) - 5; + expZ = expA - shiftDist; + if (expZ < 0) { + shiftDist = expA; + expZ = 0; + } + sigZ = sigDiff<>16; + if (sig32Z & 0xFFFF) { + sigZ |= 1; + } else { + if (! (sigZ & 0xF) && ((unsigned int) expZ < 0x1E)) { + sigZ >>= 4; + goto pack; + } + } + return softfloat_roundPackToF16(signZ, expZ, sigZ, status); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + return softfloat_propagateNaNF16UI(uiA, uiB, status); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + subEpsilon: + roundingMode = softfloat_getRoundingMode(status); + if (roundingMode != softfloat_round_near_even) { + if ((roundingMode == softfloat_round_minMag) + || (roundingMode == (signF16UI(uiZ) ? softfloat_round_max : softfloat_round_min))) { + --uiZ; + } + } + softfloat_raiseFlags(status, softfloat_flag_inexact); + return uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + pack: + return packToF16UI(signZ, expZ, sigZ); +} diff --git a/src/cpu/softfloat3e/s_subMagsF32.c b/src/cpu/softfloat3e/s_subMagsF32.c new file mode 100644 index 000000000..115e2906c --- /dev/null +++ b/src/cpu/softfloat3e/s_subMagsF32.c @@ -0,0 +1,151 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float32 softfloat_subMagsF32(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status) +{ + int16_t expA; + uint32_t sigA; + int16_t expB; + uint32_t sigB; + int16_t expDiff; + int32_t sigDiff; + bool signZ; + int8_t shiftDist; + int16_t expZ; + uint32_t sigX, sigY; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF32UI(uiA); + sigA = fracF32UI(uiA); + expB = expF32UI(uiB); + sigB = fracF32UI(uiB); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expA == 0xFF) { + if (sigA | sigB) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF32UI; + } + if (!expA && (sigA | sigB)) softfloat_raiseFlags(status, softfloat_flag_denormal); + sigDiff = sigA - sigB; + if (! sigDiff) { + return packToF32UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + if (expA) --expA; + signZ = signF32UI(uiA); + if (sigDiff < 0) { + signZ = ! signZ; + sigDiff = -sigDiff; + } + shiftDist = softfloat_countLeadingZeros32(sigDiff) - 8; + expZ = expA - shiftDist; + if (expZ < 0) { + shiftDist = expA; + expZ = 0; + } + if (!expZ && sigDiff) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF32UI(signZ, 0, 0); + } + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + return packToF32UI(signZ, expZ, sigDiff< +#include "internals.h" +#include "primitives.h" +#include "specialize.h" +#include "softfloat.h" + +float64 softfloat_subMagsF64(uint64_t uiA, uint64_t uiB, bool signZ, struct softfloat_status_t *status) +{ + int16_t expA; + uint64_t sigA; + int16_t expB; + uint64_t sigB; + int16_t expDiff; + int64_t sigDiff; + int8_t shiftDist; + int16_t expZ; + uint64_t sigZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF64UI(uiA); + sigA = fracF64UI(uiA); + expB = expF64UI(uiB); + sigB = fracF64UI(uiB); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (softfloat_denormalsAreZeros(status)) { + if (!expA) sigA = 0; + if (!expB) sigB = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if (expA == 0x7FF) { + if (sigA | sigB) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return defaultNaNF64UI; + } + if (!expA && (sigA | sigB)) softfloat_raiseFlags(status, softfloat_flag_denormal); + sigDiff = sigA - sigB; + if (! sigDiff) { + return packToF64UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + if (expA) --expA; + if (sigDiff < 0) { + signZ = ! signZ; + sigDiff = -sigDiff; + } + shiftDist = softfloat_countLeadingZeros64(sigDiff) - 11; + expZ = expA - shiftDist; + if (expZ < 0) { + shiftDist = expA; + expZ = 0; + } + if (!expZ && sigDiff) { + if (softfloat_flushUnderflowToZero(status)) { + softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact); + return packToF64UI(signZ, 0, 0); + } + if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) { + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + } + return packToF64UI(signZ, expZ, sigDiff< + +#include "primitives.h" +#include "primitiveTypes.h" + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by +| `b' to obtain a 192-bit product. The product is broken into three 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +| `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static __inline void mul128By64To192(uint64_t a64, uint64_t a0, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr) +{ + uint64_t zPtr[4]; + + softfloat_mul128To256M(a64, a0, 0, b, (uint64_t*) zPtr); + + assert(zPtr[indexWord(4, 3)] == 0); + + *z0Ptr = zPtr[indexWord(4, 2)]; + *z1Ptr = zPtr[indexWord(4, 1)]; + *z2Ptr = zPtr[indexWord(4, 0)]; +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' must be less than 64. The result is broken into two 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static __inline void shortShift128Left(uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) +{ + *z1Ptr = a1<>((-count) & 63)); +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' must be less than 64. The result is broken into two 64-bit pieces +| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static __inline void shortShift128Right(uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) +{ + uint64_t z0 = a0, z1 = a1; + int negCount = (-count) & 63; + + if (count != 0) { + z1 = (a0<>count); + z0 = a0>>count; + } + *z1Ptr = z1; + *z0Ptr = z0; +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +#ifdef USE_estimateDiv128To64 +static uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b) +{ + uint128 term, rem; + uint64_t b0, b1; + uint64_t z; + if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF); + b0 = b>>32; + z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32; + term = softfloat_mul64To128(b, z); + rem = softfloat_sub128(a0, a1, term.v64, term.v0); + while (((int64_t) rem.v64) < 0) { + z -= UINT64_C(0x100000000); + b1 = b<<32; + rem = softfloat_add128(rem.v64, rem.v0, b0, b1); + } + rem.v64 = (rem.v64<<32) | (rem.v0>>32); + z |= (b0<<32 <= rem.v64) ? 0xFFFFFFFF : rem.v64 / b0; + return z; +} +#endif + +/*---------------------------------------------------------------------------- +| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the +| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +| modulo 2^192, so any carry out is lost. The result is broken into three +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', +| `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static __inline void add192(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t b0, uint64_t b1, uint64_t b2, uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr) +{ + uint64_t z0, z1, z2; + unsigned carry0, carry1; + + z2 = a2 + b2; + carry1 = (z2 < a2); + z1 = a1 + b1; + carry0 = (z1 < a1); + z0 = a0 + b0; + z1 += carry1; + z0 += (z1 < carry1); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; +} + +/*---------------------------------------------------------------------------- +| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +| 2^128, so any borrow out (carry out) is lost. The result is broken into two +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +| `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static __inline void sub128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr) +{ + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - (a1 < b1); +} + +#endif diff --git a/src/cpu/softfloat3e/softfloat-specialize.h b/src/cpu/softfloat3e/softfloat-specialize.h new file mode 100644 index 000000000..bc7dcd263 --- /dev/null +++ b/src/cpu/softfloat3e/softfloat-specialize.h @@ -0,0 +1,224 @@ +/*============================================================================ +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. +=============================================================================*/ + +#ifndef _SOFTFLOAT_SPECIALIZE_H_ +#define _SOFTFLOAT_SPECIALIZE_H_ + +#include "config.h" +#include "softfloat.h" +#include "softfloat_types.h" + +/*============================================================================ + * Adapted for Bochs (x86 achitecture simulator) by + * Stanislav Shwartsman [sshwarts at sourceforge net] + * ==========================================================================*/ + +const int16_t int16_indefinite = (int16_t) 0x8000; +const int32_t int32_indefinite = (int32_t) 0x80000000; +const int64_t int64_indefinite = (int64_t) BX_CONST64(0x8000000000000000); + +const uint16_t uint16_indefinite = 0xffff; +const uint32_t uint32_indefinite = 0xffffffff; +const uint64_t uint64_indefinite = BX_CONST64(0xffffffffffffffff); + +/*---------------------------------------------------------------------------- +| Commonly used half-precision floating point constants +*----------------------------------------------------------------------------*/ +const float16 float16_negative_inf = 0xfc00; +const float16 float16_positive_inf = 0x7c00; +const float16 float16_negative_zero = 0x8000; +const float16 float16_positive_zero = 0x0000; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated half-precision NaN. +*----------------------------------------------------------------------------*/ +const float16 float16_default_nan = 0xFE00; + +#define FLOAT16_EXP_BIAS 0xF + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +| single-precision floating-point value, returning the result. After being +| shifted into the proper positions, the three fields are simply added +| together to form the result. This means that any integer portion of `zSig' +| will be added into the exponent. Since a properly normalized significand +| will have an integer portion equal to 1, the `zExp' input should be 1 less +| than the desired result exponent whenever `zSig' is a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +static __inline float16 packFloat16(int zSign, int zExp, uint16_t zSig) +{ + return (((uint16_t) zSign)<<15) + (((uint16_t) zExp)<<10) + zSig; +} + +/*---------------------------------------------------------------------------- +| Commonly used single-precision floating point constants +*----------------------------------------------------------------------------*/ +const float32 float32_negative_inf = 0xff800000; +const float32 float32_positive_inf = 0x7f800000; +const float32 float32_negative_zero = 0x80000000; +const float32 float32_positive_zero = 0x00000000; +const float32 float32_negative_one = 0xbf800000; +const float32 float32_positive_one = 0x3f800000; +const float32 float32_max_float = 0x7f7fffff; +const float32 float32_min_float = 0xff7fffff; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +const float32 float32_default_nan = 0xffc00000; + +#define FLOAT32_EXP_BIAS 0x7F + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +| single-precision floating-point value, returning the result. After being +| shifted into the proper positions, the three fields are simply added +| together to form the result. This means that any integer portion of `zSig' +| will be added into the exponent. Since a properly normalized significand +| will have an integer portion equal to 1, the `zExp' input should be 1 less +| than the desired result exponent whenever `zSig' is a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +static __inline float32 packFloat32(int zSign, int16_t zExp, uint32_t zSig) +{ + return (((uint32_t) zSign)<<31) + (((uint32_t) zExp)<<23) + zSig; +} + +/*---------------------------------------------------------------------------- +| Commonly used single-precision floating point constants +*----------------------------------------------------------------------------*/ +const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000); +const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000); +const float64 float64_negative_zero = BX_CONST64(0x8000000000000000); +const float64 float64_positive_zero = BX_CONST64(0x0000000000000000); +const float64 float64_negative_one = BX_CONST64(0xbff0000000000000); +const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000); +const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff); +const float64 float64_min_float = BX_CONST64(0xffefffffffffffff); + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000); + +#define FLOAT64_EXP_BIAS 0x3FF + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +| double-precision floating-point value, returning the result. After being +| shifted into the proper positions, the three fields are simply added +| together to form the result. This means that any integer portion of `zSig' +| will be added into the exponent. Since a properly normalized significand +| will have an integer portion equal to 1, the `zExp' input should be 1 less +| than the desired result exponent whenever `zSig' is a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +static __inline float64 packFloat64(int zSign, int16_t zExp, uint64_t zSig) +{ + return (((uint64_t) zSign)<<63) + (((uint64_t) zExp)<<52) + zSig; +} + +/*----------------------------------------------------------------------------- +| Commonly used extended double-precision floating-point constants. +*----------------------------------------------------------------------------*/ +extern const floatx80 Const_Z; +extern const floatx80 Const_1; +extern const floatx80 Const_L2T; +extern const floatx80 Const_L2E; +extern const floatx80 Const_PI; +extern const floatx80 Const_LG2; +extern const floatx80 Const_LN2; +extern const floatx80 Const_INF; +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. The +| `high' and `low' values hold the most- and least-significant bits, +| respectively. +*----------------------------------------------------------------------------*/ +#define floatx80_default_nan_exp 0xFFFF +#define floatx80_default_nan_fraction BX_CONST64(0xC000000000000000) + +#define FLOATX80_EXP_BIAS 0x3FFF + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an +| extended double-precision floating-point value, returning the result. +*----------------------------------------------------------------------------*/ + +static __inline floatx80 packFloatx80(int zSign, int32_t zExp, uint64_t zSig) +{ + floatx80 z; + z.signif = zSig; + z.signExp = (zSign << 15) + zExp; + return z; +} + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', the exponent `zExp', and the significand formed +| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision +| floating-point value, returning the result. After being shifted into the +| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply +| added together to form the most significant 32 bits of the result. This +| means that any integer portion of `zSig0' will be added into the exponent. +| Since a properly normalized significand will have an integer portion equal +| to 1, the `zExp' input should be 1 less than the desired result exponent +| whenever `zSig0' and `zSig1' concatenated form a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +static __inline float128_t packFloat128(int zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1) +{ + float128_t z; + z.v0 = zSig1; + z.v64 = (((uint64_t) zSign)<<63) + (((uint64_t) zExp)<<48) + zSig0; + return z; +} + +/*---------------------------------------------------------------------------- +| Packs two 64-bit precision integers into into the quadruple-precision +| floating-point value, returning the result. +*----------------------------------------------------------------------------*/ + +static __inline float128_t packFloat128(uint64_t zHi, uint64_t zLo) +{ + float128_t z; + z.v0 = zLo; + z.v64 = zHi; + return z; +} + +#define PACK_FLOAT_128(hi,lo) packFloat128(BX_CONST64(hi),BX_CONST64(lo)) + +#endif +#endif diff --git a/src/cpu/softfloat3e/softfloat.h b/src/cpu/softfloat3e/softfloat.h new file mode 100644 index 000000000..40253a2a9 --- /dev/null +++ b/src/cpu/softfloat3e/softfloat.h @@ -0,0 +1,702 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +/*============================================================================ +| Note: If SoftFloat is made available as a general library for programs to +| use, it is strongly recommended that a platform-specific version of this +| header, "softfloat.h", be created that folds in "softfloat_types.h" and that +| eliminates all dependencies on compile-time macros. +*============================================================================*/ + +#ifndef _SOFTFLOAT_H_ +#define _SOFTFLOAT_H_ + +#include + +#include "softfloat_types.h" +#include "softfloat-extra.h" + +struct softfloat_status_t +{ + uint8_t softfloat_roundingMode; + int softfloat_exceptionFlags; + int softfloat_exceptionMasks; + int softfloat_suppressException; + + bool softfloat_denormals_are_zeros; + bool softfloat_flush_underflow_to_zero; + + /*---------------------------------------------------------------------------- + | Rounding precision for 80-bit extended double-precision floating-point. + | Valid values are 32, 64, and 80. + *----------------------------------------------------------------------------*/ + uint8_t extF80_roundingPrecision; +}; + +/*---------------------------------------------------------------------------- +| Software floating-point rounding mode. +*----------------------------------------------------------------------------*/ +enum { + softfloat_round_near_even = 0, + softfloat_round_min = 1, + softfloat_round_down = softfloat_round_min, + softfloat_round_max = 2, + softfloat_round_up = softfloat_round_max, + softfloat_round_minMag = 3, + softfloat_round_to_zero = softfloat_round_minMag, + softfloat_round_near_maxMag = 4 +}; + +/*---------------------------------------------------------------------------- +| Software floating-point exception flags. +*----------------------------------------------------------------------------*/ +enum softfloat_exception_flag_t { + softfloat_flag_invalid = 0x01, + softfloat_flag_denormal = 0x02, + softfloat_flag_divbyzero = 0x04, + softfloat_flag_infinite = softfloat_flag_divbyzero, + softfloat_flag_overflow = 0x08, + softfloat_flag_underflow = 0x10, + softfloat_flag_inexact = 0x20 +}; + +static const unsigned softfloat_all_exceptions_mask = 0x3f; + +#define FLOATX80 + +#ifdef FLOATX80 +#define RAISE_SW_C1 0x0200 +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point ordering relations +*----------------------------------------------------------------------------*/ +enum { + softfloat_relation_less = -1, + softfloat_relation_equal = 0, + softfloat_relation_greater = 1, + softfloat_relation_unordered = 2 +}; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point class. +*----------------------------------------------------------------------------*/ +typedef enum { + softfloat_zero, + softfloat_SNaN, + softfloat_QNaN, + softfloat_negative_inf, + softfloat_positive_inf, + softfloat_denormal, + softfloat_normalized +} softfloat_class_t; + +/*---------------------------------------------------------------------------- +| Options to indicate which negations to perform in f*_muladd() +| Using these differs from negating an input or output before calling +| the muladd function in that this means that a NaN doesn't have its +| sign bit inverted before it is propagated. +*----------------------------------------------------------------------------*/ +enum { + softfloat_mulAdd_subC = 1, + softfloat_muladd_negate_c = softfloat_mulAdd_subC, + softfloat_mulAdd_subProd = 2, + softfloat_muladd_negate_product = softfloat_mulAdd_subProd, + softfloat_muladd_negate_result = softfloat_muladd_negate_c | softfloat_muladd_negate_product +}; + +static __inline void softfloat_setFlags(struct softfloat_status_t *status, int flags) { + status->softfloat_exceptionFlags = flags; +} + +/*---------------------------------------------------------------------------- +| Routine to raise any or all of the software floating-point exception flags. +*----------------------------------------------------------------------------*/ +static __inline void softfloat_raiseFlags(struct softfloat_status_t *status, int flags) { + status->softfloat_exceptionFlags |= flags; +} + +/*---------------------------------------------------------------------------- +| Check if exception is masked. +*----------------------------------------------------------------------------*/ +static __inline int softfloat_isMaskedException(const struct softfloat_status_t *status, int flags) { + return status->softfloat_exceptionMasks & flags; +} + +/*---------------------------------------------------------------------------- +| Suppress generation of these exceptions. +*----------------------------------------------------------------------------*/ +static __inline void softfloat_suppressException(struct softfloat_status_t *status, int flags) { + status->softfloat_suppressException |= flags; +} + +/*---------------------------------------------------------------------------- +| Obtain current rounding mode. +*----------------------------------------------------------------------------*/ +static __inline uint8_t softfloat_getRoundingMode(const struct softfloat_status_t *status) { + return status->softfloat_roundingMode; +} + +/*---------------------------------------------------------------------------- +| Read denormals-are-zeroes flag. +*----------------------------------------------------------------------------*/ +static __inline bool softfloat_denormalsAreZeros(const struct softfloat_status_t *status) { + return status->softfloat_denormals_are_zeros; +} + +/*---------------------------------------------------------------------------- +| Read flush-underflow-to-zero flag. +*----------------------------------------------------------------------------*/ +static __inline bool softfloat_flushUnderflowToZero(const struct softfloat_status_t *status) { + return status->softfloat_flush_underflow_to_zero; +} + +/*---------------------------------------------------------------------------- +| Obtain current rounding precision for F80. +*----------------------------------------------------------------------------*/ +static __inline uint8_t softfloat_extF80_roundingPrecision(const struct softfloat_status_t *status) { + return status->extF80_roundingPrecision; +} + +/*---------------------------------------------------------------------------- +| Returns raised IEC/IEEE floating-point exception flags. +*----------------------------------------------------------------------------*/ +static __inline int softfloat_getExceptionFlags(const struct softfloat_status_t *status) { + return status->softfloat_exceptionFlags & ~status->softfloat_suppressException; +} + +/*---------------------------------------------------------------------------- +| Raise floating point precision lost up flag (floatx80 only). +*----------------------------------------------------------------------------*/ +#ifdef FLOATX80 +static __inline void softfloat_setRoundingUp(struct softfloat_status_t *status) { + status->softfloat_exceptionFlags |= RAISE_SW_C1; +} +#endif + +/*---------------------------------------------------------------------------- +| Integer-to-floating-point conversion routines. +*----------------------------------------------------------------------------*/ +float16 ui32_to_f16(uint32_t, struct softfloat_status_t *); +float32 ui32_to_f32(uint32_t, struct softfloat_status_t *); +float64 ui32_to_f64(uint32_t); +float16 ui64_to_f16(uint64_t, struct softfloat_status_t *); +float32 ui64_to_f32(uint64_t, struct softfloat_status_t *); +float64 ui64_to_f64(uint64_t, struct softfloat_status_t *); +float16 i32_to_f16(int32_t, struct softfloat_status_t *); +float32 i32_to_f32(int32_t, struct softfloat_status_t *); +float64 i32_to_f64(int32_t); +float16 i64_to_f16(int64_t, struct softfloat_status_t *); +float32 i64_to_f32(int64_t, struct softfloat_status_t *); +float64 i64_to_f64(int64_t, struct softfloat_status_t *); + +static __inline float16 i16_to_f16(int16_t a, struct softfloat_status_t *status) { + return i32_to_f16((int32_t)(a), status); +} + +static __inline float16 ui16_to_f16(uint16_t a, struct softfloat_status_t *status) { + return ui32_to_f16((uint32_t)(a), status); +} + +/*---------------------------------------------------------------------------- +| 16-bit (half-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint32_t f16_to_ui32(float16, uint8_t, bool, struct softfloat_status_t *); +uint64_t f16_to_ui64(float16, uint8_t, bool, struct softfloat_status_t *); +int32_t f16_to_i32(float16, uint8_t, bool, struct softfloat_status_t *); +int64_t f16_to_i64(float16, uint8_t, bool, struct softfloat_status_t *); +uint32_t f16_to_ui32_r_minMag(float16, bool, struct softfloat_status_t *); +uint64_t f16_to_ui64_r_minMag(float16, bool, struct softfloat_status_t *); +int32_t f16_to_i32_r_minMag(float16, bool, struct softfloat_status_t *); +int64_t f16_to_i64_r_minMag(float16, bool, struct softfloat_status_t *); +float32 f16_to_f32(float16, struct softfloat_status_t *); +float64 f16_to_f64(float16, struct softfloat_status_t *); +float16 f16_roundToInt(float16, uint8_t, uint8_t, bool, struct softfloat_status_t *); +float16 f16_add(float16, float16, struct softfloat_status_t *); +float16 f16_sub(float16, float16, struct softfloat_status_t *); +float16 f16_mul(float16, float16, struct softfloat_status_t *); +float16 f16_mulAdd(float16, float16, float16, uint8_t op, struct softfloat_status_t *); +float16 f16_div(float16, float16, struct softfloat_status_t *); +float16 f16_min(float16, float16, struct softfloat_status_t *); +float16 f16_max(float16, float16, struct softfloat_status_t *); +float16 f16_getExp(float16, struct softfloat_status_t *); +float16 f16_getMant(float16, struct softfloat_status_t *, int, int); +float16 f16_range(float16, float16, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *); +int f16_compare(float16, float16, bool, struct softfloat_status_t *); +float16 f16_sqrt(float16, struct softfloat_status_t *); +softfloat_class_t f16_class(float16); + +#ifdef __cplusplus +extern "C" { +#endif +bool f16_isSignalingNaN(float16); +bool f16_isNaN(float16); +#ifdef __cplusplus +} +#endif + +bool f16_sign(float16); +int8_t f16_exp(float16); +uint16_t f16_fraction(float16); +float16 f16_denormal_to_zero(float16); + +static __inline int f16_compare_normal(float16 a, float16 b, struct softfloat_status_t *status) { + return f16_compare(a, b, 0, status); +} + +static __inline int f16_compare_quiet(float16 a, float16 b, struct softfloat_status_t *status) { + return f16_compare(a, b, 1, status); +} + +static __inline float16 f16_roundToInt_normal(float16 a, uint8_t scale, struct softfloat_status_t *status) { + return f16_roundToInt(a, scale, softfloat_getRoundingMode(status), true, status); +} +static __inline float16 f16_roundToInt_noscale(float16 a, struct softfloat_status_t *status) { + return f16_roundToInt(a, 0, softfloat_getRoundingMode(status), true, status); +} + +static __inline int64_t f16_to_i64_normal(float16 a, struct softfloat_status_t *status) { + return f16_to_i64(a, softfloat_getRoundingMode(status), true, status); +} +static __inline int32_t f16_to_i32_normal(float16 a, struct softfloat_status_t *status) { + return f16_to_i32(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline int16_t f16_to_i16(float16 a, struct softfloat_status_t *status) +{ + int32_t val_32 = f16_to_i32_normal(a, status); + int16_t val_16 = (int16_t) val_32; + if ((int32_t)(val_16) != val_32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return val_16; +} + +static __inline int64_t f16_to_i64_round_to_zero(float16 a, struct softfloat_status_t *status) { + return f16_to_i64_r_minMag(a, true, status); +} +static __inline int32_t f16_to_i32_round_to_zero(float16 a, struct softfloat_status_t *status) { + return f16_to_i32_r_minMag(a, true, status); +} + +static __inline int16_t f16_to_i16_round_to_zero(float16 a, struct softfloat_status_t *status) +{ + int32_t val_32 = f16_to_i32_round_to_zero(a, status); + int16_t val_16 = (int16_t) val_32; + if ((int32_t)(val_16) != val_32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return val_16; +} + +static __inline uint64_t f16_to_ui64_normal(float16 a, struct softfloat_status_t *status) { + return f16_to_ui64(a, softfloat_getRoundingMode(status), true, status); +} +static __inline uint32_t f16_to_ui32_normal(float16 a, struct softfloat_status_t *status) { + return f16_to_ui32(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline uint16_t f16_to_ui16(float16 a, struct softfloat_status_t *status) +{ + uint32_t val_32 = f16_to_ui32_normal(a, status); + if (val_32 > 0xFFFF) { + softfloat_setFlags(status, softfloat_flag_invalid); + return 0xFFFF; + } + return (uint16_t) val_32; +} + +static __inline uint64_t f16_to_ui64_round_to_zero(float16 a, struct softfloat_status_t *status) { + return f16_to_ui64_r_minMag(a, true, status); +} +static __inline uint32_t f16_to_ui32_round_to_zero(float16 a, struct softfloat_status_t *status) { + return f16_to_ui32_r_minMag(a, true, status); +} + +static __inline uint16_t f16_to_ui16_round_to_zero(float16 a, struct softfloat_status_t *status) +{ + uint32_t val_32 = f16_to_ui32_round_to_zero(a, status); + if (val_32 > 0xFFFF) { + softfloat_setFlags(status, softfloat_flag_invalid); + return 0xFFFF; + } + return (uint16_t) val_32; +} + +static __inline float16 f16_fmadd(float16 a, float16 b, float16 c, struct softfloat_status_t *status) { + return f16_mulAdd(a, b, c, 0, status); +} +static __inline float16 f16_fmsub(float16 a, float16 b, float16 c, struct softfloat_status_t *status) { + return f16_mulAdd(a, b, c, softfloat_muladd_negate_c, status); +} +static __inline float16 f16_fnmadd(float16 a, float16 b, float16 c, struct softfloat_status_t *status) { + return f16_mulAdd(a, b, c, softfloat_muladd_negate_product, status); +} +static __inline float16 f16_fnmsub(float16 a, float16 b, float16 c, struct softfloat_status_t *status) { + return f16_mulAdd(a, b, c, softfloat_muladd_negate_result, status); +} + +/*---------------------------------------------------------------------------- +| 32-bit (single-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint32_t f32_to_ui32(float32, uint8_t, bool, struct softfloat_status_t *); +uint64_t f32_to_ui64(float32, uint8_t, bool, struct softfloat_status_t *); +int32_t f32_to_i32(float32, uint8_t, bool, struct softfloat_status_t *); +int64_t f32_to_i64(float32, uint8_t, bool, struct softfloat_status_t *); +uint32_t f32_to_ui32_r_minMag(float32, bool, struct softfloat_status_t *); +uint64_t f32_to_ui64_r_minMag(float32, bool, struct softfloat_status_t *); +int32_t f32_to_i32_r_minMag(float32, bool, struct softfloat_status_t *); +int64_t f32_to_i64_r_minMag(float32, bool, struct softfloat_status_t *); +float16 f32_to_f16(float32, struct softfloat_status_t *); +float64 f32_to_f64(float32, struct softfloat_status_t *); +float32 f32_roundToInt(float32, uint8_t, uint8_t, bool, struct softfloat_status_t *); +float32 f32_add(float32, float32, struct softfloat_status_t *); +float32 f32_sub(float32, float32, struct softfloat_status_t *); +float32 f32_mul(float32, float32, struct softfloat_status_t *); +float32 f32_mulAdd(float32, float32, float32, uint8_t op, struct softfloat_status_t *); +float32 f32_div(float32, float32, struct softfloat_status_t *); +float32 f32_min(float32, float32, struct softfloat_status_t *); +float32 f32_max(float32, float32, struct softfloat_status_t *); +float32 f32_scalef(float32, float32, struct softfloat_status_t *); +float32 f32_getExp(float32, struct softfloat_status_t *); +float32 f32_getMant(float32, struct softfloat_status_t *, int, int); +float32 f32_range(float32, float32, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *); +float32 f32_frc(float32, struct softfloat_status_t *); +int f32_compare(float32, float32, bool, struct softfloat_status_t *); +float32 f32_sqrt(float32, struct softfloat_status_t *); +softfloat_class_t f32_class(float32); + +#ifdef __cplusplus +extern "C" { +#endif +bool f32_isSignalingNaN(float32); +bool f32_isNaN(float32); +#ifdef __cplusplus +} +#endif + +bool f32_sign(float32); +int16_t f32_exp(float32); +uint32_t f32_fraction(float32); +float32 f32_denormal_to_zero(float32); + +static __inline int f32_compare_normal(float32 a, float32 b, struct softfloat_status_t *status) { + return f32_compare(a, b, 0, status); +} + +static __inline int f32_compare_quiet(float32 a, float32 b, struct softfloat_status_t *status) { + return f32_compare(a, b, 1, status); +} + +static __inline float32 f32_roundToInt_normal(float32 a, uint8_t scale, struct softfloat_status_t *status) { + return f32_roundToInt(a, scale, softfloat_getRoundingMode(status), true, status); +} +static __inline float32 f32_roundToInt_noscale(float32 a, struct softfloat_status_t *status) { + return f32_roundToInt(a, 0, softfloat_getRoundingMode(status), true, status); +} + +static __inline int32_t f32_to_i32_normal(float32 a, struct softfloat_status_t *status) { + return f32_to_i32(a, softfloat_getRoundingMode(status), true, status); +} +static __inline int64_t f32_to_i64_normal(float32 a, struct softfloat_status_t *status) { + return f32_to_i64(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline int32_t f32_to_i32_round_to_zero(float32 a, struct softfloat_status_t *status) { + return f32_to_i32_r_minMag(a, true, status); +} +static __inline int64_t f32_to_i64_round_to_zero(float32 a, struct softfloat_status_t *status) { + return f32_to_i64_r_minMag(a, true, status); +} + +static __inline uint32_t f32_to_ui32_normal(float32 a, struct softfloat_status_t *status) { + return f32_to_ui32(a, softfloat_getRoundingMode(status), true, status); +} +static __inline uint64_t f32_to_ui64_normal(float32 a, struct softfloat_status_t *status) { + return f32_to_ui64(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline uint32_t f32_to_ui32_round_to_zero(float32 a, struct softfloat_status_t *status) { + return f32_to_ui32_r_minMag(a, true, status); +} +static __inline uint64_t f32_to_ui64_round_to_zero(float32 a, struct softfloat_status_t *status) { + return f32_to_ui64_r_minMag(a, true, status); +} + +static __inline float32 f32_fmadd(float32 a, float32 b, float32 c, struct softfloat_status_t *status) { + return f32_mulAdd(a, b, c, 0, status); +} +static __inline float32 f32_fmsub(float32 a, float32 b, float32 c, struct softfloat_status_t *status) { + return f32_mulAdd(a, b, c, softfloat_muladd_negate_c, status); +} +static __inline float32 f32_fnmadd(float32 a, float32 b, float32 c, struct softfloat_status_t *status) { + return f32_mulAdd(a, b, c, softfloat_muladd_negate_product, status); +} +static __inline float32 f32_fnmsub(float32 a, float32 b, float32 c, struct softfloat_status_t *status) { + return f32_mulAdd(a, b, c, softfloat_muladd_negate_result, status); +} + +/*---------------------------------------------------------------------------- +| 64-bit (double-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint32_t f64_to_ui32(float64, uint8_t, bool, struct softfloat_status_t *); +uint64_t f64_to_ui64(float64, uint8_t, bool, struct softfloat_status_t *); +int32_t f64_to_i32(float64, uint8_t, bool, struct softfloat_status_t *); +int64_t f64_to_i64(float64, uint8_t, bool, struct softfloat_status_t *); +uint32_t f64_to_ui32_r_minMag(float64, bool, struct softfloat_status_t *); +uint64_t f64_to_ui64_r_minMag(float64, bool, struct softfloat_status_t *); +int32_t f64_to_i32_r_minMag(float64, bool, struct softfloat_status_t *); +int64_t f64_to_i64_r_minMag(float64, bool, struct softfloat_status_t *); +float16 f64_to_f16(float64, struct softfloat_status_t *); +float32 f64_to_f32(float64, struct softfloat_status_t *); +float64 f64_roundToInt(float64, uint8_t, uint8_t, bool, struct softfloat_status_t *); +float64 f64_add(float64, float64, struct softfloat_status_t *); +float64 f64_sub(float64, float64, struct softfloat_status_t *); +float64 f64_mul(float64, float64, struct softfloat_status_t *); +float64 f64_mulAdd(float64, float64, float64, uint8_t op, struct softfloat_status_t *); +float64 f64_div(float64, float64, struct softfloat_status_t *); +float64 f64_min(float64, float64, struct softfloat_status_t *); +float64 f64_max(float64, float64, struct softfloat_status_t *); +float64 f64_scalef(float64, float64, struct softfloat_status_t *); +float64 f64_getExp(float64, struct softfloat_status_t *); +float64 f64_getMant(float64, struct softfloat_status_t *, int, int); +float64 f64_range(float64, float64, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *); +float64 f64_frc(float64, struct softfloat_status_t *); +int f64_compare(float64, float64, bool, struct softfloat_status_t *); +float64 f64_sqrt(float64, struct softfloat_status_t *); +softfloat_class_t f64_class(float64); + +#ifdef __cplusplus +extern "C" { +#endif +bool f64_isSignalingNaN(float64); +bool f64_isNaN(float64); +#ifdef __cplusplus +} +#endif + +bool f64_sign(float64); +int16_t f64_exp(float64); +uint64_t f64_fraction(float64); +float64 f64_denormal_to_zero(float64); + +static __inline int f64_compare_normal(float64 a, float64 b, struct softfloat_status_t *status) { + return f64_compare(a, b, 0, status); +} + +static __inline int f64_compare_quiet(float64 a, float64 b, struct softfloat_status_t *status) { + return f64_compare(a, b, 1, status); +} + +static __inline float64 f64_roundToInt_normal(float64 a, uint8_t scale, struct softfloat_status_t *status) { + return f64_roundToInt(a, scale, softfloat_getRoundingMode(status), true, status); +} +static __inline float64 f64_roundToInt_noscale(float64 a, struct softfloat_status_t *status) { + return f64_roundToInt(a, 0, softfloat_getRoundingMode(status), true, status); +} + +static __inline int32_t f64_to_i32_normal(float64 a, struct softfloat_status_t *status) { + return f64_to_i32(a, softfloat_getRoundingMode(status), true, status); +} +static __inline int64_t f64_to_i64_normal(float64 a, struct softfloat_status_t *status) { + return f64_to_i64(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline int32_t f64_to_i32_round_to_zero(float64 a, struct softfloat_status_t *status) { + return f64_to_i32_r_minMag(a, true, status); +} +static __inline int64_t f64_to_i64_round_to_zero(float64 a, struct softfloat_status_t *status) { + return f64_to_i64_r_minMag(a, true, status); +} + +static __inline uint32_t f64_to_ui32_normal(float64 a, struct softfloat_status_t *status) { + return f64_to_ui32(a, softfloat_getRoundingMode(status), true, status); +} +static __inline uint64_t f64_to_ui64_normal(float64 a, struct softfloat_status_t *status) { + return f64_to_ui64(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline uint32_t f64_to_ui32_round_to_zero(float64 a, struct softfloat_status_t *status) { + return f64_to_ui32_r_minMag(a, true, status); +} +static __inline uint64_t f64_to_ui64_round_to_zero(float64 a, struct softfloat_status_t *status) { + return f64_to_ui64_r_minMag(a, true, status); +} + +static __inline float64 f64_fmadd(float64 a, float64 b, float64 c, struct softfloat_status_t *status) { + return f64_mulAdd(a, b, c, 0, status); +} +static __inline float64 f64_fmsub(float64 a, float64 b, float64 c, struct softfloat_status_t *status) { + return f64_mulAdd(a, b, c, softfloat_muladd_negate_c, status); +} +static __inline float64 f64_fnmadd(float64 a, float64 b, float64 c, struct softfloat_status_t *status) { + return f64_mulAdd(a, b, c, softfloat_muladd_negate_product, status); +} +static __inline float64 f64_fnmsub(float64 a, float64 b, float64 c, struct softfloat_status_t *status) { + return f64_mulAdd(a, b, c, softfloat_muladd_negate_result, status); +} + +#ifdef __cplusplus +extern "C" { +#endif +/*---------------------------------------------------------------------------- +| 80-bit extended double-precision floating-point operations. +*----------------------------------------------------------------------------*/ +extFloat80_t f16_to_extF80(float16, struct softfloat_status_t *); +extFloat80_t f32_to_extF80(float32, struct softfloat_status_t *); +extFloat80_t f64_to_extF80(float64, struct softfloat_status_t *); +extFloat80_t i32_to_extF80(int32_t); +extFloat80_t i64_to_extF80(int64_t); +extFloat80_t ui32_to_extF80(uint32_t); +extFloat80_t ui64_to_extF80(uint64_t); + +uint32_t extF80_to_ui32(extFloat80_t, uint8_t, bool, struct softfloat_status_t *); +uint64_t extF80_to_ui64(extFloat80_t, uint8_t, bool, struct softfloat_status_t *); +int32_t extF80_to_i32(extFloat80_t, uint8_t, bool, struct softfloat_status_t *); +int64_t extF80_to_i64(extFloat80_t, uint8_t, bool, struct softfloat_status_t *); +uint32_t extF80_to_ui32_r_minMag(extFloat80_t, bool, struct softfloat_status_t *); +uint64_t extF80_to_ui64_r_minMag(extFloat80_t, bool, struct softfloat_status_t *); +int32_t extF80_to_i32_r_minMag(extFloat80_t, bool, struct softfloat_status_t *); +int64_t extF80_to_i64_r_minMag(extFloat80_t, bool, struct softfloat_status_t *); +float16 extF80_to_f16(extFloat80_t, struct softfloat_status_t *); +float32 extF80_to_f32(extFloat80_t, struct softfloat_status_t *); +float64 extF80_to_f64(extFloat80_t, struct softfloat_status_t *); +float128_t extF80_to_f128(extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_roundToInt(extFloat80_t, uint8_t, bool, struct softfloat_status_t *); +extFloat80_t extF80_add(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_sub(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_mul(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_div(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_rem(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_scale(extFloat80_t, extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_sqrt(extFloat80_t, struct softfloat_status_t *); +extFloat80_t extF80_extract(extFloat80_t *, struct softfloat_status_t *); +int extF80_compare(extFloat80_t, extFloat80_t, int, struct softfloat_status_t *); +softfloat_class_t extF80_class(extFloat80_t); + +static __inline int extF80_compare_normal(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) { + return extF80_compare(a, b, 0, status); +} + +static __inline int extF80_compare_quiet(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) { + return extF80_compare(a, b, 1, status); +} + +static __inline extFloat80_t extF80_roundToInt_normal(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_roundToInt(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline int64_t extF80_to_i64_normal(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i64(a, softfloat_getRoundingMode(status), true, status); +} +static __inline int32_t extF80_to_i32_normal(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i32(a, softfloat_getRoundingMode(status), true, status); +} + +static __inline int16_t extF80_to_i16(extFloat80_t a, struct softfloat_status_t *status) +{ + int32_t v32 = extF80_to_i32_normal(a, status); + int16_t v16 = (int16_t) v32; + + if ((int32_t)(v16) != v32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return v16; +} + +static __inline int64_t extF80_to_i64_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i64_r_minMag(a, true, status); +} +static __inline int32_t extF80_to_i32_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i32_r_minMag(a, true, status); +} + +static __inline int16_t extF80_to_i16_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) +{ + int32_t v32 = extF80_to_i32_round_to_zero(a, status); + int16_t v16 = (int16_t) v32; + + if ((int32_t)(v16) != v32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return v16; +} + +bool extF80_isUnsupported(extFloat80_t); +bool extF80_isSignalingNaN(extFloat80_t); +bool extF80_isNaN(extFloat80_t); + +bool extF80_sign(extFloat80_t); +int16_t extF80_exp(extFloat80_t); +uint64_t extF80_fraction(extFloat80_t); + +/*---------------------------------------------------------------------------- +| 128-bit (quadruple-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +float128_t f32_to_f128(float32, struct softfloat_status_t *); +float128_t f64_to_f128(float64, struct softfloat_status_t *); +float128_t i32_to_f128(int32_t); +float128_t i64_to_f128(int64_t); +float128_t ui32_to_f128(uint32_t); +float128_t ui64_to_f128(uint64_t); + +uint32_t f128_to_ui32(float128_t, uint8_t, bool, struct softfloat_status_t *); +uint64_t f128_to_ui64(float128_t, uint8_t, bool, struct softfloat_status_t *); +int32_t f128_to_i32(float128_t, uint8_t, bool, struct softfloat_status_t *); +int64_t f128_to_i64(float128_t, uint8_t, bool, struct softfloat_status_t *); +uint32_t f128_to_ui32_r_minMag(float128_t, bool, struct softfloat_status_t *); +uint64_t f128_to_ui64_r_minMag(float128_t, bool, struct softfloat_status_t *); +int32_t f128_to_i32_r_minMag(float128_t, bool, struct softfloat_status_t *); +int64_t f128_to_i64_r_minMag(float128_t, bool, struct softfloat_status_t *); +float32 f128_to_f32(float128_t, struct softfloat_status_t *); +float64 f128_to_f64(float128_t, struct softfloat_status_t *); +extFloat80_t f128_to_extF80(float128_t, struct softfloat_status_t *); +float128_t f128_roundToInt(float128_t, uint8_t, bool, struct softfloat_status_t *); +float128_t f128_add(float128_t, float128_t, struct softfloat_status_t *); +float128_t f128_sub(float128_t, float128_t, struct softfloat_status_t *); +float128_t f128_mul(float128_t, float128_t, struct softfloat_status_t *); +float128_t f128_mulAdd(float128_t, float128_t, float128_t, uint8_t op, struct softfloat_status_t *); +float128_t f128_div(float128_t, float128_t, struct softfloat_status_t *); +float128_t f128_sqrt(float128_t, struct softfloat_status_t *); +bool f128_isSignalingNaN(float128_t); +bool f128_isNaN(float128_t); +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/cpu/softfloat3e/softfloat_types.h b/src/cpu/softfloat3e/softfloat_types.h new file mode 100644 index 000000000..001f8e0c6 --- /dev/null +++ b/src/cpu/softfloat3e/softfloat_types.h @@ -0,0 +1,87 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef _SOFTFLOAT_TYPES_H_ +#define _SOFTFLOAT_TYPES_H_ + +#include + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point types. +*----------------------------------------------------------------------------*/ +typedef uint16_t float16, bfloat16; +typedef uint32_t float32; +typedef uint64_t float64; + +struct uint128 { uint64_t v0, v64; }; +struct uint64_extra { uint64_t extra, v; }; +struct uint128_extra { uint64_t extra; struct uint128 v; }; + +/*---------------------------------------------------------------------------- +| Types used to pass 16-bit, 32-bit, 64-bit, and 128-bit floating-point +| arguments and results to/from functions. These types must be exactly +| 16 bits, 32 bits, 64 bits, and 128 bits in size, respectively. +*----------------------------------------------------------------------------*/ +typedef struct f16_t { uint16_t v; } float16_t; +typedef struct f32_t { uint32_t v; } float32_t; +typedef struct f64_t { uint64_t v; } float64_t; +typedef struct uint128 float128_t; + +/*---------------------------------------------------------------------------- +| The format of an 80-bit extended floating-point number in memory. This +| structure must contain a 16-bit field named 'signExp' and a 64-bit field +| named 'signif'. +*----------------------------------------------------------------------------*/ + +struct extFloat80M { + uint64_t signif; + uint16_t signExp; +}; + +/*---------------------------------------------------------------------------- +| The type used to pass 80-bit extended floating-point arguments and +| results to/from functions. This type must have size identical to +| 'struct extFloat80M'. Type 'extFloat80_t' can be defined as an alias for +| 'struct extFloat80M'. Alternatively, if a platform has "native" support +| for IEEE-Standard 80-bit extended floating-point, it may be possible, +| if desired, to define 'extFloat80_t' as an alias for the native type +| (presumably either 'long double' or a nonstandard compiler-intrinsic type). +| In that case, the 'signif' and 'signExp' fields of 'struct extFloat80M' +| must align exactly with the locations in memory of the sign, exponent, and +| significand of the native type. +*----------------------------------------------------------------------------*/ +typedef struct extFloat80M extFloat80_t, floatx80; + +#endif diff --git a/src/cpu/softfloat3e/specialize.h b/src/cpu/softfloat3e/specialize.h new file mode 100644 index 000000000..90d4a2caa --- /dev/null +++ b/src/cpu/softfloat3e/specialize.h @@ -0,0 +1,280 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2018 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef _SPECIALIZE_H_ +#define _SPECIALIZE_H_ + +#include +#include +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 32-bit integer formats that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui32_fromPosOverflow 0xFFFFFFFF +#define ui32_fromNegOverflow 0xFFFFFFFF +#define ui32_fromNaN 0xFFFFFFFF +#define i32_fromPosOverflow (-0x7FFFFFFF - 1) +#define i32_fromNegOverflow (-0x7FFFFFFF - 1) +#define i32_fromNaN (-0x7FFFFFFF - 1) + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 64-bit integer formats that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF) +#define ui64_fromNegOverflow UINT64_C(0xFFFFFFFFFFFFFFFF) +#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF) +#define i64_fromPosOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1) +#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1) +#define i64_fromNaN (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1) + +/*---------------------------------------------------------------------------- +| "Common NaN" structure, used to transfer NaN representations from one format +| to another. +*----------------------------------------------------------------------------*/ +struct commonNaN { + bool sign; + uint64_t v0, v64; +}; + + +#ifdef __cplusplus +extern "C" { +#endif +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 16-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF16UI 0xFE00 + +/*---------------------------------------------------------------------------- +| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a +| 16-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF16UI(uiA) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) + +/*---------------------------------------------------------------------------- +| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f16UIToCommonNaN(uint16_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint16_t softfloat_commonNaNToF16UI(const struct commonNaN *aPtr); + +/*---------------------------------------------------------------------------- +| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint16_t + softfloat_propagateNaNF16UI(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 32-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF32UI 0xFFC00000 + +/*---------------------------------------------------------------------------- +| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a +| 32-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF32UI(uiA) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) + +/*---------------------------------------------------------------------------- +| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f32UIToCommonNaN(uint32_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint32_t softfloat_commonNaNToF32UI(const struct commonNaN *aPtr); + +/*---------------------------------------------------------------------------- +| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint32_t + softfloat_propagateNaNF32UI(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 64-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF64UI UINT64_C(0xFFF8000000000000) + +/*---------------------------------------------------------------------------- +| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a +| 64-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF64UI(uiA) ((((uiA) & UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA) & UINT64_C(0x0007FFFFFFFFFFFF))) + +/*---------------------------------------------------------------------------- +| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f64UIToCommonNaN(uint64_t uiA, struct commonNaN *zPtr, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +uint64_t softfloat_commonNaNToF64UI(const struct commonNaN *aPtr); + +/*---------------------------------------------------------------------------- +| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint64_t + softfloat_propagateNaNF64UI(uint64_t uiA, uint64_t uiB, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 80-bit extended floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNExtF80UI64 0xFFFF +#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000) + +/*---------------------------------------------------------------------------- +| Returns true when the 80-bit unsigned integer formed from concatenating +| 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended +| floating-point signaling NaN. +| Note: This macro evaluates its arguments more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C(0x4000000000000000)) && ((uiA0) & UINT64_C(0x3FFFFFFFFFFFFFFF))) + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' +| has the bit pattern of an 80-bit extended floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +void softfloat_extF80UIToCommonNaN(uint16_t uiA64, uint64_t uiA0, struct commonNaN *zPtr, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended +| floating-point NaN, and returns the bit pattern of this value as an unsigned +| integer. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN *aPtr); + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating 'uiA64' and +| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting +| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another +| 80-bit extended floating-point value, and assuming at least on of these +| floating-point values is a NaN, returns the bit pattern of the combined NaN +| result. If either original floating-point value is a signaling NaN, the +| invalid exception is raised. +*----------------------------------------------------------------------------*/ +extFloat80_t + softfloat_propagateNaNExtF80UI( + uint16_t uiA64, + uint64_t uiA0, + uint16_t uiB64, + uint64_t uiB0, + struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 128-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000) +#define defaultNaNF128UI0 UINT64_C(0) + +/*---------------------------------------------------------------------------- +| Returns true when the 128-bit unsigned integer formed from concatenating +| 64-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of a 128-bit floating- +| point signaling NaN. +| Note: This macro evaluates its arguments more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF128UI(uiA64, uiA0) ((((uiA64) & UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64) & UINT64_C(0x00007FFFFFFFFFFF)))) + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' +| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to +| the common NaN form, and stores the resulting common NaN at the location +| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception +| is raised. +*----------------------------------------------------------------------------*/ +void softfloat_f128UIToCommonNaN(uint64_t uiA64, uint64_t uiA0, struct commonNaN *zPtr, struct softfloat_status_t *status); + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN *); + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating 'uiA64' and +| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the +| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another +| 128-bit floating-point value, and assuming at least on of these floating- +| point values is a NaN, returns the bit pattern of the combined NaN result. +| If either original floating-point value is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_propagateNaNF128UI( + uint64_t uiA64, + uint64_t uiA0, + uint64_t uiB64, + uint64_t uiB0, + struct softfloat_status_t *status +); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpu/softfloat3e/ui32_to_extF80.cc b/src/cpu/softfloat3e/ui32_to_extF80.cc new file mode 100644 index 000000000..80c6d86b0 --- /dev/null +++ b/src/cpu/softfloat3e/ui32_to_extF80.cc @@ -0,0 +1,56 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +extFloat80_t ui32_to_extF80(uint32_t a) +{ + uint16_t uiZ64; + int8_t shiftDist; + extFloat80_t z; + + uiZ64 = 0; + if (a) { + shiftDist = softfloat_countLeadingZeros32(a); + uiZ64 = 0x401E - shiftDist; + a <<= shiftDist; + } + z.signExp = uiZ64; + z.signif = (uint64_t) a<<32; + return z; +} diff --git a/src/cpu/softfloat3e/ui32_to_f128.cc b/src/cpu/softfloat3e/ui32_to_f128.cc new file mode 100644 index 000000000..6ef8214a8 --- /dev/null +++ b/src/cpu/softfloat3e/ui32_to_f128.cc @@ -0,0 +1,55 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float128_t ui32_to_f128(uint32_t a) +{ + uint64_t uiZ64; + int8_t shiftDist; + float128_t z; + + uiZ64 = 0; + if (a) { + shiftDist = softfloat_countLeadingZeros32(a) + 17; + uiZ64 = packToF128UI64(0, 0x402E - shiftDist, (uint64_t) a< +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float16 ui32_to_f16(uint32_t a, struct softfloat_status_t *status) +{ + int8_t shiftDist; + uint16_t sig; + + shiftDist = softfloat_countLeadingZeros32(a) - 21; + if (0 <= shiftDist) { + return a ? packToF16UI(0, 0x18 - shiftDist, (uint16_t) a<>(-shiftDist) | ((uint32_t) (a<<(shiftDist & 31)) != 0) + : (uint16_t) a< +#include "internals.h" +#include "softfloat.h" + +float32 ui32_to_f32(uint32_t a, struct softfloat_status_t *status) +{ + if (! a) { + return 0; + } + if (a & 0x80000000) { + return softfloat_roundPackToF32(0, 0x9D, a>>1 | (a & 1), status); + } else { + return softfloat_normRoundPackToF32(0, 0x9C, a, status); + } +} diff --git a/src/cpu/softfloat3e/ui32_to_f64.c b/src/cpu/softfloat3e/ui32_to_f64.c new file mode 100644 index 000000000..524d64eed --- /dev/null +++ b/src/cpu/softfloat3e/ui32_to_f64.c @@ -0,0 +1,49 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float64 ui32_to_f64(uint32_t a) +{ + if (! a) { + return 0; + } else { + int8_t shiftDist = softfloat_countLeadingZeros32(a) + 21; + return packToF64UI(0, 0x432 - shiftDist, (uint64_t) a< +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +extFloat80_t ui64_to_extF80(uint64_t a) +{ + uint16_t uiZ64; + int8_t shiftDist; + extFloat80_t z; + + uiZ64 = 0; + if (a) { + shiftDist = softfloat_countLeadingZeros64(a); + uiZ64 = 0x403E - shiftDist; + a <<= shiftDist; + } + z.signExp = uiZ64; + z.signif = a; + return z; +} diff --git a/src/cpu/softfloat3e/ui64_to_f128.cc b/src/cpu/softfloat3e/ui64_to_f128.cc new file mode 100644 index 000000000..91be29f37 --- /dev/null +++ b/src/cpu/softfloat3e/ui64_to_f128.cc @@ -0,0 +1,65 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float128_t ui64_to_f128(uint64_t a) +{ + uint64_t uiZ64, uiZ0; + int8_t shiftDist; + struct uint128 zSig; + float128_t z; + + if (! a) { + uiZ64 = 0; + uiZ0 = 0; + } else { + shiftDist = softfloat_countLeadingZeros64(a) + 49; + if (64 <= shiftDist) { + zSig.v64 = a<<(shiftDist - 64); + zSig.v0 = 0; + } else { + zSig = softfloat_shortShiftLeft128(0, a, shiftDist); + } + uiZ64 = packToF128UI64(0, 0x406E - shiftDist, zSig.v64); + uiZ0 = zSig.v0; + } + z.v64 = uiZ64; + z.v0 = uiZ0; + return z; +} diff --git a/src/cpu/softfloat3e/ui64_to_f16.c b/src/cpu/softfloat3e/ui64_to_f16.c new file mode 100644 index 000000000..f2339e905 --- /dev/null +++ b/src/cpu/softfloat3e/ui64_to_f16.c @@ -0,0 +1,55 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float16 ui64_to_f16(uint64_t a, struct softfloat_status_t *status) +{ + int8_t shiftDist; + uint16_t sig; + + shiftDist = softfloat_countLeadingZeros64(a) - 53; + if (0 <= shiftDist) { + return a ? packToF16UI(0, 0x18 - shiftDist, (uint16_t) a< +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float32 ui64_to_f32(uint64_t a, struct softfloat_status_t *status) +{ + int8_t shiftDist; + uint32_t sig; + + shiftDist = softfloat_countLeadingZeros64(a) - 40; + if (0 <= shiftDist) { + return a ? packToF32UI(0, 0x95 - shiftDist, (uint32_t) a< +#include "internals.h" +#include "primitives.h" +#include "softfloat.h" + +float64 ui64_to_f64(uint64_t a, struct softfloat_status_t *status) +{ + if (! a) { + return 0; + } + if (a & UINT64_C(0x8000000000000000)) { + return softfloat_roundPackToF64(0, 0x43D, softfloat_shortShiftRightJam64(a, 1), status); + } else { + return softfloat_normRoundPackToF64(0, 0x43C, a, status); + } +} diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 6fb9b7a22..86f54ee3b 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -434,9 +434,9 @@ extern const OpFn ops_2386_REPE[1024]; extern const OpFn ops_2386_REPNE[1024]; extern const OpFn ops_2386_3DNOW[256]; -#define C0 (1 << 8) -#define C1 (1 << 9) -#define C2 (1 << 10) -#define C3 (1 << 14) +#define FPU_SW_C3 (0x4000) /* condition bit 3 */ +#define FPU_SW_C2 (0x0400) /* condition bit 2 */ +#define FPU_SW_C1 (0x0200) /* condition bit 1 */ +#define FPU_SW_C0 (0x0100) /* condition bit 0 */ #endif /*_X86_OPS_H*/ diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index 849e24e3d..9ea04b447 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -4,6 +4,7 @@ static int opESCAPE_d8_a16(uint32_t fetchdat) { + //pclog("D8 A16: fetchdat=%02x.\n", (fetchdat >> 3) & 0x1f); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int @@ -15,6 +16,7 @@ opESCAPE_d8_a32(uint32_t fetchdat) static int opESCAPE_d9_a16(uint32_t fetchdat) { + //pclog("D9 A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } static int @@ -26,6 +28,7 @@ opESCAPE_d9_a32(uint32_t fetchdat) static int opESCAPE_da_a16(uint32_t fetchdat) { + //pclog("DA A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } static int @@ -37,6 +40,7 @@ opESCAPE_da_a32(uint32_t fetchdat) static int opESCAPE_db_a16(uint32_t fetchdat) { + //pclog("DB A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } static int @@ -48,6 +52,7 @@ opESCAPE_db_a32(uint32_t fetchdat) static int opESCAPE_dc_a16(uint32_t fetchdat) { + //pclog("DC A16: fetchdat=%02x.\n", (fetchdat >> 3) & 0x1f); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int @@ -59,6 +64,7 @@ opESCAPE_dc_a32(uint32_t fetchdat) static int opESCAPE_dd_a16(uint32_t fetchdat) { + //pclog("DD A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } static int @@ -70,6 +76,7 @@ opESCAPE_dd_a32(uint32_t fetchdat) static int opESCAPE_de_a16(uint32_t fetchdat) { + //pclog("DE A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } static int @@ -81,6 +88,7 @@ opESCAPE_de_a32(uint32_t fetchdat) static int opESCAPE_df_a16(uint32_t fetchdat) { + //pclog("DF A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } static int diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index ab9d02d25..5e5dc3c7c 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -100,8 +100,8 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) /* load i387 register file */ for (index = 0; index < 8; index++) { - reg.fraction = readmemq(easeg, cpu_state.eaaddr + (index * 16) + 32); - reg.exp = readmemw(easeg, cpu_state.eaaddr + (index * 16) + 40); + reg.signif = readmemq(easeg, cpu_state.eaaddr + (index * 16) + 32); + reg.signExp = readmemw(easeg, cpu_state.eaaddr + (index * 16) + 40); // update tag only if it is not empty FPU_save_regi_tag(reg, IS_TAG_EMPTY(index) ? X87_TAG_EMPTY : FPU_tagof(reg), index); @@ -159,8 +159,8 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) for (index = 0; index < 8; index++) { const floatx80 fp = FPU_read_regi(index); - writememq(easeg, cpu_state.eaaddr + (index * 16) + 32, fp.fraction); - writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.exp); + writememq(easeg, cpu_state.eaaddr + (index * 16) + 32, fp.signif); + writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.signExp); } CLOCK_CYCLES((cr0 & 1) ? 56 : 67); diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c index f26c903f9..55fc987c2 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -33,7 +33,7 @@ uint16_t *MMEP[8]; static uint16_t MME[8]; -#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) +#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].signif) : &(cpu_state.MM[r]) void mmx_init(void) { @@ -41,8 +41,8 @@ mmx_init(void) for (uint8_t i = 0; i < 8; i++) { if (fpu_softfloat) { - MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; - MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp; + MMP[i] = (MMX_REG *) &fpu_state.st_space[i].signif; + MMEP[i] = (uint16_t *) &fpu_state.st_space[i].signExp; } else { MMP[i] = &(cpu_state.MM[i]); MMEP[i] = &(MME[i]); diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 1f7643453..980431f15 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -16,7 +16,9 @@ #include "x86seg_common.h" #include "x87.h" #include "386_common.h" -#include "softfloat/softfloat-specialize.h" +#include "softfloat3e/config.h" +#include "softfloat3e/fpu_trans.h" +#include "softfloat3e/specialize.h" uint32_t x87_pc_off; uint32_t x87_op_off; @@ -106,24 +108,24 @@ x87_settag(uint16_t new_tag) } #endif -static floatx80 -FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct float_status_t *status) +static extFloat80_t +FPU_handle_NaN32_Func(extFloat80_t a, int aIsNaN, float32 b32, int bIsNaN, struct softfloat_status_t *status) { - int aIsSignalingNaN = floatx80_is_signaling_nan(a); - int bIsSignalingNaN = float32_is_signaling_nan(b32); + int aIsSignalingNaN = extF80_isSignalingNaN(a); + int bIsSignalingNaN = f32_isSignalingNaN(b32); if (aIsSignalingNaN | bIsSignalingNaN) - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(status, softfloat_flag_invalid); // propagate QNaN to SNaN - a = propagateFloatx80NaNOne(a, status); + a = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, 0, 0, status); if (aIsNaN & !bIsNaN) return a; // float32 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags - floatx80 b = float32_to_floatx80(b32, status); + extFloat80_t b = f32_to_extF80(b32, status); if (aIsSignalingNaN) { if (bIsSignalingNaN) @@ -133,29 +135,33 @@ FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct fl if (bIsSignalingNaN) return a; returnLargerSignificand: - if (a.fraction < b.fraction) + if (a.signif < b.signif) return b; - if (b.fraction < a.fraction) + if (b.signif < a.signif) return a; - return (a.exp < b.exp) ? a : b; + return (a.signExp < b.signExp) ? a : b; } else { return b; } } int -FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status) +FPU_handle_NaN32(extFloat80_t a, float32 b, extFloat80_t *r, struct softfloat_status_t *status) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); *r = floatx80_default_nan; return 1; } - int aIsNaN = floatx80_is_nan(a); - int bIsNaN = float32_is_nan(b); + int aIsNaN = extF80_isNaN(a); + int bIsNaN = f32_isNaN(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN32_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -163,24 +169,24 @@ FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *stat return 0; } -static floatx80 -FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct float_status_t *status) +static extFloat80_t +FPU_handle_NaN64_Func(extFloat80_t a, int aIsNaN, float64 b64, int bIsNaN, struct softfloat_status_t *status) { - int aIsSignalingNaN = floatx80_is_signaling_nan(a); - int bIsSignalingNaN = float64_is_signaling_nan(b64); + int aIsSignalingNaN = extF80_isSignalingNaN(a); + int bIsSignalingNaN = f64_isSignalingNaN(b64); if (aIsSignalingNaN | bIsSignalingNaN) - float_raise(status, float_flag_invalid); + softfloat_raiseFlags(status, softfloat_flag_invalid); // propagate QNaN to SNaN - a = propagateFloatx80NaNOne(a, status); + a = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, 0, 0, status); if (aIsNaN & !bIsNaN) return a; // float64 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags - floatx80 b = float64_to_floatx80(b64, status); + extFloat80_t b = f64_to_extF80(b64, status); if (aIsSignalingNaN) { if (bIsSignalingNaN) @@ -190,29 +196,33 @@ FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct fl if (bIsSignalingNaN) return a; returnLargerSignificand: - if (a.fraction < b.fraction) + if (a.signif < b.signif) return b; - if (b.fraction < a.fraction) + if (b.signif < a.signif) return a; - return (a.exp < b.exp) ? a : b; + return (a.signExp < b.signExp) ? a : b; } else { return b; } } int -FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status) +FPU_handle_NaN64(extFloat80_t a, float64 b, extFloat80_t *r, struct softfloat_status_t *status) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ + const extFloat80_t floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); + if (extF80_isUnsupported(a)) { + softfloat_raiseFlags(status, softfloat_flag_invalid); *r = floatx80_default_nan; return 1; } - int aIsNaN = floatx80_is_nan(a); - int bIsNaN = float64_is_nan(b); + int aIsNaN = extF80_isNaN(a); + int bIsNaN = f64_isNaN(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN64_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -220,37 +230,36 @@ FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *stat return 0; } -struct float_status_t +struct softfloat_status_t i387cw_to_softfloat_status_word(uint16_t control_word) { - struct float_status_t status; + struct softfloat_status_t status; int precision = control_word & FPU_CW_PC; switch (precision) { case FPU_PR_32_BITS: - status.float_rounding_precision = 32; + status.extF80_roundingPrecision = 32; break; case FPU_PR_64_BITS: - status.float_rounding_precision = 64; + status.extF80_roundingPrecision = 64; break; case FPU_PR_80_BITS: - status.float_rounding_precision = 80; + status.extF80_roundingPrecision = 80; break; default: /* With the precision control bits set to 01 "(reserved)", a real CPU behaves as if the precision control bits were set to 11 "80 bits" */ - status.float_rounding_precision = 80; + status.extF80_roundingPrecision = 80; break; } - status.float_exception_flags = 0; // clear exceptions before execution - status.float_nan_handling_mode = float_first_operand_nan; - status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10; - status.flush_underflow_to_zero = 0; - status.float_suppress_exception = 0; - status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask; - status.denormals_are_zeros = 0; + status.softfloat_exceptionFlags = 0; // clear exceptions before execution + status.softfloat_roundingMode = (control_word & FPU_CW_RC) >> 10; + status.softfloat_flush_underflow_to_zero = 0; + status.softfloat_suppressException = 0; + status.softfloat_exceptionMasks = control_word & FPU_CW_Exceptions_Mask; + status.softfloat_denormals_are_zeros = 0; return status; } @@ -258,17 +267,20 @@ int FPU_status_word_flags_fpu_compare(int float_relation) { switch (float_relation) { - case float_relation_unordered: - return (C0 | C2 | C3); + case softfloat_relation_unordered: + return (FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); - case float_relation_greater: + case softfloat_relation_greater: return 0; - case float_relation_less: - return C0; + case softfloat_relation_less: + return FPU_SW_C0; - case float_relation_equal: - return C3; + case softfloat_relation_equal: + return FPU_SW_C3; + + default: + break; } return (-1); // should never get here @@ -278,18 +290,18 @@ void FPU_write_eflags_fpu_compare(int float_relation) { switch (float_relation) { - case float_relation_unordered: + case softfloat_relation_unordered: cpu_state.flags |= (Z_FLAG | P_FLAG | C_FLAG); break; - case float_relation_greater: + case softfloat_relation_greater: break; - case float_relation_less: + case softfloat_relation_less: cpu_state.flags |= C_FLAG; break; - case float_relation_equal: + case softfloat_relation_equal: cpu_state.flags |= Z_FLAG; break; @@ -324,10 +336,10 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) // FPU_EX_Invalid cannot come with any other exception but x87 stack fault fpu_state.swd |= exceptions; if (exceptions & FPU_SW_Stack_Fault) { - if (!(exceptions & C1)) { + if (!(exceptions & FPU_SW_C1)) { /* This bit distinguishes over- from underflow for a stack fault, and roundup from round-down for precision loss. */ - fpu_state.swd &= ~C1; + fpu_state.swd &= ~FPU_SW_C1; } } return unmasked; @@ -359,10 +371,10 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) fpu_state.swd |= exceptions; if (exceptions & FPU_EX_Precision) { - if (!(exceptions & C1)) { + if (!(exceptions & FPU_SW_C1)) { /* This bit distinguishes over- from underflow for a stack fault, and roundup from round-down for precision loss. */ - fpu_state.swd &= ~C1; + fpu_state.swd &= ~FPU_SW_C1; } } @@ -380,7 +392,7 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) if (!store) unmasked &= ~(FPU_EX_Underflow | FPU_EX_Overflow); else { - fpu_state.swd &= ~C1; + fpu_state.swd &= ~FPU_SW_C1; if (!(status & FPU_EX_Precision)) fpu_state.swd &= ~FPU_EX_Precision; } @@ -391,7 +403,11 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) void FPU_stack_overflow(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); /* The masked response */ if (is_IA_masked()) { @@ -404,7 +420,11 @@ FPU_stack_overflow(uint32_t fetchdat) void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ + const floatx80 floatx80_default_nan = + packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); /* The masked response */ if (is_IA_masked()) { @@ -420,11 +440,11 @@ FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack) * rather than a kernel (ported by Kevin Lawton) * ------------------------------------------------------------ */ int -FPU_tagof(const floatx80 reg) +FPU_tagof(const extFloat80_t reg) { - int32_t exp = floatx80_exp(reg); + int32_t exp = extF80_exp(reg); if (exp == 0) { - if (!floatx80_fraction(reg)) + if (!extF80_fraction(reg)) return X87_TAG_ZERO; /* The number is a de-normal or pseudodenormal. */ @@ -436,7 +456,7 @@ FPU_tagof(const floatx80 reg) return X87_TAG_INVALID; } - if (!(reg.fraction & BX_CONST64(0x8000000000000000))) { + if (!(reg.signif & BX_CONST64(0x8000000000000000))) { /* Unsupported data type. */ /* Valid numbers have the ms bit set to 1. */ return X87_TAG_INVALID; @@ -516,12 +536,10 @@ unpack_FPU_TW(uint16_t tag_byte) */ for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) { - if (tag_byte & 0x80) { - const floatx80 *fpu_reg = &fpu_state.st_space[index & 7]; - twd |= FPU_tagof(*fpu_reg); - } else { + if (tag_byte & 0x80) + twd |= FPU_tagof(fpu_state.st_space[index & 7]); + else twd |= X87_TAG_EMPTY; - } } return (twd >> 2); diff --git a/src/cpu/x87.h b/src/cpu/x87.h index f4e24f1ca..197e18bfe 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -60,89 +60,80 @@ void x87_settag(uint16_t new_tag); void codegen_set_rounding_mode(int mode); /* Status Word */ -#define FPU_SW_Backward (0x8000) /* backward compatibility */ -#define FPU_SW_C3 (0x4000) /* condition bit 3 */ -#define FPU_SW_Top (0x3800) /* top of stack */ -#define FPU_SW_C2 (0x0400) /* condition bit 2 */ -#define FPU_SW_C1 (0x0200) /* condition bit 1 */ -#define FPU_SW_C0 (0x0100) /* condition bit 0 */ -#define FPU_SW_Summary (0x0080) /* exception summary */ -#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ -#define FPU_SW_Precision (0x0020) /* loss of precision */ -#define FPU_SW_Underflow (0x0010) /* underflow */ -#define FPU_SW_Overflow (0x0008) /* overflow */ -#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ -#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ -#define FPU_SW_Invalid (0x0001) /* invalid operation */ +#define FPU_SW_Backward (0x8000) /* backward compatibility */ +#define FPU_SW_C3 (0x4000) /* condition bit 3 */ +#define FPU_SW_Top (0x3800) /* top of stack */ +#define FPU_SW_C2 (0x0400) /* condition bit 2 */ +#define FPU_SW_C1 (0x0200) /* condition bit 1 */ +#define FPU_SW_C0 (0x0100) /* condition bit 0 */ +#define FPU_SW_Summary (0x0080) /* exception summary */ +#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ +#define FPU_SW_Precision (0x0020) /* loss of precision */ +#define FPU_SW_Underflow (0x0010) /* underflow */ +#define FPU_SW_Overflow (0x0008) /* overflow */ +#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ +#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ +#define FPU_SW_Invalid (0x0001) /* invalid operation */ -#define C0 (1 << 8) -#define C1 (1 << 9) -#define C2 (1 << 10) -#define C3 (1 << 14) +#define FPU_SW_CC (FPU_SW_C0|FPU_SW_C1|FPU_SW_C2|FPU_SW_C3) -#define FPU_SW_CC (C0 | C1 | C2 | C3) - -#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ +#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ /* Exception flags: */ -#define FPU_EX_Precision (0x0020) /* loss of precision */ -#define FPU_EX_Underflow (0x0010) /* underflow */ -#define FPU_EX_Overflow (0x0008) /* overflow */ -#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ -#define FPU_EX_Denormal (0x0002) /* denormalized operand */ -#define FPU_EX_Invalid (0x0001) /* invalid operation */ +#define FPU_EX_Precision (0x0020) /* loss of precision */ +#define FPU_EX_Underflow (0x0010) /* underflow */ +#define FPU_EX_Overflow (0x0008) /* overflow */ +#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ +#define FPU_EX_Denormal (0x0002) /* denormalized operand */ +#define FPU_EX_Invalid (0x0001) /* invalid operation */ /* Special exceptions: */ -#define FPU_EX_Stack_Overflow (0x0041 | C1) /* stack overflow */ -#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ +#define FPU_EX_Stack_Overflow (0x0041|FPU_SW_C1) /* stack overflow */ +#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ /* precision control */ -#define FPU_EX_Precision_Lost_Up (EX_Precision | C1) -#define FPU_EX_Precision_Lost_Dn (EX_Precision) +#define FPU_EX_Precision_Lost_Up (EX_Precision | SW_C1) +#define FPU_EX_Precision_Lost_Dn (EX_Precision) -#define setcc(cc) \ - fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) &FPU_SW_CC) +#define setcc(cc) \ + fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) & FPU_SW_CC) -#define clear_C1() \ - { \ - fpu_state.swd &= ~C1; \ - } -#define clear_C2() \ - { \ - fpu_state.swd &= ~C2; \ - } +#define clear_C1() { fpu_state.swd &= ~FPU_SW_C1; } +#define clear_C2() { fpu_state.swd &= ~FPU_SW_C2; } /* ************ */ /* Control Word */ /* ************ */ -#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ +#define FPU_CW_Reserved_Bits (0xe0c0) /* reserved bits */ -#define FPU_CW_RC (0x0C00) /* rounding control */ -#define FPU_CW_PC (0x0300) /* precision control */ +#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ -#define FPU_RC_RND (0x0000) /* rounding control */ -#define FPU_RC_DOWN (0x0400) -#define FPU_RC_UP (0x0800) -#define FPU_RC_CHOP (0x0C00) +#define FPU_CW_RC (0x0C00) /* rounding control */ +#define FPU_CW_PC (0x0300) /* precision control */ -#define FPU_CW_Precision (0x0020) /* loss of precision mask */ -#define FPU_CW_Underflow (0x0010) /* underflow mask */ -#define FPU_CW_Overflow (0x0008) /* overflow mask */ -#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ -#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ -#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ +#define FPU_RC_RND (0x0000) /* rounding control */ +#define FPU_RC_DOWN (0x0400) +#define FPU_RC_UP (0x0800) +#define FPU_RC_CHOP (0x0C00) -#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ +#define FPU_CW_Precision (0x0020) /* loss of precision mask */ +#define FPU_CW_Underflow (0x0010) /* underflow mask */ +#define FPU_CW_Overflow (0x0008) /* overflow mask */ +#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ +#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ +#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ + +#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ /* Precision control bits affect only the following: ADD, SUB(R), MUL, DIV(R), and SQRT */ -#define FPU_PR_32_BITS (0x000) -#define FPU_PR_RESERVED_BITS (0x100) -#define FPU_PR_64_BITS (0x200) -#define FPU_PR_80_BITS (0x300) +#define FPU_PR_32_BITS (0x000) +#define FPU_PR_RESERVED_BITS (0x100) +#define FPU_PR_64_BITS (0x200) +#define FPU_PR_80_BITS (0x300) -#include "softfloat/softfloatx80.h" +#include "softfloat3e/softfloat.h" static __inline int is_IA_masked(void) @@ -150,15 +141,15 @@ is_IA_masked(void) return (fpu_state.cwd & FPU_CW_Invalid); } -struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word); +struct softfloat_status_t i387cw_to_softfloat_status_word(uint16_t control_word); uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store); int FPU_status_word_flags_fpu_compare(int float_relation); void FPU_write_eflags_fpu_compare(int float_relation); void FPU_stack_overflow(uint32_t fetchdat); void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); -int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); -int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); -int FPU_tagof(const floatx80 reg); +int FPU_handle_NaN32(extFloat80_t a, float32 b, extFloat80_t *r, struct softfloat_status_t *status); +int FPU_handle_NaN64(extFloat80_t a, float64 b, extFloat80_t *r, struct softfloat_status_t *status); +int FPU_tagof(const extFloat80_t reg); uint8_t pack_FPU_TW(uint16_t twd); uint16_t unpack_FPU_TW(uint16_t tag_byte); @@ -207,11 +198,11 @@ FPU_push(void) static __inline void FPU_pop(void) { - fpu_state.tag |= 3 << (fpu_state.tos * 2); + fpu_state.tag |= (3 << (fpu_state.tos * 2)); fpu_state.tos = (fpu_state.tos + 1) & 7; } -static __inline floatx80 +static __inline extFloat80_t FPU_read_regi(int stnr) { return fpu_state.st_space[(stnr + fpu_state.tos) & 7]; @@ -221,14 +212,14 @@ FPU_read_regi(int stnr) // instructions like FNSAVE, and they update tag word to its // real value anyway static __inline void -FPU_save_regi(floatx80 reg, int stnr) +FPU_save_regi(extFloat80_t reg, int stnr) { fpu_state.st_space[(stnr + fpu_state.tos) & 7] = reg; FPU_settagi_valid(stnr); } static __inline void -FPU_save_regi_tag(floatx80 reg, int tag, int stnr) +FPU_save_regi_tag(extFloat80_t reg, int tag, int stnr) { fpu_state.st_space[(stnr + fpu_state.tos) & 7] = reg; FPU_settagi(tag, stnr); @@ -237,6 +228,7 @@ FPU_save_regi_tag(floatx80 reg, int tag, int stnr) #define FPU_check_pending_exceptions() \ do { \ if (fpu_state.swd & FPU_SW_Summary) { \ + pclog("SW Summary.\n"); \ if (cr0 & 0x20) { \ x86_int(16); \ return 1; \ diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index aef9289e7..6be9d7648 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -40,17 +40,17 @@ static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARD #define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] -#define C0 (1 << 8) -#define C1 (1 << 9) -#define C2 (1 << 10) -#define C3 (1 << 14) +#define FPU_SW_C3 (0x4000) /* condition bit 3 */ +#define FPU_SW_C2 (0x0400) /* condition bit 2 */ +#define FPU_SW_C1 (0x0200) /* condition bit 1 */ +#define FPU_SW_C0 (0x0100) /* condition bit 0 */ #define X87_TAG_VALID 0 #define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 -#define STATUS_ZERODIVIDE 4 +#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ typedef union { double d; @@ -76,8 +76,8 @@ typedef union { # define x87_div(dst, src1, src2) \ do { \ if (((double) src2) == 0.0) { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + cpu_state.npxs |= FPU_SW_Zero_Div; \ + if (cpu_state.npxc & FPU_SW_Zero_Div) \ dst = src1 / (double) src2; \ else { \ fpu_log("FPU : divide by zero\n"); \ @@ -94,8 +94,8 @@ typedef union { # define x87_div(dst, src1, src2) \ do { \ if (((double) src2) == 0.0) { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + cpu_state.npxs |= FPU_SW_Zero_Div; \ + if (cpu_state.npxc & FPU_SW_Zero_Div) \ dst = src1 / (double) src2; \ else { \ fpu_log("FPU : divide by zero\n"); \ @@ -107,12 +107,6 @@ typedef union { } while (0) #endif -static __inline void -x87_checkexceptions(void) -{ - // -} - static __inline void x87_push(double i) { @@ -366,7 +360,7 @@ x87_compare(double a, double b) /* Hack to make CHKCOP happy. */ if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) - return C3; + return FPU_SW_C3; if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) eb = ea; @@ -399,7 +393,7 @@ x87_compare(double a, double b) } # endif - return result & (C0 | C2 | C3); + return result & (FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); #else /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ @@ -410,9 +404,9 @@ x87_compare(double a, double b) eb = ea; if (ea == eb) - result |= C3; + result |= FPU_SW_C3; else if (ea < eb) - result |= C0; + result |= FPU_SW_C0; return result; #endif @@ -452,16 +446,16 @@ x87_ucompare(double a, double b) } # endif - return result & (C0 | C2 | C3); + return result & (FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); #else /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ uint32_t result = 0; if (a == b) - result |= C3; + result |= FPU_SW_C3; else if (a < b) - result |= C0; + result |= FPU_SW_C0; return result; #endif @@ -503,7 +497,8 @@ typedef union { # define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 #endif -#include "softfloat/softfloat-specialize.h" +#include "softfloat3e/softfloat-specialize.h" +#include "softfloat3e/fpu_trans.h" #include "x87_ops_sf_arith.h" #include "x87_ops_sf_compare.h" @@ -1093,10 +1088,10 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { const OpFn OP_TABLE(sf_fpu_d8_a16)[32] = { // clang-format off - sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, - sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, - sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, - sf_FADD_st0_stj, sf_FMUL_st0_stj, sf_FCOM_sti, sf_FCOMP_sti, sf_FSUB_st0_stj, sf_FSUBR_st0_stj, sf_FDIV_st0_stj, sf_FDIVR_st0_stj, + /*0x00*/ sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, + /*0x08*/ sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, + /*0x10*/ sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, + /*0x18*/ sf_FADD_st0_stj, sf_FMUL_st0_stj, sf_FCOM_sti, sf_FCOMP_sti, sf_FSUB_st0_stj, sf_FSUBR_st0_stj, sf_FDIV_st0_stj, sf_FDIVR_st0_stj, // clang-format on }; @@ -1191,41 +1186,41 @@ const OpFn OP_TABLE(sf_fpu_287_d9_a32)[256] = { const OpFn OP_TABLE(sf_fpu_d9_a16)[256] = { // clang-format off - sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, - sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, - sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, - sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, - sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, - sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + /*0x00*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x18*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0x20*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0x28*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0x30*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0x38*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, - sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, - sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, - sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, - sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, - sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, - sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + /*0x40*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x58*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0x60*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0x68*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0x70*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0x78*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, - sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, - sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, - sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, - sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, - sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, - sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + /*0x80*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x98*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0xa0*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0xa8*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0xb0*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0xb8*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, - sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, - sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, - sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, /*Invalid*/ - sf_FCHS, sf_FABS, ILLEGAL_a16, ILLEGAL_a16, sf_FTST, sf_FXAM, ILLEGAL_a16, ILLEGAL_a16, - sf_FLD1, sf_FLDL2T, sf_FLDL2E, sf_FLDPI, sf_FLDEG2, sf_FLDLN2, sf_FLDZ, ILLEGAL_a16, - sf_F2XM1, sf_FYL2X, sf_FPTAN, sf_FPATAN, sf_FXTRACT, sf_FPREM1, sf_FDECSTP, sf_FINCSTP, - sf_FPREM, sf_FYL2XP1, sf_FSQRT, sf_FSINCOS, sf_FRNDINT, sf_FSCALE, sf_FSIN, sf_FCOS, + /*0xc0*/ sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, + /*0xc8*/ sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + /*0xd0*/ sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xd8*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, /*Invalid*/ + /*0xe0*/ sf_FCHS, sf_FABS, ILLEGAL_a16, ILLEGAL_a16, sf_FTST, sf_FXAM, ILLEGAL_a16, ILLEGAL_a16, + /*0xe8*/ sf_FLD1, sf_FLDL2T, sf_FLDL2E, sf_FLDPI, sf_FLDEG2, sf_FLDLN2, sf_FLDZ, ILLEGAL_a16, + /*0xf0*/ sf_F2XM1, sf_FYL2X, sf_FPTAN, sf_FPATAN, sf_FXTRACT, sf_FPREM1, sf_FDECSTP, sf_FINCSTP, + /*0xf8*/ sf_FPREM, sf_FYL2XP1, sf_FSQRT, sf_FSINCOS, sf_FRNDINT, sf_FSCALE, sf_FSIN, sf_FCOS, // clang-format on }; @@ -1593,41 +1588,41 @@ const OpFn OP_TABLE(sf_fpu_287_db_a32)[256] = { const OpFn OP_TABLE(sf_fpu_db_a16)[256] = { // clang-format off - sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, - sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + /*0x00*/ sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + /*0x18*/ sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + /*0x20*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x28*/ sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + /*0x30*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x38*/ sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, - sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, - sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + /*0x40*/ sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + /*0x58*/ sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + /*0x60*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x68*/ sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + /*0x70*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x78*/ sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, - sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, - sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + /*0x80*/ sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + /*0x98*/ sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + /*0xa0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xa8*/ sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + /*0xb0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xb8*/ sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FNOP, sf_FNOP, sf_FNCLEX, sf_FNINIT, sf_FNOP, sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xc0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xc8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xd0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xd8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xe0*/ sf_FNOP, sf_FNOP, sf_FNCLEX, sf_FNINIT, sf_FNOP, sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, + /*0xe8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, // clang-format on }; @@ -1870,41 +1865,41 @@ const OpFn OP_TABLE(sf_fpu_287_dd_a32)[256] = { const OpFn OP_TABLE(sf_fpu_dd_a16)[256] = { // clang-format off - sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, - sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, - sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, - sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + /*0x00*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x18*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0x20*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0x28*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x30*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0x38*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, - sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, - sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, - sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, - sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + /*0x40*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x58*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0x60*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0x68*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x70*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0x78*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, - sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, - sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, - sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, - sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + /*0x80*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x98*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0xa0*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0xa8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xb0*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0xb8*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, - sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, - sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, - sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, - sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, - sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, - sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xc0*/ sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, + /*0xc8*/ sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + /*0xd0*/ sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, + /*0xd8*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + /*0xe0*/ sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, + /*0xe8*/ sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, + /*0xf0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, // clang-format on }; @@ -2030,41 +2025,41 @@ const OpFn OP_TABLE(sf_fpu_287_de_a32)[256] = { const OpFn OP_TABLE(sf_fpu_de_a16)[256] = { // clang-format off - sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, - sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, - sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, - sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, - sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, - sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, - sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, - sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, + /*0x00*/ sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, + /*0x08*/ sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, + /*0x10*/ sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, + /*0x18*/ sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, + /*0x20*/ sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, + /*0x28*/ sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, + /*0x30*/ sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, + /*0x38*/ sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, - sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, - sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, - sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, - sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, - sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, - sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, - sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, - sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, + /*0x40*/ sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, + /*0x48*/ sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, + /*0x50*/ sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, + /*0x58*/ sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, + /*0x60*/ sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, + /*0x68*/ sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, + /*0x70*/ sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, + /*0x78*/ sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, - sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, - sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, - sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, - sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, - sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, - sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, - sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, - sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, + /*0x80*/ sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, + /*0x88*/ sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, sf_FMULiw_a16, + /*0x90*/ sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, sf_FCOMiw_a16, + /*0x98*/ sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, sf_FCOMPiw_a16, + /*0xa0*/ sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, sf_FSUBiw_a16, + /*0xa8*/ sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, sf_FSUBRiw_a16, + /*0xb0*/ sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, sf_FDIViw_a16, + /*0xb8*/ sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, sf_FDIVRiw_a16, - sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, - sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, - sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, - ILLEGAL_a16, sf_FCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, - sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, - sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, - sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, + /*0xc0*/ sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, sf_FADDP_sti_st0, + /*0xc8*/ sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, sf_FMULP_sti_st0, + /*0xd0*/ sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, sf_FCOMP_sti, + /*0xd8*/ ILLEGAL_a16, sf_FCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xe0*/ sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, sf_FSUBRP_sti_st0, + /*0xe8*/ sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, sf_FSUBP_sti_st0, + /*0xf0*/ sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, sf_FDIVRP_sti_st0, + /*0xf8*/ sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, sf_FDIVP_sti_st0, // clang-format on }; @@ -2190,41 +2185,41 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { // clang-format off - sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, - sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, - sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, - sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, - sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + /*0x00*/ sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + /*0x18*/ sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + /*0x20*/ sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + /*0x28*/ sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + /*0x30*/ sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + /*0x38*/ sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, - sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, - sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, - sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, - sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, - sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + /*0x40*/ sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + /*0x58*/ sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + /*0x60*/ sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + /*0x68*/ sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + /*0x70*/ sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + /*0x78*/ sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, - sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, - sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, - sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, - sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, - sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + /*0x80*/ sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + /*0x98*/ sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + /*0xa0*/ sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + /*0xa8*/ sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + /*0xb0*/ sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + /*0xb8*/ sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, - sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, - sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, - sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, - sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, - sf_FNSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xc0*/ sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, + /*0xc8*/ sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + /*0xd0*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + /*0xd8*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + /*0xe0*/ sf_FNSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xe8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, // clang-format on }; diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 808a15051..31c26231b 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -27,7 +27,7 @@ load_var = get(); \ if (cpu_state.abrt) \ return 1; \ - cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ @@ -42,7 +42,7 @@ load_var = get(); \ if (cpu_state.abrt) \ return 1; \ - cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ x87_pop(); \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ @@ -128,24 +128,24 @@ // clang-format off opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) #ifndef FPU_8087 - opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) +opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) #endif opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) #ifndef FPU_8087 - opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) +opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) #endif opFPU(iw, uint16_t, 16, t, geteaw, (double) (int16_t) t, _i16) #ifndef FPU_8087 - opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16) +opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16) #endif opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 - opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) +opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif - // clang-format on +// clang-format on - static int opFADD(uint32_t fetchdat) +static int opFADD(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; @@ -184,11 +184,11 @@ opFCOM(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (ST(0) == ST(fetchdat & 7)) - cpu_state.npxs |= C3; + cpu_state.npxs |= FPU_SW_C3; else if (ST(0) < ST(fetchdat & 7)) - cpu_state.npxs |= C0; + cpu_state.npxs |= FPU_SW_C0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; @@ -199,7 +199,7 @@ opFCOMP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); x87_pop(); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); @@ -213,11 +213,11 @@ opFCOMPP(uint32_t fetchdat) uint64_t *p, *q; FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); p = (uint64_t *) &ST(0); q = (uint64_t *) &ST(1); if ((*p == ((uint64_t) 1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) - cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + cpu_state.npxs |= FPU_SW_C0; /*Nasty hack to fix 80387 detection*/ else cpu_state.npxs |= x87_compare(ST(0), ST(1)); @@ -233,7 +233,7 @@ opFUCOMPP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); x87_pop(); x87_pop(); @@ -458,7 +458,7 @@ opFUCOM(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); @@ -470,7 +470,7 @@ opFUCOMP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); x87_pop(); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); @@ -478,7 +478,7 @@ opFUCOMP(uint32_t fetchdat) return 0; } -# ifndef OPS_286_386 +#ifndef OPS_286_386 static int opFUCOMI(uint32_t fetchdat) { diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index d854f83db..d40d70140 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -536,11 +536,11 @@ opFTST(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (ST(0) == 0.0) - cpu_state.npxs |= C3; + cpu_state.npxs |= FPU_SW_C3; else if (ST(0) < 0.0) - cpu_state.npxs |= C0; + cpu_state.npxs |= FPU_SW_C0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); return 0; @@ -551,20 +551,20 @@ opFXAM(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C1 | FPU_SW_C2 | FPU_SW_C3); #ifdef USE_NEW_DYNAREC if (cpu_state.tag[cpu_state.TOP & 7] == TAG_EMPTY) - cpu_state.npxs |= (C0 | C3); + cpu_state.npxs |= (FPU_SW_C0 | FPU_SW_C3); #else if (cpu_state.tag[cpu_state.TOP & 7] == 3) - cpu_state.npxs |= (C0 | C3); + cpu_state.npxs |= (FPU_SW_C0 | FPU_SW_C3); #endif else if (ST(0) == 0.0) - cpu_state.npxs |= C3; + cpu_state.npxs |= FPU_SW_C3; else - cpu_state.npxs |= C2; + cpu_state.npxs |= FPU_SW_C2; if (ST(0) < 0.0) - cpu_state.npxs |= C1; + cpu_state.npxs |= FPU_SW_C1; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); return 0; @@ -694,7 +694,7 @@ opFPTAN(uint32_t fetchdat) ST(0) = tan(ST(0)); FP_TAG_VALID; x87_push(1.0); - cpu_state.npxs &= ~C2; + cpu_state.npxs &= ~FPU_SW_C2; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); return 0; @@ -752,13 +752,13 @@ opFPREM(uint32_t fetchdat) temp64 = (int64_t) (ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double) temp64); FP_TAG_VALID; - cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C1 | FPU_SW_C2 | FPU_SW_C3); if (temp64 & 4) - cpu_state.npxs |= C0; + cpu_state.npxs |= FPU_SW_C0; if (temp64 & 2) - cpu_state.npxs |= C3; + cpu_state.npxs |= FPU_SW_C3; if (temp64 & 1) - cpu_state.npxs |= C1; + cpu_state.npxs |= FPU_SW_C1; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); return 0; @@ -773,13 +773,13 @@ opFPREM1(uint32_t fetchdat) temp64 = (int64_t) (ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double) temp64); FP_TAG_VALID; - cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C1 | FPU_SW_C2 | FPU_SW_C3); if (temp64 & 4) - cpu_state.npxs |= C0; + cpu_state.npxs |= FPU_SW_C0; if (temp64 & 2) - cpu_state.npxs |= C3; + cpu_state.npxs |= FPU_SW_C3; if (temp64 & 1) - cpu_state.npxs |= C1; + cpu_state.npxs |= FPU_SW_C1; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); return 0; @@ -808,7 +808,7 @@ opFSINCOS(uint32_t fetchdat) ST(0) = sin(td); FP_TAG_VALID; x87_push(cos(td)); - cpu_state.npxs &= ~C2; + cpu_state.npxs &= ~FPU_SW_C2; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); return 0; @@ -853,7 +853,7 @@ opFSIN(uint32_t fetchdat) cpu_state.pc++; ST(0) = sin(ST(0)); FP_TAG_VALID; - cpu_state.npxs &= ~C2; + cpu_state.npxs &= ~FPU_SW_C2; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); return 0; @@ -866,7 +866,7 @@ opFCOS(uint32_t fetchdat) cpu_state.pc++; ST(0) = cos(ST(0)); FP_TAG_VALID; - cpu_state.npxs &= ~C2; + cpu_state.npxs &= ~FPU_SW_C2; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); return 0; diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index 137919fa9..ea3715c41 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -240,6 +240,7 @@ sf_FLDCW_a16(uint32_t fetchdat) uint16_t tempw; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); tempw = geteaw(); @@ -265,6 +266,7 @@ sf_FLDCW_a32(uint32_t fetchdat) uint16_t tempw; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); tempw = geteaw(); @@ -375,12 +377,13 @@ sf_FRSTOR_a16(uint32_t fetchdat) int offset; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { - tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.signif = readmemq(easeg, offset + (n * 10)); + tmp.signExp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -395,12 +398,13 @@ sf_FRSTOR_a32(uint32_t fetchdat) int offset; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { - tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.signif = readmemq(easeg, offset + (n * 10)); + tmp.signExp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -422,8 +426,8 @@ sf_FNSAVE_a16(uint32_t fetchdat) /* save all registers in stack order. */ for (int m = 0; m < 8; m++) { stn = FPU_read_regi(m); - writememq(easeg, offset + (m * 10), stn.fraction); - writememw(easeg, offset + (m * 10) + 8, stn.exp); + writememq(easeg, offset + (m * 10), stn.signif); + writememw(easeg, offset + (m * 10) + 8, stn.signExp); } #ifdef FPU_8087 @@ -458,8 +462,8 @@ sf_FNSAVE_a32(uint32_t fetchdat) /* save all registers in stack order. */ for (int m = 0; m < 8; m++) { stn = FPU_read_regi(m); - writememq(easeg, offset + (m * 10), stn.fraction); - writememw(easeg, offset + (m * 10) + 8, stn.exp); + writememq(easeg, offset + (m * 10), stn.signif); + writememw(easeg, offset + (m * 10) + 8, stn.signExp); } # ifdef FPU_8087 @@ -524,6 +528,7 @@ sf_FLDENV_a16(uint32_t fetchdat) int tag; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); fpu_load_environment(); @@ -546,6 +551,7 @@ sf_FLDENV_a32(uint32_t fetchdat) int tag; FP_ENTER(); + FPU_check_pending_exceptions(); fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); fpu_load_environment(); @@ -600,6 +606,8 @@ static int sf_FNOP(uint32_t fetchdat) { FP_ENTER(); + pclog("FNOP.\n"); + FPU_check_pending_exceptions(); cpu_state.pc++; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); diff --git a/src/cpu/x87_ops_sf_arith.h b/src/cpu/x87_ops_sf_arith.h index 5144062bb..edbd64dcf 100644 --- a/src/cpu/x87_ops_sf_arith.h +++ b/src/cpu/x87_ops_sf_arith.h @@ -1,8 +1,8 @@ #define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -19,9 +19,9 @@ status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) \ - result = floatx80_add(a, use_var, &status); \ + result = extF80_add(a, use_var, &status); \ \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -31,8 +31,8 @@ next_ins: } \ static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -49,9 +49,9 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) { \ - result = floatx80_div(a, use_var, &status); \ + result = extF80_div(a, use_var, &status); \ } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -61,8 +61,8 @@ next_ins: } \ static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -79,9 +79,9 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) { \ - result = floatx80_div(use_var, a, &status); \ + result = extF80_div(use_var, a, &status); \ } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -91,8 +91,8 @@ next_ins: } \ static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -109,9 +109,9 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) { \ - result = floatx80_mul(a, use_var, &status); \ + result = extF80_mul(a, use_var, &status); \ } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -121,8 +121,8 @@ next_ins: } \ static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -139,9 +139,9 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) \ - result = floatx80_sub(a, use_var, &status); \ + result = extF80_sub(a, use_var, &status); \ \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -151,8 +151,8 @@ next_ins: } \ static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ + floatx80 a, result; \ + struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ FPU_check_pending_exceptions(); \ @@ -169,9 +169,9 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (!is_nan) \ - result = floatx80_sub(use_var, a, &status); \ + result = extF80_sub(use_var, a, &status); \ \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_save_regi(result, 0); \ \ next_ins: \ @@ -181,31 +181,31 @@ next_ins: } // clang-format off -sf_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32) +sf_FPU(s, float32, 16, temp, geteal(), f32_to_extF80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32) #ifndef FPU_8087 -sf_FPU(s, float32, 32, temp, geteal(), float32_to_floatx80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32) +sf_FPU(s, float32, 32, temp, geteal(), f32_to_extF80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32) #endif -sf_FPU(d, float64, 16, temp, geteaq(), float64_to_floatx80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64) +sf_FPU(d, float64, 16, temp, geteaq(), f64_to_extF80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64) #ifndef FPU_8087 -sf_FPU(d, float64, 32, temp, geteaq(), float64_to_floatx80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64) +sf_FPU(d, float64, 32, temp, geteaq(), f64_to_extF80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64) #endif -sf_FPU(iw, uint16_t, 16, temp, geteaw(), int32_to_floatx80((int16_t)temp), 0, _i16) +sf_FPU(iw, uint16_t, 16, temp, geteaw(), i32_to_extF80((int16_t)temp), 0, _i16) #ifndef FPU_8087 -sf_FPU(iw, uint16_t, 32, temp, geteaw(), int32_to_floatx80((int16_t)temp), 0, _i16) +sf_FPU(iw, uint16_t, 32, temp, geteaw(), i32_to_extF80((int16_t)temp), 0, _i16) #endif -sf_FPU(il, uint32_t, 16, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32) +sf_FPU(il, uint32_t, 16, temp, geteal(), i32_to_extF80((int32_t)temp), 0, _i32) #ifndef FPU_8087 -sf_FPU(il, uint32_t, 32, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32) +sf_FPU(il, uint32_t, 32, temp, geteal(), i32_to_extF80((int32_t)temp), 0, _i32) #endif - // clang-format on +// clang-format on - static int sf_FADD_st0_stj(uint32_t fetchdat) +static int sf_FADD_st0_stj(uint32_t fetchdat) { floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); FPU_check_pending_exceptions(); @@ -218,9 +218,9 @@ sf_FPU(il, uint32_t, 32, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_add(a, b, &status); + result = extF80_add(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, 0); next_ins: @@ -234,7 +234,7 @@ sf_FADD_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); FPU_check_pending_exceptions(); @@ -247,9 +247,9 @@ sf_FADD_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_add(a, b, &status); + result = extF80_add(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, fetchdat & 7); next_ins: @@ -264,7 +264,7 @@ sf_FADDP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); FPU_check_pending_exceptions(); @@ -277,9 +277,9 @@ sf_FADDP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_add(a, b, &status); + result = extF80_add(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -296,9 +296,10 @@ sf_FDIV_st0_stj(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -308,9 +309,9 @@ sf_FDIV_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, 0); next_ins: @@ -325,9 +326,10 @@ sf_FDIV_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -337,9 +339,9 @@ sf_FDIV_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, fetchdat & 7); next_ins: @@ -353,9 +355,10 @@ sf_FDIVP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -365,9 +368,9 @@ sf_FDIVP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -384,9 +387,10 @@ sf_FDIVR_st0_stj(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -396,9 +400,9 @@ sf_FDIVR_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, 0); next_ins: @@ -412,9 +416,10 @@ sf_FDIVR_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -424,9 +429,9 @@ sf_FDIVR_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, fetchdat & 7); next_ins: @@ -440,9 +445,10 @@ sf_FDIVRP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -452,9 +458,9 @@ sf_FDIVRP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_div(a, b, &status); + result = extF80_div(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -471,9 +477,10 @@ sf_FMUL_st0_stj(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -483,9 +490,9 @@ sf_FMUL_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_mul(a, b, &status); + result = extF80_mul(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 0); } @@ -500,9 +507,10 @@ sf_FMUL_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -512,9 +520,9 @@ sf_FMUL_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_mul(a, b, &status); + result = extF80_mul(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); } @@ -529,9 +537,10 @@ sf_FMULP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -541,9 +550,9 @@ sf_FMULP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_mul(a, b, &status); + result = extF80_mul(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -560,9 +569,10 @@ sf_FSUB_st0_stj(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -572,9 +582,9 @@ sf_FSUB_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 0); } @@ -589,9 +599,10 @@ sf_FSUB_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -601,9 +612,9 @@ sf_FSUB_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); } @@ -618,9 +629,10 @@ sf_FSUBP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -630,9 +642,9 @@ sf_FSUBP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -649,9 +661,10 @@ sf_FSUBR_st0_stj(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -661,9 +674,9 @@ sf_FSUBR_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(fetchdat & 7); b = FPU_read_regi(0); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 0); } @@ -678,9 +691,10 @@ sf_FSUBR_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -690,9 +704,9 @@ sf_FSUBR_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); } @@ -707,9 +721,10 @@ sf_FSUBRP_sti_st0(uint32_t fetchdat) floatx80 a; floatx80 b; floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { @@ -719,9 +734,9 @@ sf_FSUBRP_sti_st0(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - result = floatx80_sub(a, b, &status); + result = extF80_sub(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, fetchdat & 7); FPU_pop(); } @@ -736,9 +751,10 @@ static int sf_FSQRT(uint32_t fetchdat) { floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0)) { @@ -746,9 +762,9 @@ sf_FSQRT(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = floatx80_sqrt(FPU_read_regi(0), &status); + result = extF80_sqrt(FPU_read_regi(0), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 0); } @@ -762,9 +778,10 @@ static int sf_FRNDINT(uint32_t fetchdat) { floatx80 result; - struct float_status_t status; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0)) { @@ -772,9 +789,9 @@ sf_FRNDINT(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = floatx80_round_to_int(FPU_read_regi(0), &status); + result = extF80_roundToInt_normal(FPU_read_regi(0), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 0); } diff --git a/src/cpu/x87_ops_sf_compare.h b/src/cpu/x87_ops_sf_compare.h index 6b4c1cb62..c4a38b375 100644 --- a/src/cpu/x87_ops_sf_compare.h +++ b/src/cpu/x87_ops_sf_compare.h @@ -1,11 +1,12 @@ #define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct softfloat_status_t status; \ + optype temp; \ FP_ENTER(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = rw; \ @@ -14,19 +15,19 @@ clear_C1(); \ if (IS_TAG_EMPTY(0)) { \ FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ goto next_ins; \ } \ status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ + rc = softfloat_relation_unordered; \ + softfloat_raiseFlags(&status, softfloat_flag_invalid); \ } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ + rc = extF80_compare_normal(a, use_var, &status); \ } \ setcc(FPU_status_word_flags_fpu_compare(rc)); \ - FPU_exception(fetchdat, status.float_exception_flags, 0); \ + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); \ \ next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ @@ -35,11 +36,12 @@ next_ins: } \ static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct softfloat_status_t status; \ + optype temp; \ FP_ENTER(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = rw; \ @@ -48,7 +50,7 @@ next_ins: clear_C1(); \ if (IS_TAG_EMPTY(0)) { \ FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ if (is_IA_masked()) \ FPU_pop(); \ \ @@ -57,13 +59,13 @@ next_ins: status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ a = FPU_read_regi(0); \ if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ + rc = softfloat_relation_unordered; \ + softfloat_raiseFlags(&status, softfloat_flag_invalid); \ } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ + rc = extF80_compare_normal(a, use_var, &status); \ } \ setcc(FPU_status_word_flags_fpu_compare(rc)); \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) \ FPU_pop(); \ \ next_ins: \ @@ -73,46 +75,48 @@ next_ins: } // clang-format off -cmp_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32) +cmp_FPU(s, float32, 16, temp, geteal(), f32_to_extF80(temp, &status), extF80_isNaN(a) || extF80_isUnsupported(a) || f32_isNaN(temp), _32) #ifndef FPU_8087 -cmp_FPU(s, float32, 32, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32) +cmp_FPU(s, float32, 32, temp, geteal(), f32_to_extF80(temp, &status), extF80_isNaN(a) || extF80_isUnsupported(a) || f32_isNaN(temp), _32) #endif -cmp_FPU(d, float64, 16, temp, geteaq(), float64_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(temp), _64) +cmp_FPU(d, float64, 16, temp, geteaq(), f64_to_extF80(temp, &status), extF80_isNaN(a) || extF80_isUnsupported(a) || f64_isNaN(temp), _64) #ifndef FPU_8087 -cmp_FPU(d, float64, 32, temp, geteaq(), float64_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(temp), _64) +cmp_FPU(d, float64, 32, temp, geteaq(), f64_to_extF80(temp, &status), extF80_isNaN(a) || extF80_isUnsupported(a) || f64_isNaN(temp), _64) #endif -cmp_FPU(iw, int16_t, 16, temp, (int16_t)geteaw(), int32_to_floatx80((int32_t)temp), 0, _i16) +cmp_FPU(iw, int16_t, 16, temp, (int16_t)geteaw(), i32_to_extF80((int32_t)temp), 0, _i16) #ifndef FPU_8087 -cmp_FPU(iw, int16_t, 32, temp, (int16_t)geteaw(), int32_to_floatx80((int32_t)temp), 0, _i16) +cmp_FPU(iw, int16_t, 32, temp, (int16_t)geteaw(), i32_to_extF80((int32_t)temp), 0, _i16) #endif -cmp_FPU(il, int32_t, 16, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32) +cmp_FPU(il, int32_t, 16, temp, (int32_t)geteal(), i32_to_extF80(temp), 0, _i32) #ifndef FPU_8087 -cmp_FPU(il, int32_t, 32, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32) +cmp_FPU(il, int32_t, 32, temp, (int32_t)geteal(), i32_to_extF80(temp), 0, _i32) #endif - // clang-format on +// clang-format on - static int sf_FCOM_sti(uint32_t fetchdat) +static int +sf_FCOM_sti(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + rc = extF80_compare_normal(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - FPU_exception(fetchdat, status.float_exception_flags, 0); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); next_ins: CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); @@ -123,17 +127,18 @@ next_ins: static int sf_FCOMP_sti(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (is_IA_masked()) { FPU_pop(); } @@ -142,9 +147,9 @@ sf_FCOMP_sti(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + rc = extF80_compare_normal(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); } @@ -157,17 +162,18 @@ next_ins: static int sf_FCOMPP(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (is_IA_masked()) { FPU_pop(); FPU_pop(); @@ -177,9 +183,9 @@ sf_FCOMPP(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(1); - rc = floatx80_compare_two(a, b, &status); + rc = extF80_compare_normal(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); FPU_pop(); } @@ -194,17 +200,18 @@ next_ins: static int sf_FUCOMPP(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (is_IA_masked()) { FPU_pop(); FPU_pop(); @@ -214,9 +221,9 @@ sf_FUCOMPP(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(1); - rc = floatx80_compare_quiet(a, b, &status); + rc = extF80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); FPU_pop(); } @@ -227,16 +234,17 @@ next_ins: return 0; } -# ifndef OPS_286_386 +#ifndef OPS_286_386 static int sf_FCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; flags_rebuild(); clear_C1(); @@ -248,9 +256,9 @@ sf_FCOMI_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + rc = extF80_compare_normal(a, b, &status); FPU_write_eflags_fpu_compare(rc); - FPU_exception(fetchdat, status.float_exception_flags, 0); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); next_ins: CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); @@ -260,12 +268,13 @@ next_ins: static int sf_FCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; flags_rebuild(); clear_C1(); @@ -280,9 +289,9 @@ sf_FCOMIP_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + rc = extF80_compare_normal(a, b, &status); FPU_write_eflags_fpu_compare(rc); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); } @@ -291,30 +300,31 @@ next_ins: CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } -# endif +#endif static int sf_FUCOM_sti(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + rc = extF80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - FPU_exception(fetchdat, status.float_exception_flags, 0); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); next_ins: CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); @@ -325,17 +335,18 @@ next_ins: static int sf_FUCOMP_sti(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); if (is_IA_masked()) FPU_pop(); @@ -344,9 +355,9 @@ sf_FUCOMP_sti(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + rc = extF80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_pop(); next_ins: @@ -359,12 +370,13 @@ next_ins: static int sf_FUCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; flags_rebuild(); clear_C1(); @@ -376,9 +388,9 @@ sf_FUCOMI_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + rc = extF80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); - FPU_exception(fetchdat, status.float_exception_flags, 0); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); next_ins: CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); @@ -388,12 +400,13 @@ next_ins: static int sf_FUCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - struct float_status_t status; - int rc; + floatx80 a; + floatx80 b; + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; flags_rebuild(); clear_C1(); @@ -408,9 +421,9 @@ sf_FUCOMIP_st0_stj(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + rc = extF80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_pop(); next_ins: @@ -418,26 +431,28 @@ next_ins: CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } -# endif +#endif #endif static int sf_FTST(uint32_t fetchdat) { - int rc; - struct float_status_t status; + const floatx80 Const_Z = packFloatx80(0, 0x0000, 0); + struct softfloat_status_t status; + int rc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); - setcc(C0 | C2 | C3); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status); + rc = extF80_compare_normal(FPU_read_regi(0), Const_Z, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); - FPU_exception(fetchdat, status.float_exception_flags, 0); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); @@ -447,45 +462,45 @@ sf_FTST(uint32_t fetchdat) static int sf_FXAM(uint32_t fetchdat) { - floatx80 reg; - int sign; - float_class_t aClass; + floatx80 reg; + int sign; + softfloat_class_t aClass; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; reg = FPU_read_regi(0); - sign = floatx80_sign(reg); + sign = extF80_sign(reg); /* * Examine the contents of the ST(0) register and sets the condition * code flags C0, C2 and C3 in the FPU status word to indicate the * class of value or number in the register. */ if (IS_TAG_EMPTY(0)) { - setcc(C3 | C1 | C0); + setcc(FPU_SW_C0 | FPU_SW_C1 | FPU_SW_C3); } else { - aClass = floatx80_class(reg); + aClass = extF80_class(reg); switch (aClass) { - case float_zero: - setcc(C3 | C1); + case softfloat_zero: + setcc(FPU_SW_C1 | FPU_SW_C3); break; - case float_SNaN: - case float_QNaN: + case softfloat_SNaN: + case softfloat_QNaN: // unsupported handled as NaNs - if (floatx80_is_unsupported(reg)) { - setcc(C1); - } else { - setcc(C1 | C0); - } + if (extF80_isUnsupported(reg)) + setcc(FPU_SW_C1); + else + setcc(FPU_SW_C0 | FPU_SW_C1); break; - case float_negative_inf: - case float_positive_inf: - setcc(C2 | C1 | C0); + case softfloat_negative_inf: + case softfloat_positive_inf: + setcc(FPU_SW_C0 | FPU_SW_C1 | FPU_SW_C2); break; - case float_denormal: - setcc(C3 | C2 | C1); + case softfloat_denormal: + setcc(FPU_SW_C1 | FPU_SW_C2 | FPU_SW_C3); break; - case float_normalized: - setcc(C2 | C1); + case softfloat_normalized: + setcc(FPU_SW_C1 | FPU_SW_C2); break; } } diff --git a/src/cpu/x87_ops_sf_const.h b/src/cpu/x87_ops_sf_const.h index 0808cbae8..19cc401f5 100644 --- a/src/cpu/x87_ops_sf_const.h +++ b/src/cpu/x87_ops_sf_const.h @@ -3,18 +3,11 @@ */ #define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN) -static __inline floatx80 -FPU_round_const(const floatx80 a, int adj) -{ - floatx80 result = a; - result.fraction += adj; - return result; -} - static int sf_FLDL2T(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -32,6 +25,7 @@ static int sf_FLDL2E(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -49,6 +43,7 @@ static int sf_FLDPI(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -66,6 +61,7 @@ static int sf_FLDEG2(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -83,6 +79,7 @@ static int sf_FLDLN2(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -100,6 +97,7 @@ static int sf_FLD1(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) @@ -117,6 +115,7 @@ static int sf_FLDZ(uint32_t fetchdat) { FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (!IS_TAG_EMPTY(-1)) diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index 228d9fc06..69249016e 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -38,10 +38,10 @@ sf_FILDiw_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; clear_C1(); - if (!IS_TAG_EMPTY(-1)) { + if (!IS_TAG_EMPTY(-1)) FPU_stack_overflow(fetchdat); - } else { - result = int32_to_floatx80(temp); + else { + result = i32_to_extF80(temp); FPU_push(); FPU_save_regi(result, 0); } @@ -67,7 +67,7 @@ sf_FILDiw_a32(uint32_t fetchdat) if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - result = int32_to_floatx80(temp); + result = i32_to_extF80(temp); FPU_push(); FPU_save_regi(result, 0); } @@ -94,7 +94,7 @@ sf_FILDil_a16(uint32_t fetchdat) if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - result = int32_to_floatx80(templ); + result = i32_to_extF80(templ); FPU_push(); FPU_save_regi(result, 0); } @@ -120,7 +120,7 @@ sf_FILDil_a32(uint32_t fetchdat) if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - result = int32_to_floatx80(templ); + result = i32_to_extF80(templ); FPU_push(); FPU_save_regi(result, 0); } @@ -147,7 +147,7 @@ sf_FILDiq_a16(uint32_t fetchdat) if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - result = int64_to_floatx80(temp64); + result = i64_to_extF80(temp64); FPU_push(); FPU_save_regi(result, 0); } @@ -173,7 +173,7 @@ sf_FILDiq_a32(uint32_t fetchdat) if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - result = int64_to_floatx80(temp64); + result = i64_to_extF80(temp64); FPU_push(); FPU_save_regi(result, 0); } @@ -187,40 +187,36 @@ static int sf_FBLD_PACKED_BCD_a16(uint32_t fetchdat) { floatx80 result; - uint16_t load_reg_hi = 0xffff; - uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); - int64_t load_val = 0ULL; - uint64_t power; - int sign; + uint16_t load_reg_hi; + uint64_t load_reg_lo; + int64_t val64 = 0; + int64_t scale = 1; FP_ENTER(); FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_hi = readmemw(easeg, (cpu_state.eaaddr + 8) & 0xffff); load_reg_lo = readmemq(easeg, cpu_state.eaaddr); - load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - sign = (load_reg_hi & 0x8000) != 0; - load_val = 0ULL; - power = 1; - for (int i = 0; i < 16; i++) { - load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + for (int n = 0; n < 16; n++) { + val64 += ((load_reg_lo & 0x0f) * scale); load_reg_lo >>= 4; - power *= 10; + scale *= 10; } - for (int i = 0; i < 2; i++) { - load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; - load_reg_hi >>= 4; - power *= 10; - } - if (sign) - load_val = -load_val; - result = int64_to_floatx80(load_val); + val64 += ((load_reg_hi & 0x0f) * scale); + val64 += (((load_reg_hi >> 4) & 0x0f) * scale * 10); + + result = (floatx80) i64_to_extF80(val64); + + if (load_reg_hi & 0x8000) + floatx80_chs(result); + FPU_push(); FPU_save_regi(result, 0); } @@ -233,40 +229,36 @@ static int sf_FBLD_PACKED_BCD_a32(uint32_t fetchdat) { floatx80 result; - uint16_t load_reg_hi = 0xffff; - uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); - int64_t load_val = 0ULL; - uint64_t power; - int sign; + uint16_t load_reg_hi; + uint64_t load_reg_lo; + int64_t val64 = 0; + int64_t scale = 1; FP_ENTER(); FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_hi = readmemw(easeg, (cpu_state.eaaddr + 8) & 0xffff); load_reg_lo = readmemq(easeg, cpu_state.eaaddr); - load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); } else { - sign = (load_reg_hi & 0x8000) != 0; - load_val = 0ULL; - power = 1; - for (int i = 0; i < 16; i++) { - load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + for (int n = 0; n < 16; n++) { + val64 += ((load_reg_lo & 0x0f) * scale); load_reg_lo >>= 4; - power *= 10; + scale *= 10; } - for (int i = 0; i < 2; i++) { - load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; - load_reg_hi >>= 4; - power *= 10; - } - if (sign) - load_val = -load_val; - result = int64_to_floatx80(load_val); + val64 += ((load_reg_hi & 0x0f) * scale); + val64 += (((load_reg_hi >> 4) & 0x0f) * scale * 10); + + result = (floatx80) i64_to_extF80(val64); + + if (load_reg_hi & 0x8000) + floatx80_chs(result); + FPU_push(); FPU_save_regi(result, 0); } @@ -279,10 +271,10 @@ sf_FBLD_PACKED_BCD_a32(uint32_t fetchdat) static int sf_FLDs_a16(uint32_t fetchdat) { - struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + struct softfloat_status_t status; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -297,8 +289,8 @@ sf_FLDs_a16(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); - unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); + result = f32_to_extF80(load_reg, &status); + unmasked = FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); FPU_save_regi(result, 0); @@ -313,10 +305,10 @@ next_ins: static int sf_FLDs_a32(uint32_t fetchdat) { - struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + struct softfloat_status_t status; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -331,8 +323,8 @@ sf_FLDs_a32(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); - unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); + result = f32_to_extF80(load_reg, &status); + unmasked = FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); FPU_save_regi(result, 0); @@ -348,10 +340,10 @@ next_ins: static int sf_FLDd_a16(uint32_t fetchdat) { - struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + struct softfloat_status_t status; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -366,8 +358,8 @@ sf_FLDd_a16(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); - unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); + result = f64_to_extF80(load_reg, &status); + unmasked = FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); FPU_save_regi(result, 0); @@ -382,10 +374,10 @@ next_ins: static int sf_FLDd_a32(uint32_t fetchdat) { - struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + struct softfloat_status_t status; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -400,8 +392,8 @@ sf_FLDd_a32(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); - unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); + result = f64_to_extF80(load_reg, &status); + unmasked = FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); FPU_save_regi(result, 0); @@ -423,10 +415,11 @@ sf_FLDe_a16(uint32_t fetchdat) FPU_check_pending_exceptions(); fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); - result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.signif = readmemq(easeg, cpu_state.eaaddr); + result.signExp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; + clear_C1(); if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); @@ -448,10 +441,11 @@ sf_FLDe_a32(uint32_t fetchdat) FPU_check_pending_exceptions(); fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); - result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.signif = readmemq(easeg, cpu_state.eaaddr); + result.signExp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; + clear_C1(); if (!IS_TAG_EMPTY(-1)) { FPU_stack_overflow(fetchdat); @@ -484,9 +478,8 @@ sf_FLD_sti(uint32_t fetchdat) FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); if (!is_IA_masked()) goto next_ins; - } else { + } else sti_reg = FPU_read_regi(fetchdat & 7); - } FPU_push(); FPU_save_regi(sti_reg, 0); @@ -500,9 +493,9 @@ next_ins: static int sf_FISTiw_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -516,8 +509,8 @@ sf_FISTiw_a16(uint32_t fetchdat) } } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int16(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_i16(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -535,9 +528,9 @@ next_ins: static int sf_FISTiw_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -550,8 +543,8 @@ sf_FISTiw_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int16(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_i16(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -569,9 +562,9 @@ next_ins: static int sf_FISTPiw_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -584,8 +577,8 @@ sf_FISTPiw_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int16(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_i16(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -606,9 +599,9 @@ next_ins: static int sf_FISTPiw_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -621,8 +614,8 @@ sf_FISTPiw_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int16(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_i16(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -643,9 +636,9 @@ next_ins: static int sf_FISTil_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -658,8 +651,8 @@ sf_FISTil_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_i32_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -677,9 +670,9 @@ next_ins: static int sf_FISTil_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -692,8 +685,8 @@ sf_FISTil_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_i32_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -711,9 +704,9 @@ next_ins: static int sf_FISTPil_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -726,8 +719,8 @@ sf_FISTPil_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_i32_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -748,9 +741,9 @@ next_ins: static int sf_FISTPil_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -763,8 +756,8 @@ sf_FISTPil_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_i32_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -785,9 +778,9 @@ next_ins: static int sf_FISTPiq_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -800,8 +793,8 @@ sf_FISTPiq_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_i64_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -822,9 +815,9 @@ next_ins: static int sf_FISTPiq_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -837,8 +830,8 @@ sf_FISTPiq_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_int64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_i64_normal(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case origial FPU_SW must be kept @@ -859,13 +852,13 @@ next_ins: static int sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -879,15 +872,15 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); reg = FPU_read_regi(0); - save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + save_val = extF80_to_i64_normal(reg, &status); + sign = extF80_sign(reg); if (sign) save_val = -save_val; if (save_val > BX_CONST64(999999999999999999)) - status.float_exception_flags = float_flag_invalid; // throw away other flags + softfloat_setFlags(&status, softfloat_flag_invalid); // throw away other flags - if (!(status.float_exception_flags & float_flag_invalid)) { + if (!(status.softfloat_exceptionFlags & softfloat_flag_invalid)) { save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { @@ -899,7 +892,7 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -923,13 +916,13 @@ next_ins: static int sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -943,15 +936,15 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); reg = FPU_read_regi(0); - save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + save_val = extF80_to_i64_normal(reg, &status); + sign = extF80_sign(reg); if (sign) save_val = -save_val; if (save_val > BX_CONST64(999999999999999999)) - status.float_exception_flags = float_flag_invalid; // throw away other flags + softfloat_setFlags(&status, softfloat_flag_invalid); // throw away other flags - if (!(status.float_exception_flags & float_flag_invalid)) { + if (!(status.softfloat_exceptionFlags & softfloat_flag_invalid)) { save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { @@ -963,7 +956,7 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -988,9 +981,9 @@ next_ins: static int sf_FSTs_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1003,8 +996,8 @@ sf_FSTs_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_f32(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -1022,9 +1015,9 @@ next_ins: static int sf_FSTs_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1037,8 +1030,8 @@ sf_FSTs_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_f32(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -1056,9 +1049,9 @@ next_ins: static int sf_FSTPs_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1071,17 +1064,17 @@ sf_FSTPs_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_f32(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } // store to the memory might generate an exception, in this case original FPU_SW must be kept swap_values16u(sw, fpu_state.swd); seteal(save_reg); - if (cpu_state.abrt) { + if (cpu_state.abrt) return 1; - } + fpu_state.swd = sw; FPU_pop(); @@ -1094,9 +1087,9 @@ next_ins: static int sf_FSTPs_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1109,8 +1102,8 @@ sf_FSTPs_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float32(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_f32(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -1118,6 +1111,7 @@ sf_FSTPs_a32(uint32_t fetchdat) seteal(save_reg); if (cpu_state.abrt) return 1; + fpu_state.swd = sw; FPU_pop(); @@ -1131,9 +1125,9 @@ next_ins: static int sf_FSTd_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1146,8 +1140,8 @@ sf_FSTd_a16(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_f64(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -1165,9 +1159,9 @@ next_ins: static int sf_FSTd_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1180,8 +1174,8 @@ sf_FSTd_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_f64(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -1199,9 +1193,9 @@ next_ins: static int sf_FSTPd_a16(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1215,8 +1209,8 @@ sf_FSTPd_a16(uint32_t fetchdat) } } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + save_reg = extF80_to_f64(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) { goto next_ins; } } @@ -1225,6 +1219,7 @@ sf_FSTPd_a16(uint32_t fetchdat) seteaq(save_reg); if (cpu_state.abrt) return 1; + fpu_state.swd = sw; FPU_pop(); @@ -1237,9 +1232,9 @@ next_ins: static int sf_FSTPd_a32(uint32_t fetchdat) { - struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + struct softfloat_status_t status; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1252,8 +1247,8 @@ sf_FSTPd_a32(uint32_t fetchdat) goto next_ins; } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - save_reg = floatx80_to_float64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) + save_reg = extF80_to_f64(FPU_read_regi(0), &status); + if (FPU_exception(fetchdat, status.softfloat_exceptionFlags, 1)) goto next_ins; } // store to the memory might generate an exception, in this case original FPU_SW must be kept @@ -1261,6 +1256,7 @@ sf_FSTPd_a32(uint32_t fetchdat) seteaq(save_reg); if (cpu_state.abrt) return 1; + fpu_state.swd = sw; FPU_pop(); @@ -1293,8 +1289,8 @@ sf_FSTPe_a16(uint32_t fetchdat) } else { save_reg = FPU_read_regi(0); } - writememq(easeg, cpu_state.eaaddr, save_reg.fraction); - writememw(easeg, cpu_state.eaaddr + 8, save_reg.exp); + writememq(easeg, cpu_state.eaaddr, save_reg.signif); + writememw(easeg, cpu_state.eaaddr + 8, save_reg.signExp); FPU_pop(); next_ins: @@ -1324,8 +1320,8 @@ sf_FSTPe_a32(uint32_t fetchdat) } else { save_reg = FPU_read_regi(0); } - writememq(easeg, cpu_state.eaaddr, save_reg.fraction); - writememw(easeg, cpu_state.eaaddr + 8, save_reg.exp); + writememq(easeg, cpu_state.eaaddr, save_reg.signif); + writememw(easeg, cpu_state.eaaddr + 8, save_reg.signExp); FPU_pop(); next_ins: @@ -1365,7 +1361,7 @@ sf_FSTP_sti(uint32_t fetchdat) cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0)) { - FPU_stack_underflow(fetchdat, fetchdat & 7, 1); + FPU_pop(); } else { st0_reg = FPU_read_regi(0); FPU_save_regi(st0_reg, fetchdat & 7); diff --git a/src/cpu/x87_ops_sf_misc.h b/src/cpu/x87_ops_sf_misc.h index 85f42e6d5..0aab2ec08 100644 --- a/src/cpu/x87_ops_sf_misc.h +++ b/src/cpu/x87_ops_sf_misc.h @@ -129,6 +129,7 @@ sf_FFREEP_sti(uint32_t fetchdat) FPU_settagi(X87_TAG_EMPTY, fetchdat & 7); if (cpu_state.abrt) return 1; + FPU_pop(); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); diff --git a/src/cpu/x87_ops_sf_trans.h b/src/cpu/x87_ops_sf_trans.h index 5a99abb4c..d5aec0110 100644 --- a/src/cpu/x87_ops_sf_trans.h +++ b/src/cpu/x87_ops_sf_trans.h @@ -1,10 +1,11 @@ static int sf_F2XM1(uint32_t fetchdat) { - floatx80 result; - struct float_status_t status; + floatx80 result; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0)) { @@ -13,7 +14,7 @@ sf_F2XM1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = f2xm1(FPU_read_regi(0), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, 0); next_ins: @@ -25,10 +26,11 @@ next_ins: static int sf_FYL2X(uint32_t fetchdat) { - floatx80 result; - struct float_status_t status; + floatx80 result; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { @@ -37,7 +39,7 @@ sf_FYL2X(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2x(FPU_read_regi(0), FPU_read_regi(1), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -51,11 +53,12 @@ next_ins: static int sf_FPTAN(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 y; - struct float_status_t status; + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + floatx80 y; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -76,12 +79,12 @@ sf_FPTAN(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); y = FPU_read_regi(0); if (ftan(&y, &status) == -1) { - fpu_state.swd |= C2; + fpu_state.swd |= FPU_SW_C2; goto next_ins; } - if (floatx80_is_nan(y)) { - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (extF80_isNaN(y)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(y, 0); @@ -89,7 +92,7 @@ sf_FPTAN(uint32_t fetchdat) goto next_ins; } - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(Const_1, 0); @@ -104,12 +107,13 @@ next_ins: static int sf_FPATAN(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - floatx80 result; - struct float_status_t status; + floatx80 a; + floatx80 b; + floatx80 result; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { FPU_stack_underflow(fetchdat, 1, 1); @@ -119,7 +123,7 @@ sf_FPATAN(uint32_t fetchdat) b = FPU_read_regi(1); status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fpatan(a, b, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -133,11 +137,15 @@ next_ins: static int sf_FXTRACT(uint32_t fetchdat) { - struct float_status_t status; - floatx80 a; - floatx80 b; + struct softfloat_status_t status; + floatx80 a; + floatx80 b; +#if 0 + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); +#endif FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); @@ -160,8 +168,8 @@ sf_FXTRACT(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word()); a = FPU_read_regi(0); - b = floatx80_extract(&a, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + b = extF80_extract(&a, &status); + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(b, 0); // exponent FPU_push(); FPU_save_regi(a, 0); // fraction @@ -178,15 +186,16 @@ next_ins: static int sf_FPREM1(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - floatx80 result; - struct float_status_t status; - uint64_t quotient = 0; - int flags; - int cc; + floatx80 a; + floatx80 b; + floatx80 result; + struct softfloat_status_t status; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -198,18 +207,18 @@ sf_FPREM1(uint32_t fetchdat) a = FPU_read_regi(0); b = FPU_read_regi(1); flags = floatx80_ieee754_remainder(a, b, &result, "ient, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { if (flags >= 0) { cc = 0; if (flags) - cc = C2; + cc = FPU_SW_C2; else { if (quotient & 1) - cc |= C1; + cc |= FPU_SW_C1; if (quotient & 2) - cc |= C3; + cc |= FPU_SW_C3; if (quotient & 4) - cc |= C0; + cc |= FPU_SW_C0; } setcc(cc); } @@ -225,15 +234,16 @@ next_ins: static int sf_FPREM(uint32_t fetchdat) { - floatx80 a; - floatx80 b; - floatx80 result; - struct float_status_t status; - uint64_t quotient = 0; - int flags; - int cc; + floatx80 a; + floatx80 b; + floatx80 result; + struct softfloat_status_t status; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -246,18 +256,18 @@ sf_FPREM(uint32_t fetchdat) b = FPU_read_regi(1); // handle unsupported extended double-precision floating encodings flags = floatx80_remainder(a, b, &result, "ient, &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { if (flags >= 0) { cc = 0; if (flags) - cc = C2; + cc = FPU_SW_C2; else { if (quotient & 1) - cc |= C1; + cc |= FPU_SW_C1; if (quotient & 2) - cc |= C3; + cc |= FPU_SW_C3; if (quotient & 4) - cc |= C0; + cc |= FPU_SW_C0; } setcc(cc); } @@ -273,10 +283,11 @@ next_ins: static int sf_FYL2XP1(uint32_t fetchdat) { - floatx80 result; - struct float_status_t status; + floatx80 result; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { @@ -285,7 +296,7 @@ sf_FYL2XP1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2xp1(FPU_read_regi(0), FPU_read_regi(1), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(result, 1); FPU_pop(); } @@ -300,13 +311,14 @@ next_ins: static int sf_FSINCOS(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - struct float_status_t status; - floatx80 y; - floatx80 sin_y; - floatx80 cos_y; + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + struct softfloat_status_t status; + floatx80 y; + floatx80 sin_y; + floatx80 cos_y; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -327,10 +339,10 @@ sf_FSINCOS(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); y = FPU_read_regi(0); if (fsincos(y, &sin_y, &cos_y, &status) == -1) { - fpu_state.swd |= C2; + fpu_state.swd |= FPU_SW_C2; goto next_ins; } - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { FPU_save_regi(sin_y, 0); FPU_push(); FPU_save_regi(cos_y, 0); @@ -346,10 +358,11 @@ next_ins: static int sf_FSCALE(uint32_t fetchdat) { - floatx80 result; - struct float_status_t status; + floatx80 result; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { @@ -357,8 +370,8 @@ sf_FSCALE(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = floatx80_scale(FPU_read_regi(0), FPU_read_regi(1), &status); - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + result = extF80_scale(FPU_read_regi(0), FPU_read_regi(1), &status); + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(result, 0); next_ins: @@ -371,10 +384,11 @@ next_ins: static int sf_FSIN(uint32_t fetchdat) { - floatx80 y; - struct float_status_t status; + floatx80 y; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -385,10 +399,10 @@ sf_FSIN(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); y = FPU_read_regi(0); if (fsin(&y, &status) == -1) { - fpu_state.swd |= C2; + fpu_state.swd |= FPU_SW_C2; goto next_ins; } - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(y, 0); next_ins: @@ -400,10 +414,11 @@ next_ins: static int sf_FCOS(uint32_t fetchdat) { - floatx80 y; - struct float_status_t status; + floatx80 y; + struct softfloat_status_t status; FP_ENTER(); + FPU_check_pending_exceptions(); cpu_state.pc++; clear_C1(); clear_C2(); @@ -414,10 +429,10 @@ sf_FCOS(uint32_t fetchdat) status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); y = FPU_read_regi(0); if (fcos(&y, &status) == -1) { - fpu_state.swd |= C2; + fpu_state.swd |= FPU_SW_C2; goto next_ins; } - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) FPU_save_regi(y, 0); next_ins: From b72757ac0ca42a1471f708da75add8705185aad0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 9 Jun 2024 23:37:11 +0200 Subject: [PATCH 600/690] pci.c: compile fix. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index 786573179..6475efe90 100644 --- a/src/pci.c +++ b/src/pci.c @@ -92,7 +92,7 @@ static int pci_card; static int pci_bus; static int pci_key; static int pci_trc_reg = 0; -static uint32 pci_enable = 0x00000000; +static uint32_t pci_enable = 0x00000000; static void pci_reset_regs(void); From 55f5b9fb21e780c441f2fa8cff89dfbee9ab0559 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 9 Jun 2024 23:39:33 +0200 Subject: [PATCH 601/690] vid_cga_comp.h: another compile fix. --- src/include/86box/vid_cga_comp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/vid_cga_comp.h b/src/include/86box/vid_cga_comp.h index 291145291..609e6d813 100644 --- a/src/include/86box/vid_cga_comp.h +++ b/src/include/86box/vid_cga_comp.h @@ -26,6 +26,6 @@ void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); -Bit32u *Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doublewidth*/, uint32_t *TempLine); +uint32_t *Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doublewidth*/, uint32_t *TempLine); #endif /*VIDEO_CGA_COMP_H*/ From ce201f2e8712334045c9388098dd5d1aba8a92db Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Jun 2024 23:43:22 +0200 Subject: [PATCH 602/690] PCjs: Change an uint8 to uint8_t. --- src/floppy/fdd_pcjs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/floppy/fdd_pcjs.c b/src/floppy/fdd_pcjs.c index 474d8ee37..f96af5c5f 100644 --- a/src/floppy/fdd_pcjs.c +++ b/src/floppy/fdd_pcjs.c @@ -350,7 +350,7 @@ int json_parse(pcjs_t *dev) if (sector->data == NULL ) { /* We could verify the sector size against the metadata here */ - sector->data = (uint8 *)calloc(1, current_length); + sector->data = (uint8_t *)calloc(1, current_length); if (sector->data == NULL ) { pcjs_log("Failed to allocate\n"); pcjs_error = E_ALLOC; From 2273f563a5f0f60148ea2d2f0e98f05ba38c9354 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 00:08:48 +0200 Subject: [PATCH 603/690] Moved the offending SoftFloat-related stuff to x87_sf.h, fixes warnings. --- src/CMakeLists.txt | 2 +- src/codegen/codegen_ops.c | 1 + src/codegen/codegen_x86-64.c | 1 + src/codegen/codegen_x86.c | 1 + src/codegen_new/codegen_backend_arm64_uops.c | 1 + src/codegen_new/codegen_backend_arm_uops.c | 1 + src/codegen_new/codegen_backend_x86-64_uops.c | 1 + src/codegen_new/codegen_backend_x86_uops.c | 1 + src/codegen_new/codegen_block.c | 1 + src/codegen_new/codegen_ops_fpu_arith.c | 1 + src/codegen_new/codegen_ops_fpu_constant.c | 1 + src/codegen_new/codegen_ops_fpu_loadstore.c | 1 + src/codegen_new/codegen_ops_fpu_misc.c | 1 + src/cpu/386.c | 1 + src/cpu/386_common.c | 1 + src/cpu/386_dynarec.c | 1 + src/cpu/386_dynarec_ops.c | 1 + src/cpu/808x.c | 1 + src/cpu/CMakeLists.txt | 5 ++- src/cpu/codegen_timing_486.c | 1 + src/cpu/codegen_timing_686.c | 1 + src/cpu/codegen_timing_k6.c | 1 + src/cpu/codegen_timing_p6.c | 1 + src/cpu/codegen_timing_pentium.c | 1 + src/cpu/codegen_timing_winchip.c | 1 + src/cpu/codegen_timing_winchip2.c | 1 + src/cpu/cpu.c | 1 + src/cpu/cpu.h | 19 --------- src/cpu/x86_ops_mmx.c | 1 + src/cpu/x87.c | 1 + src/cpu/x87_sf.h | 40 +++++++++++++++++++ 31 files changed, 72 insertions(+), 21 deletions(-) create mode 100644 src/cpu/x87_sf.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66fe70821..93a6f4d4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,7 +66,7 @@ if(VNC) if(LibVNCServer_FOUND) add_compile_definitions(USE_VNC) add_library(vnc OBJECT vnc.c vnc_keymap.c) - target_link_libraries(86Box vnc LibVNCServer::vncserver) + target_link_libraries(86Box vnc LibVNCServer::vncserver) if(WIN32) target_link_libraries(86Box ws2_32) endif() diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index a81eef67e..c8e258e78 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -12,6 +12,7 @@ #include "x86_flags.h" #include "x86seg_common.h" #include "x86seg.h" +#include "x87_sf.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 421f20026..958872162 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -13,6 +13,7 @@ # include "x86_ops.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.h" # include "x87.h" # include <86box/mem.h> # include <86box/plat_unused.h> diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 456f93ae9..74c209001 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -51,6 +51,7 @@ # include "x86_ops.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.h" # include "x87.h" /*ex*/ # include <86box/nmi.h> diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 421292c7e..deaf53c20 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -9,6 +9,7 @@ # include "x86.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.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 04b61255b..d8c223884 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -10,6 +10,7 @@ # include "x86.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.h" # include "x87.h" # include "386_common.h" # include "codegen.h" diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 1b82f9fca..46af68e75 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -9,6 +9,7 @@ # include "x86.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.h" # include "x87.h" # include "386_common.h" # include "codegen.h" diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 91f2c7ec3..cd79b9b47 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -10,6 +10,7 @@ # include "x86_ops.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.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 ee0a030ba..a8ea0e06e 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -12,6 +12,7 @@ #include "x86_ops.h" #include "x86seg_common.h" #include "x86seg.h" +#include "x87_sf.h" #include "x87.h" #include "386_common.h" diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 15a6399e6..a7b5290f4 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -9,6 +9,7 @@ #include "x86seg_common.h" #include "x86seg.h" #include "386_common.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index 862845868..a91d675c5 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -9,6 +9,7 @@ #include "x86seg_common.h" #include "x86seg.h" #include "386_common.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 7635063e8..12babaf49 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -9,6 +9,7 @@ #include "x86seg_common.h" #include "x86seg.h" #include "386_common.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index 7865e0573..31b668488 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -9,6 +9,7 @@ #include "x86seg_common.h" #include "x86seg.h" #include "386_common.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/cpu/386.c b/src/cpu/386.c index 5379dccf9..3e96911ba 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -15,6 +15,7 @@ #include "x86.h" #include "x86_ops.h" #include "x86seg_common.h" +#include "x87_sf.h" #include "x87.h" #include <86box/io.h> #include <86box/nmi.h> diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 801b543c3..5e80ef4c3 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -14,6 +14,7 @@ #include <86box/timer.h> #include "x86.h" #include "x86seg_common.h" +#include "x87_sf.h" #include "x87.h" #include <86box/nmi.h> #include <86box/mem.h> diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 77914a2a5..8e9403899 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -19,6 +19,7 @@ #include "x86_ops.h" #include "x86seg_common.h" #include "x86seg.h" +#include "x87_sf.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 066b00dd6..c31b725b2 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -15,6 +15,7 @@ #include "x86_ops.h" #include "x86seg_common.h" #include "x86seg.h" +#include "x87_sf.h" #include "x87.h" #include "x86_flags.h" #include <86box/io.h> diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 5b411dd66..6705563c0 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -785,6 +785,7 @@ seteaq(uint64_t val) complicates compiling. */ #define FPU_8087 #define tempc tempc_fpu +#include "x87_sf.h" #include "x87.h" #include "x87_ops.h" #undef tempc diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index fc5ba975f..a3677767d 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -23,12 +23,15 @@ endif() if(CYRIX_6X86) target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) + + add_library(ct686 OBJECT codegen_timing_686.c) + target_link_libraries(86Box ct686) endif() if(DYNAREC) target_sources(cpu PRIVATE 386_dynarec_ops.c) - add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c + add_library(cgt OBJECT codegen_timing_486.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_p6.c codegen_timing_winchip.c codegen_timing_winchip2.c) diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index e862b123e..548a9ec28 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -9,6 +9,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index a6800c5b2..6ea5ac543 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -19,6 +19,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_timing_common.h" diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 4a9f23cd8..6a2871884 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -12,6 +12,7 @@ #include "x86.h" #include "x86_ops.h" #include "x86seg_common.h" +#include "x87_sf.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 2c087ae86..25c098ca4 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -13,6 +13,7 @@ #include "x86.h" #include "x86_ops.h" #include "x86seg_common.h" +#include "x87_sf.h" #include "x87.h" #include "386_common.h" #include "codegen.h" diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 3951acc94..af344307f 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -21,6 +21,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index 11dd912b4..76ea8b954 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -9,6 +9,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c index d4e32611e..ea206f068 100644 --- a/src/cpu/codegen_timing_winchip2.c +++ b/src/cpu/codegen_timing_winchip2.c @@ -18,6 +18,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x87_sf.h" #include "x87.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b812a24f9..e1e0e913d 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -29,6 +29,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" +#include "x87_sf.h" #include <86box/device.h> #include <86box/machine.h> #include <86box/io.h> diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index ae5b4692a..9b154cd0d 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,8 +21,6 @@ #ifndef EMU_CPU_H #define EMU_CPU_H -#include "softfloat3e/softfloat.h" - enum { FPU_NONE, FPU_8087, @@ -406,22 +404,6 @@ typedef struct { uint32_t _smbase; } cpu_state_t; -typedef struct { - uint16_t cwd; - uint16_t swd; - uint16_t tag; - uint16_t foo; - uint32_t fip; - uint32_t fdp; - uint16_t fcs; - uint16_t fds; - floatx80 st_space[8]; - unsigned char tos; - unsigned char align1; - unsigned char align2; - unsigned char align3; -} fpu_state_t; - #define in_smm cpu_state._in_smm #define smi_line cpu_state._smi_line @@ -502,7 +484,6 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128) /* Global variables. */ extern cpu_state_t cpu_state; -extern fpu_state_t fpu_state; extern const cpu_family_t cpu_families[]; extern cpu_family_t *cpu_f; diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c index 55fc987c2..2737ac8fa 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -13,6 +13,7 @@ #include "cpu.h" #include <86box/timer.h> #include "x86.h" +#include "x87_sf.h" #include "x87.h" #include <86box/nmi.h> #include <86box/mem.h> diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 980431f15..2aafd44e6 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -14,6 +14,7 @@ #include "x86_flags.h" #include "x86_ops.h" #include "x86seg_common.h" +#include "x87_sf.h" #include "x87.h" #include "386_common.h" #include "softfloat3e/config.h" diff --git a/src/cpu/x87_sf.h b/src/cpu/x87_sf.h new file mode 100644 index 000000000..0388442bd --- /dev/null +++ b/src/cpu/x87_sf.h @@ -0,0 +1,40 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2024 Miran Grca. + */ +#ifndef EMU_X87_SF_H +#define EMU_X87_SF_H + +#include "softfloat3e/softfloat.h" + +typedef struct { + uint16_t cwd; + uint16_t swd; + uint16_t tag; + uint16_t foo; + uint32_t fip; + uint32_t fdp; + uint16_t fcs; + uint16_t fds; + floatx80 st_space[8]; + unsigned char tos; + unsigned char align1; + unsigned char align2; + unsigned char align3; +} fpu_state_t; + +extern fpu_state_t fpu_state; + +#endif /*EMU_X87_SF_H*/ From cd41ef012383175e86c64ae1fb0bff66485cc17e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 9 Jun 2024 20:10:43 -0400 Subject: [PATCH 604/690] Fix granularity of Generic AT RAM expansion card --- src/device/isamem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index fcbbbfb15..2b0b8f66b 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1215,7 +1215,7 @@ static const device_config_t genericat_config[] = { .spinner = { .min = 0, .max = 16384, - .step = 512 + .step = 128 }, .selection = { { 0 } } }, From 56b3a27b3389b96fa12e6c3178f8fdf8a34ad503 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 02:14:42 +0200 Subject: [PATCH 605/690] SoftFloat: Move the const's to a .c file and make the .h only contain extern's. --- src/cpu/softfloat3e/CMakeLists.txt | 2 +- src/cpu/softfloat3e/softfloat-specialize.h | 58 +++++++++++----------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/cpu/softfloat3e/CMakeLists.txt b/src/cpu/softfloat3e/CMakeLists.txt index 5565460c8..66a4287ca 100644 --- a/src/cpu/softfloat3e/CMakeLists.txt +++ b/src/cpu/softfloat3e/CMakeLists.txt @@ -13,7 +13,7 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(softfloat3e OBJECT extF80_addsub.cc extF80_class.cc extF80_compare.cc +add_library(softfloat3e OBJECT softfloat-specialize.c extF80_addsub.cc extF80_class.cc extF80_compare.cc extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc diff --git a/src/cpu/softfloat3e/softfloat-specialize.h b/src/cpu/softfloat3e/softfloat-specialize.h index bc7dcd263..587f0d345 100644 --- a/src/cpu/softfloat3e/softfloat-specialize.h +++ b/src/cpu/softfloat3e/softfloat-specialize.h @@ -39,26 +39,26 @@ these four paragraphs for those parts of this code that are retained. * Stanislav Shwartsman [sshwarts at sourceforge net] * ==========================================================================*/ -const int16_t int16_indefinite = (int16_t) 0x8000; -const int32_t int32_indefinite = (int32_t) 0x80000000; -const int64_t int64_indefinite = (int64_t) BX_CONST64(0x8000000000000000); +extern const int16_t int16_indefinite; +extern const int32_t int32_indefinite; +extern const int64_t int64_indefinite; -const uint16_t uint16_indefinite = 0xffff; -const uint32_t uint32_indefinite = 0xffffffff; -const uint64_t uint64_indefinite = BX_CONST64(0xffffffffffffffff); +extern const uint16_t uint16_indefinite; +extern const uint32_t uint32_indefinite; +extern const uint64_t uint64_indefinite; /*---------------------------------------------------------------------------- | Commonly used half-precision floating point constants *----------------------------------------------------------------------------*/ -const float16 float16_negative_inf = 0xfc00; -const float16 float16_positive_inf = 0x7c00; -const float16 float16_negative_zero = 0x8000; -const float16 float16_positive_zero = 0x0000; +extern const float16 float16_negative_inf; +extern const float16 float16_positive_inf; +extern const float16 float16_negative_zero; +extern const float16 float16_positive_zero; /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ -const float16 float16_default_nan = 0xFE00; +extern const float16 float16_default_nan; #define FLOAT16_EXP_BIAS 0xF @@ -81,19 +81,19 @@ static __inline float16 packFloat16(int zSign, int zExp, uint16_t zSig) /*---------------------------------------------------------------------------- | Commonly used single-precision floating point constants *----------------------------------------------------------------------------*/ -const float32 float32_negative_inf = 0xff800000; -const float32 float32_positive_inf = 0x7f800000; -const float32 float32_negative_zero = 0x80000000; -const float32 float32_positive_zero = 0x00000000; -const float32 float32_negative_one = 0xbf800000; -const float32 float32_positive_one = 0x3f800000; -const float32 float32_max_float = 0x7f7fffff; -const float32 float32_min_float = 0xff7fffff; +extern const float32 float32_negative_inf; +extern const float32 float32_positive_inf; +extern const float32 float32_negative_zero; +extern const float32 float32_positive_zero; +extern const float32 float32_negative_one; +extern const float32 float32_positive_one; +extern const float32 float32_max_float; +extern const float32 float32_min_float; /*---------------------------------------------------------------------------- | The pattern for a default generated single-precision NaN. *----------------------------------------------------------------------------*/ -const float32 float32_default_nan = 0xffc00000; +extern const float32 float32_default_nan; #define FLOAT32_EXP_BIAS 0x7F @@ -116,19 +116,19 @@ static __inline float32 packFloat32(int zSign, int16_t zExp, uint32_t zSig) /*---------------------------------------------------------------------------- | Commonly used single-precision floating point constants *----------------------------------------------------------------------------*/ -const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000); -const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000); -const float64 float64_negative_zero = BX_CONST64(0x8000000000000000); -const float64 float64_positive_zero = BX_CONST64(0x0000000000000000); -const float64 float64_negative_one = BX_CONST64(0xbff0000000000000); -const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000); -const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff); -const float64 float64_min_float = BX_CONST64(0xffefffffffffffff); +extern const float64 float64_negative_inf; +extern const float64 float64_positive_inf; +extern const float64 float64_negative_zero; +extern const float64 float64_positive_zero; +extern const float64 float64_negative_one; +extern const float64 float64_positive_one; +extern const float64 float64_max_float; +extern const float64 float64_min_float; /*---------------------------------------------------------------------------- | The pattern for a default generated double-precision NaN. *----------------------------------------------------------------------------*/ -const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000); +extern const float64 float64_default_nan; #define FLOAT64_EXP_BIAS 0x3FF From f4cc13d6223516c4f18a2f592045d55c68714ff2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 02:14:55 +0200 Subject: [PATCH 606/690] The forgotten .c file. --- src/cpu/softfloat3e/softfloat-specialize.c | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/cpu/softfloat3e/softfloat-specialize.c diff --git a/src/cpu/softfloat3e/softfloat-specialize.c b/src/cpu/softfloat3e/softfloat-specialize.c new file mode 100644 index 000000000..5bc57e565 --- /dev/null +++ b/src/cpu/softfloat3e/softfloat-specialize.c @@ -0,0 +1,90 @@ +/*============================================================================ +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. +=============================================================================*/ + +#include "softfloat-specialize.h" + +/*============================================================================ + * Adapted for Bochs (x86 achitecture simulator) by + * Stanislav Shwartsman [sshwarts at sourceforge net] + * ==========================================================================*/ + +const int16_t int16_indefinite = (int16_t) 0x8000; +const int32_t int32_indefinite = (int32_t) 0x80000000; +const int64_t int64_indefinite = (int64_t) BX_CONST64(0x8000000000000000); + +const uint16_t uint16_indefinite = 0xffff; +const uint32_t uint32_indefinite = 0xffffffff; +const uint64_t uint64_indefinite = BX_CONST64(0xffffffffffffffff); + +/*---------------------------------------------------------------------------- +| Commonly used half-precision floating point constants +*----------------------------------------------------------------------------*/ +const float16 float16_negative_inf = 0xfc00; +const float16 float16_positive_inf = 0x7c00; +const float16 float16_negative_zero = 0x8000; +const float16 float16_positive_zero = 0x0000; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated half-precision NaN. +*----------------------------------------------------------------------------*/ +const float16 float16_default_nan = 0xFE00; + +/*---------------------------------------------------------------------------- +| Commonly used single-precision floating point constants +*----------------------------------------------------------------------------*/ +const float32 float32_negative_inf = 0xff800000; +const float32 float32_positive_inf = 0x7f800000; +const float32 float32_negative_zero = 0x80000000; +const float32 float32_positive_zero = 0x00000000; +const float32 float32_negative_one = 0xbf800000; +const float32 float32_positive_one = 0x3f800000; +const float32 float32_max_float = 0x7f7fffff; +const float32 float32_min_float = 0xff7fffff; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +const float32 float32_default_nan = 0xffc00000; + +/*---------------------------------------------------------------------------- +| Commonly used single-precision floating point constants +*----------------------------------------------------------------------------*/ +const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000); +const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000); +const float64 float64_negative_zero = BX_CONST64(0x8000000000000000); +const float64 float64_positive_zero = BX_CONST64(0x0000000000000000); +const float64 float64_negative_one = BX_CONST64(0xbff0000000000000); +const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000); +const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff); +const float64 float64_min_float = BX_CONST64(0xffefffffffffffff); + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000); From 751f2af3823d3632a2c66e6bfcafe5cdbd6174f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 02:23:13 +0200 Subject: [PATCH 607/690] And primitives.h. as well. --- src/cpu/softfloat3e/CMakeLists.txt | 3 +- src/cpu/softfloat3e/primitives.c | 50 ++++++++++++++++++++++++++++++ src/cpu/softfloat3e/primitives.h | 10 +----- 3 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 src/cpu/softfloat3e/primitives.c diff --git a/src/cpu/softfloat3e/CMakeLists.txt b/src/cpu/softfloat3e/CMakeLists.txt index 66a4287ca..9f9ae0679 100644 --- a/src/cpu/softfloat3e/CMakeLists.txt +++ b/src/cpu/softfloat3e/CMakeLists.txt @@ -13,7 +13,8 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(softfloat3e OBJECT softfloat-specialize.c extF80_addsub.cc extF80_class.cc extF80_compare.cc +add_library(softfloat3e OBJECT primitives.c softfloat-specialize.c + extF80_addsub.cc extF80_class.cc extF80_compare.cc extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc diff --git a/src/cpu/softfloat3e/primitives.c b/src/cpu/softfloat3e/primitives.c new file mode 100644 index 000000000..ba5afb76a --- /dev/null +++ b/src/cpu/softfloat3e/primitives.c @@ -0,0 +1,50 @@ +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3e, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include "primitives.h" + +/*---------------------------------------------------------------------------- +| This function is the same as 'softfloat_shiftRightJam128Extra' (below), +| except that 'dist' must be in the range 1 to 63. +*----------------------------------------------------------------------------*/ +struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist) +{ + uint8_t negDist = -dist; + struct uint128_extra z; + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(negDist & 63) | a0>>dist; + z.extra = a0<<(negDist & 63) | (extra != 0); + return z; +} diff --git a/src/cpu/softfloat3e/primitives.h b/src/cpu/softfloat3e/primitives.h index 993067996..3c811838e 100644 --- a/src/cpu/softfloat3e/primitives.h +++ b/src/cpu/softfloat3e/primitives.h @@ -283,15 +283,7 @@ struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint8_ | This function is the same as 'softfloat_shiftRightJam128Extra' (below), | except that 'dist' must be in the range 1 to 63. *----------------------------------------------------------------------------*/ -struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist) -{ - uint8_t negDist = -dist; - struct uint128_extra z; - z.v.v64 = a64>>dist; - z.v.v0 = a64<<(negDist & 63) | a0>>dist; - z.extra = a0<<(negDist & 63) | (extra != 0); - return z; -} +extern struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist); /*---------------------------------------------------------------------------- | Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64 From c852c99d8f8621aa059e769f83fc2b6328126c0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 03:51:10 +0200 Subject: [PATCH 608/690] Modern header fixes. --- src/codegen_new/codegen_backend_arm.c | 1 + src/codegen_new/codegen_backend_arm64.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index b1e904096..9c480dccf 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -15,6 +15,7 @@ # include "x86.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.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 1eb94a909..5c2233b63 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -15,6 +15,7 @@ # include "x86.h" # include "x86seg_common.h" # include "x86seg.h" +# include "x87_sf.h" # include "x87.h" # if defined(__linux__) || defined(__APPLE__) From 80eedca82af2c10a0727ab85a38050de43f3c9d8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 03:55:12 +0200 Subject: [PATCH 609/690] Comment out the workaround for duplicate harfbuzz variales - it appears to no longer be needed. --- src/printer/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index dea0c7fbe..9fc555965 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -26,9 +26,9 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2) target_link_libraries(86Box PkgConfig::FREETYPE) if(STATIC_BUILD) - if(QT) + # if(QT) # Qt provides its own version of harfbuzz which leads to duplicated symbols. - target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") - endif() + # target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") + # endif() target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) endif() From 3374246436219c62cd777790743720996689f907 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 10 Jun 2024 14:19:32 -0400 Subject: [PATCH 610/690] Build support for macos silicon --- .github/workflows/cmake_macos.yml | 101 ++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 5a9f31a01..28b03d9ac 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -124,3 +124,104 @@ jobs: with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' path: build/artifacts/** + + macos14-arm64: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, arm64" + + runs-on: macos-14 + +# env: +# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: +# - name: ODR +# new: off +# slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + static: on + src-packages: >- + libsndfile + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qt@5 + src-packages: >- + libsndfile + + steps: + - name: Install source dependencies + run: >- + brew reinstall -s + ${{ matrix.ui.src-packages }} + + - name: Install dependencies + run: >- + brew install + ninja + freetype + sdl2 + libpng + rtmidi + openal-soft + fluidsynth + libslirp + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + +# - name: Install sonar-scanner and build-wrapper +# uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/llvm-macos-aarch64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D Qt5_ROOT=$(brew --prefix qt@5) + -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) + -D OpenAL_ROOT=$(brew --prefix openal-soft) + + - name: Build + run: | + cmake --build build + +# - name: Run sonar-scanner +# if: 0 +# env: +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# run: | +# sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-arm64-gha${{ github.run_number }}' + path: build/artifacts/** From f73dff6d768a7eb7f94336d596595516d72f5e81 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 10 Jun 2024 14:58:37 -0400 Subject: [PATCH 611/690] freetype & libpng are installed by default on mac --- .github/workflows/cmake_macos.yml | 4 ---- .github/workflows/codeql_macos.yml | 2 -- 2 files changed, 6 deletions(-) diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 28b03d9ac..f70b7334a 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -76,9 +76,7 @@ jobs: run: >- brew install ninja - freetype sdl2 - libpng rtmidi openal-soft fluidsynth @@ -176,9 +174,7 @@ jobs: run: >- brew install ninja - freetype sdl2 - libpng rtmidi openal-soft fluidsynth diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 6d2c3861f..adf34cb54 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -70,9 +70,7 @@ jobs: run: >- brew install ninja - freetype sdl2 - libpng rtmidi openal-soft fluidsynth From 7411fda449483bd5b86a2193ff371a52640d5302 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 10 Jun 2024 15:16:17 -0400 Subject: [PATCH 612/690] Switch sonarcloud scanner to git release This is temporary till it gets a new update --- .github/workflows/cmake_linux.yml | 2 +- .github/workflows/cmake_macos.yml | 4 ++-- .github/workflows/cmake_windows_msys2.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 04238ece0..f1ef973c4 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -88,7 +88,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 + uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - name: Configure CMake run: >- diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index f70b7334a..045626cd1 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -88,7 +88,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 + uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - name: Configure CMake run: >- @@ -187,7 +187,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis # - name: Install sonar-scanner and build-wrapper -# uses: SonarSource/sonarcloud-github-c-cpp@v2 +# uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - name: Configure CMake run: >- diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 36442684a..d415c7821 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -111,7 +111,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 + uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - name: Configure CMake run: >- From 2e9dbcac9c3c4983cb460e89a37cd4825ca2b6c9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Jun 2024 22:44:00 +0200 Subject: [PATCH 613/690] device.c: Add workaround for "SoundBlaster PCI" names. --- src/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.c b/src/device.c index 8517045e2..6fadc901b 100644 --- a/src/device.c +++ b/src/device.c @@ -536,7 +536,7 @@ device_get_name(const device_t *dev, int bus, char *name) strcat(name, tname + strlen(sbus) + 1); /* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or the "-ISA" from "AMD PCnet-ISA". */ - else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-')) + else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-') || (*(fbus - 2) == 'r')) strcat(name, tname); else { strncat(name, tname, fbus - tname - 1); From e3c39170ad3adab87d121375d0341fad1c3f6bc2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Jun 2024 19:03:31 -0300 Subject: [PATCH 614/690] Re-enable harfbuzz duplicate symbol workaround for now as my gcc 13 setup triggers it --- src/printer/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 9fc555965..274226a5a 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -28,7 +28,7 @@ target_link_libraries(86Box PkgConfig::FREETYPE) if(STATIC_BUILD) # if(QT) # Qt provides its own version of harfbuzz which leads to duplicated symbols. - # target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") + target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") # endif() target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) endif() From e9ef0e470d1b858430ee10a79251ce7137f2a66f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Jun 2024 19:17:55 -0300 Subject: [PATCH 615/690] AudioPCI: Add base ES1373 and CT5880 emulation --- src/include/86box/sound.h | 4 + src/sound/snd_audiopci.c | 376 ++++++++++++++++++++++++++++++++------ src/sound/sound.c | 2 + 3 files changed, 323 insertions(+), 59 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 9896b5422..9895e73d7 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -179,6 +179,10 @@ extern const device_t ess_chipchat_16_mca_device; /* Ensoniq AudioPCI */ extern const device_t es1371_device; extern const device_t es1371_onboard_device; +extern const device_t es1373_device; +extern const device_t es1373_onboard_device; +extern const device_t ct5880_device; +extern const device_t ct5880_onboard_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 1405d8769..4b512bb1d 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Ensoniq AudioPCI (ES1371) emulation. + * Ensoniq AudioPCI family emulation. * * * @@ -15,7 +15,7 @@ * Miran Grca, * * Copyright 2008-2021 Sarah Walker. - * Copyright 2021 RichardG. + * Copyright 2021-2024 RichardG. * Copyright 2021 Miran Grca. */ #include @@ -50,6 +50,9 @@ typedef struct es1371_t { uint8_t pci_command; uint8_t pci_serr; + uint8_t subsys_lock; + uint8_t subsys_id[4]; + uint32_t base_addr; uint8_t int_line; @@ -60,6 +63,7 @@ typedef struct es1371_t { uint32_t int_ctrl; uint32_t int_status; uint32_t legacy_ctrl; + uint32_t spdif_chstatus; void *gameport; int mem_page; @@ -126,9 +130,13 @@ typedef struct es1371_t { int pos; int16_t buffer[SOUNDBUFLEN * 2]; - int type; + uint32_t type; } es1371_t; +#define AUDIOPCI_ES1371 0x13710200 +#define AUDIOPCI_ES1373 0x13710400 +#define AUDIOPCI_CT5880 0x58800400 + #define LEGACY_SB_ADDR (1 << 29) #define LEGACY_SSCAPE_ADDR_SHIFT 27 #define LEGACY_CODEC_ADDR_SHIFT 25 @@ -160,6 +168,8 @@ typedef struct es1371_t { #define CODEC_READ (1 << 23) #define CODEC_READY (1 << 31) +#define INT_DAC1_BYPASS (1 << 31) +#define INT_DAC2_BYPASS (1 << 30) #define INT_DAC1_EN (1 << 6) #define INT_DAC2_EN (1 << 5) #define INT_UART_EN (1 << 3) @@ -324,13 +334,18 @@ es1371_reset(void *priv) nmi = 0; + /* Default subsystem ID. */ + dev->subsys_lock = 0x00; + *((uint16_t *) &dev->subsys_id[0]) = 0x1274; + *((uint16_t *) &dev->subsys_id[2]) = 0x1371; + /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ dev->int_ctrl = 0xfcff0000; - /* Interrupt/Chip Select Control Register, Address 00H + /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ - dev->int_status = 0x7ffffec0; + dev->int_status = (dev->type >= AUDIOPCI_ES1373) ? 0x7f080ec0 : 0x7ffffec0; /* UART Status Register, Address 09H Addressable as byte only */ @@ -360,6 +375,10 @@ es1371_reset(void *priv) Addressable as byte, word, longword */ dev->legacy_ctrl = 0x0000f801; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + dev->spdif_chstatus = 0xc0200004; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ dev->si_cr = 0xff800000; @@ -655,7 +674,9 @@ es1371_inb(uint16_t port, void *priv) ret = (dev->int_ctrl >> 16) & 0x0f; break; case 0x03: - ret = ((dev->int_ctrl >> 24) & 0x03) | 0xfc; + ret = dev->int_ctrl >> 24; + if (dev->type < AUDIOPCI_ES1373) + ret |= 0xfc; break; /* Interrupt/Chip Select Status Register, Address 04H @@ -724,6 +745,25 @@ es1371_inb(uint16_t port, void *priv) ret = dev->legacy_ctrl >> 24; break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus & 0xff; + break; + case 0x1d: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus >> 8; + break; + case 0x1e: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus >> 16; + break; + case 0x1f: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus >> 24; + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -760,7 +800,9 @@ es1371_inw(uint16_t port, void *priv) ret = dev->int_ctrl & 0xffff; break; case 0x02: - ret = ((dev->int_ctrl >> 16) & 0x030f) | 0xfc00; + ret = (dev->int_ctrl >> 16) & 0xff0f; + if (dev->type < AUDIOPCI_ES1373) + ret |= 0xfc00; break; /* Memory Page Register, Address 0CH @@ -781,6 +823,17 @@ es1371_inw(uint16_t port, void *priv) ret = dev->legacy_ctrl >> 16; break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus & 0xffff; + break; + case 0x1e: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus >> 16; + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -849,7 +902,9 @@ es1371_inl(uint16_t port, void *priv) /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: - ret = (dev->int_ctrl & 0x030fffff) | 0xfc000000; + ret = dev->int_ctrl & 0xff0fffff; + if (ret < AUDIOPCI_ES1373) + ret |= 0xfc000000; break; /* Interrupt/Chip Select Status Register, Address 04H @@ -884,6 +939,13 @@ es1371_inl(uint16_t port, void *priv) ret = (dev->legacy_ctrl & 0xffff07fd) | 0x0000f800; break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + if (dev->type >= AUDIOPCI_ES1373) + ret = dev->spdif_chstatus; + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -960,6 +1022,14 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); break; + /* Interrupt/Chip Select Status Register, Address 04H + Addressable as longword only, but PCem implements byte access, which + must be for a reason */ + case 0x06: + if (dev->type >= AUDIOPCI_ES1373) + dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); + break; + /* UART Data Register, Address 08H Addressable as byte only */ case 0x08: @@ -1021,6 +1091,21 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) update_legacy(dev, old_legacy_ctrl); break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + dev->spdif_chstatus = (dev->spdif_chstatus & 0xffffff00) | val; + break; + case 0x1d: + dev->spdif_chstatus = (dev->spdif_chstatus & 0xffff00ff) | (val << 8); + break; + case 0x1e: + dev->spdif_chstatus = (dev->spdif_chstatus & 0xff00ffff) | (val << 16); + break; + case 0x1f: + dev->spdif_chstatus = (dev->spdif_chstatus & 0x00ffffff) | (val << 24); + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -1092,6 +1177,15 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) update_legacy(dev, old_legacy_ctrl); break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + dev->spdif_chstatus = (dev->spdif_chstatus & 0xffff0000) | val; + break; + case 0x1e: + dev->spdif_chstatus = (dev->spdif_chstatus & 0x0000ffff) | (val << 16); + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -1161,6 +1255,8 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) Addressable as longword only */ case 0x04: audiopci_log("[W] STATUS = %08X\n", val); + if (dev->type >= AUDIOPCI_ES1373) + dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; /* Memory Page Register, Address 0CH @@ -1245,6 +1341,12 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) update_legacy(dev, old_legacy_ctrl); break; + /* S/PDIF Channel Status Control Register, Address 1CH + Addressable as byte, word, longword */ + case 0x1c: + dev->spdif_chstatus = val; + break; + /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: @@ -1612,9 +1714,9 @@ es1371_pci_read(int func, int addr, void *priv) return 0x12; case 0x02: - return 0x71; /* ES1371 */ + return dev->type >> 16; /* ES1371 */ case 0x03: - return 0x13; + return dev->type >> 24; case 0x04: return dev->pci_command; @@ -1627,7 +1729,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x00; case 0x08: - return 0x02; /* Revision ID - 0x02 is actual Ensoniq-branded ES1371 */ + return dev->type >> 8; /* Revision ID */ case 0x09: return 0x00; /* Multimedia audio device */ case 0x0a: @@ -1644,14 +1746,8 @@ es1371_pci_read(int func, int addr, void *priv) case 0x13: return dev->base_addr >> 24; - case 0x2c: - return 0x74; /* Subsystem vendor ID */ - case 0x2d: - return 0x12; - case 0x2e: - return 0x71; - case 0x2f: - return 0x13; + case 0x2c ... 0x2f: + return dev->subsys_id[addr & 3]; /* Subsystem vendor ID */ case 0x34: return 0xdc; /* Capabilites pointer */ @@ -1666,6 +1762,11 @@ es1371_pci_read(int func, int addr, void *priv) case 0x3f: return 0x80; /* Maximum latency */ + case 0x40: + if (dev->type >= AUDIOPCI_ES1373) + return dev->subsys_lock; + break; + case 0xdc: return 0x01; /* Capabilities identifier */ case 0xdd: @@ -1732,10 +1833,20 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) dev->base_addr = (dev->base_addr & 0x00ffffc0) | (val << 24); break; + case 0x2c ... 0x2f: + if ((dev->type >= AUDIOPCI_ES1373) && (dev->subsys_lock == 0xea)) + dev->subsys_id[addr & 3] = val; + break; + case 0x3c: dev->int_line = val; break; + case 0x40: + if (dev->type >= AUDIOPCI_ES1373) + dev->subsys_lock = val; + break; + case 0xe0: dev->pmcsr = (dev->pmcsr & 0xff00) | (val & 0x03); break; @@ -1941,51 +2052,77 @@ es1371_poll(void *priv) es1371_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - frac = dev->dac[0].ac & 0x7fff; - idx = dev->dac[0].ac >> 15; - samp1_l = dev->dac[0].filtered_l[idx]; - samp1_r = dev->dac[0].filtered_r[idx]; - samp2_l = dev->dac[0].filtered_l[(idx + 1) & 31]; - samp2_r = dev->dac[0].filtered_r[(idx + 1) & 31]; + if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) { + /* SRC bypass. */ + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) + es1371_fetch(dev, 0); - dev->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - dev->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; - dev->dac[0].ac += dev->dac[0].vf; - dev->dac[0].ac &= ((32 << 15) - 1); - if ((dev->dac[0].ac >> (15 + 4)) != dev->dac[0].f_pos) { - es1371_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); - dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; + dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; + dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; + dev->dac[0].buffer_pos++; - dev->dac[0].curr_samp_ct--; - if (dev->dac[0].curr_samp_ct < 0) { - dev->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(dev); - dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; + goto dac0_count; + } else { + frac = dev->dac[0].ac & 0x7fff; + idx = dev->dac[0].ac >> 15; + samp1_l = dev->dac[0].filtered_l[idx]; + samp1_r = dev->dac[0].filtered_r[idx]; + samp2_l = dev->dac[0].filtered_l[(idx + 1) & 31]; + samp2_r = dev->dac[0].filtered_r[(idx + 1) & 31]; + + dev->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + dev->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + dev->dac[0].ac += dev->dac[0].vf; + dev->dac[0].ac &= ((32 << 15) - 1); + if ((dev->dac[0].ac >> (15 + 4)) != dev->dac[0].f_pos) { + es1371_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); + dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; + +dac0_count: + dev->dac[0].curr_samp_ct--; + if (dev->dac[0].curr_samp_ct < 0) { + dev->int_status |= INT_STATUS_DAC1; + es1371_update_irqs(dev); + dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; + } } } } if (dev->int_ctrl & INT_DAC2_EN) { - frac = dev->dac[1].ac & 0x7fff; - idx = dev->dac[1].ac >> 15; - samp1_l = dev->dac[1].filtered_l[idx]; - samp1_r = dev->dac[1].filtered_r[idx]; - samp2_l = dev->dac[1].filtered_l[(idx + 1) & 31]; - samp2_r = dev->dac[1].filtered_r[(idx + 1) & 31]; + if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) { + /* SRC bypass. */ + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) + es1371_fetch(dev, 1); - dev->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - dev->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; - dev->dac[1].ac += dev->dac[1].vf; - dev->dac[1].ac &= ((32 << 15) - 1); - if ((dev->dac[1].ac >> (15 + 4)) != dev->dac[1].f_pos) { - es1371_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); - dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; + dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; + dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; + dev->dac[1].buffer_pos++; - dev->dac[1].curr_samp_ct--; - if (dev->dac[1].curr_samp_ct < 0) { - dev->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(dev); - dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; + goto dac1_count; + } else { + frac = dev->dac[1].ac & 0x7fff; + idx = dev->dac[1].ac >> 15; + samp1_l = dev->dac[1].filtered_l[idx]; + samp1_r = dev->dac[1].filtered_r[idx]; + samp2_l = dev->dac[1].filtered_l[(idx + 1) & 31]; + samp2_r = dev->dac[1].filtered_r[(idx + 1) & 31]; + + dev->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + dev->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + dev->dac[1].ac += dev->dac[1].vf; + dev->dac[1].ac &= ((32 << 15) - 1); + if ((dev->dac[1].ac >> (15 + 4)) != dev->dac[1].f_pos) { + es1371_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); + dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; + +dac1_count: + dev->dac[1].curr_samp_ct--; + if (dev->dac[1].curr_samp_ct < 0) { + dev->int_status |= INT_STATUS_DAC2; + es1371_update_irqs(dev); + dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; + } } } } @@ -2091,6 +2228,7 @@ es1371_init(const device_t *info) { es1371_t *dev = malloc(sizeof(es1371_t)); memset(dev, 0x00, sizeof(es1371_t)); + dev->type = info->local & 0xffffff00; if (device_get_config_int("receive_input")) midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); @@ -2101,7 +2239,7 @@ es1371_init(const device_t *info) dev->gameport = gameport_add(&gameport_pnp_device); gameport_remap(dev->gameport, 0x200); - pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); + pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); @@ -2111,7 +2249,7 @@ es1371_init(const device_t *info) ac97_codec_count = 1; ac97_codec_id = 0; /* Let the machine decide the codec on onboard implementations. */ - if (!info->local) + if (!(info->local & 1)) device_add(ac97_codec_get(device_get_config_int("codec"))); es1371_reset(dev); @@ -2165,6 +2303,70 @@ static const device_config_t es1371_config[] = { // clang-format on }; +static const device_config_t es1373_config[] = { + // clang-format off + { + .name = "codec", + .description = "Codec", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "Crystal CS4297A", + .value = AC97_CODEC_CS4297A + }, + { + .description = "SigmaTel STAC9721T", + .value = AC97_CODEC_STAC9721 + }, + { + .description = "TriTech TR28023 / Creative CT1297", + .value = AC97_CODEC_TR28023 + }, + { .description = "" } + }, + .default_int = AC97_CODEC_CS4297A + }, + { + .name = "receive_input", + .description = "Receive input (MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_config_t ct5880_config[] = { + // clang-format off + { + .name = "codec", + .description = "Codec", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "SigmaTel STAC9708T", + .value = AC97_CODEC_STAC9708 + }, + { + .description = "SigmaTel STAC9721T (stereo)", + .value = AC97_CODEC_STAC9721 + }, + { .description = "" } + }, + .default_int = AC97_CODEC_STAC9708 + }, + { + .name = "receive_input", + .description = "Receive input (MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t es1371_onboard_config[] = { // clang-format off { @@ -2182,7 +2384,7 @@ const device_t es1371_device = { .name = "Ensoniq AudioPCI (ES1371)", .internal_name = "es1371", .flags = DEVICE_PCI, - .local = 0, + .local = AUDIOPCI_ES1371, .init = es1371_init, .close = es1371_close, .reset = es1371_reset, @@ -2196,7 +2398,63 @@ const device_t es1371_onboard_device = { .name = "Ensoniq AudioPCI (ES1371) (On-Board)", .internal_name = "es1371_onboard", .flags = DEVICE_PCI, - .local = 1, + .local = AUDIOPCI_ES1371 | 1, + .init = es1371_init, + .close = es1371_close, + .reset = es1371_reset, + { .available = NULL }, + .speed_changed = es1371_speed_changed, + .force_redraw = NULL, + .config = es1371_onboard_config +}; + +const device_t es1373_device = { + .name = "Sound Blaster PCI 128 (ES1373)", + .internal_name = "es1373", + .flags = DEVICE_PCI, + .local = AUDIOPCI_ES1373, + .init = es1371_init, + .close = es1371_close, + .reset = es1371_reset, + { .available = NULL }, + .speed_changed = es1371_speed_changed, + .force_redraw = NULL, + .config = es1373_config +}; + +const device_t es1373_onboard_device = { + .name = "Sound Blaster PCI 128 (ES1373) (On-Board)", + .internal_name = "es1373_onboard", + .flags = DEVICE_PCI, + .local = AUDIOPCI_ES1373 | 1, + .init = es1371_init, + .close = es1371_close, + .reset = es1371_reset, + { .available = NULL }, + .speed_changed = es1371_speed_changed, + .force_redraw = NULL, + .config = es1371_onboard_config +}; + +const device_t ct5880_device = { + .name = "Sound Blaster PCI 4.1 (CT5880)", + .internal_name = "ct5880", + .flags = DEVICE_PCI, + .local = AUDIOPCI_CT5880, + .init = es1371_init, + .close = es1371_close, + .reset = es1371_reset, + { .available = NULL }, + .speed_changed = es1371_speed_changed, + .force_redraw = NULL, + .config = ct5880_config +}; + +const device_t ct5880_onboard_device = { + .name = "Sound Blaster PCI 4.1 (CT5880) (On-Board)", + .internal_name = "ct5880_onboard", + .flags = DEVICE_PCI, + .local = AUDIOPCI_CT5880 | 1, .init = es1371_init, .close = es1371_close, .reset = es1371_reset, diff --git a/src/sound/sound.c b/src/sound/sound.c index f527cbc61..f941c8817 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -172,6 +172,8 @@ static const SOUND_CARD sound_cards[] = { { &cmi8338_device }, { &cmi8738_device }, { &es1371_device }, + { &es1373_device }, + { &ct5880_device }, { &ad1881_device }, { &cs4297a_device }, { &ess_688_device }, From ba4a1daf91dabb0522d6abc4aa564cad8bb23fe6 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Jun 2024 19:36:47 -0300 Subject: [PATCH 616/690] Add ES1373 to machines that were missing it --- src/machine/m_at_slot1.c | 16 +++++++++------- src/machine/m_at_socket370.c | 4 ++-- src/machine/m_at_sockets7.c | 5 +++++ src/machine/machine_table.c | 18 +++++++++--------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index d1486b579..b92815ede 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -530,8 +530,8 @@ machine_at_s1846_init(const machine_t *model) spd_register(SPD_TYPE_SDRAM, 0x7, 256); if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); - device_add(&cs4297_device); /* found on other Tyan boards around the same time */ + device_add(machine_get_snd_device(machine)); + device_add(&ct1297_device); /* no good pictures, but the marking looks like CT1297 from a distance */ } return ret; @@ -675,7 +675,7 @@ machine_at_gt694va_init(const machine_t *model) hwm_values.temperatures[2] = 0; /* unused */ if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); + device_add(machine_get_snd_device(machine)); device_add(&cs4297_device); /* assumed */ } @@ -739,7 +739,7 @@ machine_at_ms6168_common_init(const machine_t *model) spd_register(SPD_TYPE_SDRAM, 0x3, 256); if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); + device_add(machine_get_snd_device(machine)); device_add(&cs4297_device); } } @@ -823,19 +823,21 @@ machine_at_p6f99_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUND, 2, 3, 4, 1); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_SOUND, 2, 3, 4, 1); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); device_add(&sis_5600_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&it8661f_device); device_add(&winbond_flash_w29c020_device); - if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&es1371_onboard_device); + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(machine_get_snd_device(machine)); + device_add(&ct1297_device); + } return ret; } diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 010aee3da..6d7b8c710 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -105,8 +105,8 @@ machine_at_s1857_init(const machine_t *model) spd_register(SPD_TYPE_SDRAM, 0x7, 256); if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); - device_add(&cs4297_device); /* found on other Tyan boards around the same time */ + device_add(machine_get_snd_device(machine)); + device_add(&cs4297_device); /* no good pictures, but the marking looks like CS4297 from a distance */ } return ret; diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 32319e160..fe6983733 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -135,6 +135,11 @@ machine_at_gwlucas_init(const machine_t *model) device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(machine_get_snd_device(machine)); + device_add(&cs4297_device); + } + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index da3df57b6..31a86bd5c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12886,7 +12886,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCIONLY | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 262144, @@ -12901,7 +12901,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &es1373_onboard_device, .net_device = NULL }, /* Has the ALi M1543C southbridge with on-chip KBC. */ @@ -14288,7 +14288,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1371 */ .ram = { .min = 8192, .max = 1048576, @@ -14387,7 +14387,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &voodoo_3_2000_agp_onboard_8m_device, - .snd_device = NULL, + .snd_device = &es1373_onboard_device, .net_device = NULL }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC @@ -14428,7 +14428,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &voodoo_3_2000_agp_onboard_8m_device, - .snd_device = NULL, + .snd_device = &es1373_onboard_device, .net_device = NULL }, @@ -14637,7 +14637,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = &es1371_onboard_device, + .snd_device = &es1373_onboard_device, .net_device = NULL }, @@ -14679,7 +14679,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ + .snd_device = &es1373_onboard_device, .net_device = NULL }, /* Has the SiS (5)600 chipset with on-chip KBC. */ @@ -14792,7 +14792,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14807,7 +14807,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = &es1371_onboard_device, + .snd_device = &es1373_onboard_device, .net_device = NULL }, /* VIA Apollo Pro */ From bf4977b20c3ab4f8ef4e9044264085d598be2690 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 11 Jun 2024 03:51:15 +0500 Subject: [PATCH 617/690] mem.c: Remove duplicate definitions (#4524) Fixes building with debug registers for 486+ enabled --- src/mem/mem.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/mem/mem.c b/src/mem/mem.c index 5fe7f3c29..0e06fbfca 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -164,46 +164,6 @@ mem_log(const char *fmt, ...) # define mem_log(fmt, ...) #endif -#ifdef USE_DEBUG_REGS_486 -/* As below, 1 = exec, 4 = read. */ -int read_type = 4; - -/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */ -void -mem_debug_check_addr(uint32_t addr, int flags) -{ - uint32_t bp_addr; - uint32_t bp_mask; - uint32_t len_type_pair; - int bp_enabled; - uint8_t match_flags[4] = { 0, 2, 0, 6 }; - - if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) - return; - - if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) { - bp_addr = dr[i]; - bp_enabled = (dr[7] >> (i << 1)) & 0x03; - len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f; - bp_mask = ~((len_type_pair >> 2) & 0x03); - - if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) { - /* - From the Intel i386 documemntation: - - (Note that the processor sets Bn regardless of whether Gn or - Ln is set. If more than one breakpoint condition occurs at one time and if - the breakpoint trap occurs due to an enabled condition other than n, Bn may - be set, even though neither Gn nor Ln is set.) - */ - dr[6] |= (1 << i); - if (bp_enabled) - trap |= (read_type == 1) ? 8 : 4; - } - } -} -#endif - int mem_addr_is_ram(uint32_t addr) { From ec0998a0896a53e63b9140fc53c28414ddf6965b Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 11 Jun 2024 03:58:24 +0500 Subject: [PATCH 618/690] Add onboard C&T 69000 video to the ADLink NuPRO-592 (#4525) * Give the ADLink NuPRO-592 the onboard C&T 69000 This turns it into the 591 model, if the internal video is chosen * Use machine_get_vid_device --- src/machine/m_at_socket7.c | 8 ++++++-- src/machine/machine_table.c | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 49ad043e8..d13f0039a 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -869,13 +869,17 @@ machine_at_nupro592_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_VIDEO, 3, 4, 1, 2); /* C&T B69000 */ + pci_register_slot(0x0C, PCI_CARD_NETWORK, 4, 1, 2, 3); /* Intel 82559 */ pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); /*Strongly suspect these are on-board slots*/ - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + device_add(&i430tx_device); device_add(&piix4_device); device_add(&keyboard_ps2_ami_pci_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 31a86bd5c..b6ea732af 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11922,7 +11922,7 @@ const machine_t machines[] = { /* 430TX */ /* The BIOS sends KBC command B8, CA, and CB, so it has an AMI KBC firmware. */ { - .name = "[i430TX] ADLink NuPRO-592", + .name = "[i430TX] ADLink NuPRO-591/592", .internal_name = "nupro592", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -11942,7 +11942,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Has internal video: C&T B69000 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO, .ram = { .min = 8192, .max = 262144, @@ -11956,7 +11956,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &chips_69000_onboard_device, .snd_device = NULL, .net_device = NULL }, From eaed7643c0f5e3de0f165803c41a98f16e4a3509 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 11 Jun 2024 01:29:00 +0200 Subject: [PATCH 619/690] ET4000 RAMDAC break fix. This should fix the black screens when returning to text mode after the GUI. --- src/video/vid_et4000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 583487c5f..c223d37ba 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -145,6 +145,7 @@ et4000_in(uint16_t addr, void *priv) case 0x3c9: if (dev->type >= ET4000_TYPE_ISA) return sc1502x_ramdac_in(addr, svga->ramdac, svga); + break; case 0x3cd: /*Banking*/ return dev->banking; From 19f4d4f914a6f2159726bf889f45b0dce5b4916b Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 10 Jun 2024 19:36:33 -0400 Subject: [PATCH 620/690] Fix 10 more warnings in the code --- src/floppy/fdd_pcjs.c | 4 +--- src/qt/dummy_cdrom_ioctl.c | 6 ------ src/unix/dummy_cdrom_ioctl.c | 6 ------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/floppy/fdd_pcjs.c b/src/floppy/fdd_pcjs.c index f96af5c5f..b7b3cc69d 100644 --- a/src/floppy/fdd_pcjs.c +++ b/src/floppy/fdd_pcjs.c @@ -276,7 +276,7 @@ int json_parse(pcjs_t *dev) } /* Read and null terminate */ - fread(buffer, sizeof(char), numbytes, dev->fp); + (void) !fread(buffer, sizeof(char), numbytes, dev->fp); buffer[numbytes] = '\0'; cJSON *parsed_json = cJSON_Parse(buffer); @@ -305,7 +305,6 @@ int json_parse(pcjs_t *dev) const cJSON *each_track = NULL; int total_c = 0; - int full_count = 0; /* The diskData array is essentially [c][h][s] */ /* Start with the tracks in [c] */ @@ -422,7 +421,6 @@ int json_parse(pcjs_t *dev) } total_sectors++; - full_count++; dev->calc_total_sectors = total_sectors; /* End sectors */ } diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index cb0824675..5c533b216 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -167,8 +167,6 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF int plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - long size = 0; - *track = 1; *attr = 0x14; *index = 1; @@ -197,10 +195,6 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) { - int status; - long size = 0; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - plat_cdrom_open(); if (raw) { diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index cb0824675..5c533b216 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -167,8 +167,6 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF int plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - long size = 0; - *track = 1; *attr = 0x14; *index = 1; @@ -197,10 +195,6 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) { - int status; - long size = 0; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - plat_cdrom_open(); if (raw) { From 5b8bf0239913998047798c240363e1c7a7181ef8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 11 Jun 2024 02:35:38 +0200 Subject: [PATCH 621/690] Fix a bug in dma_advance(). --- src/dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dma.c b/src/dma.c index 0593d0395..1c23c53c2 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1411,7 +1411,7 @@ dma_retreat(dma_t *dma_c) dma_c->page = dma_c->page_l = (dma_c->ac >> 16) & 0xff; dma_c->page_h = (dma_c->ac >> 24) & 0xff; } else if (as == 2) - dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac - as) & 0xffff); + dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac - as) & 0x1ffff); else dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac - as) & 0xffff); } @@ -1427,7 +1427,7 @@ dma_advance(dma_t *dma_c) dma_c->page = dma_c->page_l = (dma_c->ac >> 16) & 0xff; dma_c->page_h = (dma_c->ac >> 24) & 0xff; } else if (as == 2) - dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); + dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac + as) & 0x1ffff); else dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); } From a8d3e788dada877d8c326106f3e2b2a14c8eacec Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Jun 2024 23:01:07 -0300 Subject: [PATCH 622/690] AudioPCI: Add some CT5880 specific bits; 4-channel not quite working yet --- src/machine/m_at_slot1.c | 2 +- src/sound/snd_audiopci.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index b92815ede..a870d4c59 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -676,7 +676,7 @@ machine_at_gt694va_init(const machine_t *model) if (sound_card_current[0] == SOUND_INTERNAL) { device_add(machine_get_snd_device(machine)); - device_add(&cs4297_device); /* assumed */ + device_add(&cs4297_device); /* no good pictures, but the marking looks like CS4297 from a distance */ } return ret; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 4b512bb1d..f8c14e06f 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -122,6 +122,8 @@ typedef struct es1371_t { int master_vol_r; int pcm_vol_l; int pcm_vol_r; + int pcm_rear_vol_l; + int pcm_rear_vol_r; int cd_vol_l; int cd_vol_r; @@ -180,6 +182,9 @@ typedef struct es1371_t { #define SI_P1_INTR_EN (1 << 8) #define INT_STATUS_INTR (1 << 31) +#define INT_STATUS_REAR_B27 (1 << 27) +#define INT_STATUS_REAR_B26 (1 << 26) +#define INT_STATUS_REAR_B24 (1 << 24) #define INT_STATUS_UART (1 << 3) #define INT_STATUS_DAC1 (1 << 2) #define INT_STATUS_DAC2 (1 << 1) @@ -345,7 +350,12 @@ es1371_reset(void *priv) /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ - dev->int_status = (dev->type >= AUDIOPCI_ES1373) ? 0x7f080ec0 : 0x7ffffec0; + if (dev->type >= AUDIOPCI_CT5880) + dev->int_status = 0x52080ec0; + else if (dev->type >= AUDIOPCI_ES1373) + dev->int_status = 0x7f080ec0; + else + dev->int_status = 0x7ffffec0; /* UART Status Register, Address 09H Addressable as byte only */ @@ -1029,6 +1039,10 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) if (dev->type >= AUDIOPCI_ES1373) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; + case 0x07: + if (dev->type >= AUDIOPCI_CT5880) + dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); + break; /* UART Data Register, Address 08H Addressable as byte only */ @@ -1255,7 +1269,9 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) Addressable as longword only */ case 0x04: audiopci_log("[W] STATUS = %08X\n", val); - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_CT5880) + dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); + else if (dev->type >= AUDIOPCI_ES1373) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1327,6 +1343,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) ac97_codec_getattn(dev->codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); ac97_codec_getattn(dev->codec, 0x18, &dev->pcm_vol_l, &dev->pcm_vol_r); + ac97_codec_getattn(dev->codec, 0x38, &dev->pcm_rear_vol_l, &dev->pcm_rear_vol_r); ac97_codec_getattn(dev->codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); } break; @@ -1834,7 +1851,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x2c ... 0x2f: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->subsys_lock == 0xea)) + if (dev->subsys_lock == 0xea) dev->subsys_id[addr & 3] = val; break; From f907b7817b7573be1ea30a7f479866f065fbcd6e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 4 May 2024 17:01:29 +0600 Subject: [PATCH 623/690] Microtouch support (working at least for MS-DOS, Windows 95 and Windows NT 3.5) --- src/device/CMakeLists.txt | 3 +- src/device/mouse.c | 1 + src/device/mouse_microtouch_touchscreen.c | 279 ++++++++++++++++++++++ src/include/86box/mouse.h | 1 + src/qt/qt_rendererstack.cpp | 2 +- 5 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 src/device/mouse_microtouch_touchscreen.c diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index c0719af2a..e48f30d0f 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -23,7 +23,8 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c serial_passthrough.c - novell_cardkey.c) + novell_cardkey.c + mouse_microtouch_touchscreen.c) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_link_libraries(86Box atomic) diff --git a/src/device/mouse.c b/src/device/mouse.c index da4ed1c04..8fd783ee2 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -98,6 +98,7 @@ static mouse_t mouse_devices[] = { { &mouse_wacom_device }, { &mouse_wacom_artpad_device }, #endif + { &mouse_mtouch_device }, { NULL } // clang-format on }; diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c new file mode 100644 index 000000000..50323210a --- /dev/null +++ b/src/device/mouse_microtouch_touchscreen.c @@ -0,0 +1,279 @@ + +/* TODO: + MN, SS, SF commands (sensitivity-related). + GP/SP commands (formats are not documented at all). + GF, FQF, FQP (what are those for?) +*/ +#include +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/mouse.h> +#include <86box/serial.h> +#include <86box/plat.h> +#include <86box/fifo8.h> +#include <86box/fifo.h> + +enum mtouch_modes +{ + MODE_TABLET = 1, + MODE_RAW = 2 +}; + +typedef struct mouse_microtouch_t { + double abs_x; + double abs_y; + int oldb; + int b; + char cmd[512]; + int bits; + int baud_rate_sel; + int cmd_pos; + int mode; + double rate; + bool soh; + bool in_reset; + serial_t *serial; + Fifo8 resp; + pc_timer_t host_to_serial_timer; + pc_timer_t reset_timer; +} mouse_microtouch_t; + +static mouse_microtouch_t* mtouch_inst = NULL; + +void microtouch_reset_complete(void *priv) +{ + mouse_microtouch_t *mtouch = (mouse_microtouch_t*)priv; + + mtouch->in_reset = false; + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); +} + +void microtouch_process_commands(mouse_microtouch_t* mtouch) +{ + int i = 0; + mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; + mtouch->cmd_pos = 0; + pclog("Command received: %s\n", mtouch->cmd); + for (i = 0; i < strlen(mtouch->cmd); i++) { + mtouch->cmd[i] = toupper(mtouch->cmd[i]); + } + /* Re-enable and finish this if actually needed by TouchPen. */ + if (mtouch->cmd[0] == 'Z' || (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O')) { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "QM****00\r", sizeof("QM****00\r") - 1); + } + if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "Q10200\r", sizeof("Q10200\r") - 1); + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { + mtouch->mode = MODE_TABLET; + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'R') { + mtouch->in_reset = true; + mtouch->mode = MODE_TABLET; + timer_on_auto(&mtouch->reset_timer, 500. * 1000.); + } + if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'N' && mtouch->cmd[1] == 'M') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'Q') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + } + if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'F') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + } +} + +void mtouch_write_to_host(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; + if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { + if (fifo_get_full(dev->serial->rcvr_fifo)) { + goto no_write_to_machine; + } + } else { + if (dev->serial->lsr & 1) { + goto no_write_to_machine; + } + } + + if (dev->in_reset) + goto no_write_to_machine; + + if (fifo8_num_used(&dev->resp)) { + serial_write_fifo(dev->serial, fifo8_pop(&dev->resp)); + } + +no_write_to_machine: + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) 9600.0) * (double) (1 + 8 + 1)); +} + +void mtouch_write(serial_t* serial, void* priv, uint8_t data) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; + if (!dev->soh && data == 0x11) { + pclog("\n"); + } + if (data == '\x1'){ + dev->soh = 1; + } else if (dev->soh) { + if (data != '\r') { + dev->cmd[dev->cmd_pos++] = data; + } else { + dev->cmd[dev->cmd_pos++] = data; + microtouch_process_commands(dev); + } + } +} + +static int +mtouch_poll(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; + + if (dev->mode != MODE_RAW && fifo8_num_free(&dev->resp) >= 10) { + unsigned int abs_x_int = 0, abs_y_int = 0; + double abs_x; + double abs_y; + int b = mouse_get_buttons_ex(); + mouse_get_abs_coords(&abs_x, &abs_y); + dev->b |= b & 1; + if (abs_x >= 1.0) + abs_x = 1.0; + if (abs_y >= 1.0) + abs_y = 1.0; + if (abs_x <= 0.0) + abs_x = 0.0; + if (abs_y <= 0.0) + abs_y = 0.0; + if (b & 1) { + dev->abs_x = abs_x; + dev->abs_y = abs_y; + dev->b |= 1; + + abs_x_int = abs_x * 16383; + abs_y_int = 16383 - abs_y * 16383; + + fifo8_push(&dev->resp, 0b11000000); + fifo8_push(&dev->resp, abs_x_int & 0b1111111); + fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); + fifo8_push(&dev->resp, abs_y_int & 0b1111111); + fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); + } else if ((dev->b & 1) && !(b & 1)) { + dev->b &= ~1; + abs_x_int = dev->abs_x * 16383; + abs_y_int = 16383 - dev->abs_y * 16383; + fifo8_push(&dev->resp, 0b11000000); + fifo8_push(&dev->resp, abs_x_int & 0b1111111); + fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); + fifo8_push(&dev->resp, abs_y_int & 0b1111111); + fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); + fifo8_push(&dev->resp, 0b10000000); + fifo8_push(&dev->resp, abs_x_int & 0b1111111); + fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); + fifo8_push(&dev->resp, abs_y_int & 0b1111111); + fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); + } + } + return 0; +} + +static void mtouch_poll_global(void) +{ + mtouch_poll(mtouch_inst); +} + +void* mtouch_init(const device_t* info) +{ + mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t)); + + dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev); + fifo8_create(&dev->resp, 512); + timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); + timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); + timer_on_auto(&dev->host_to_serial_timer, (1000000. / 9600.) * 10); + dev->mode = MODE_TABLET; + mouse_input_mode = 1; + mouse_set_buttons(2); + mouse_set_poll_ex(mtouch_poll_global); + + mtouch_inst = dev; + + return dev; +} + +void mtouch_close(void* priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + fifo8_destroy(&dev->resp); + /* Detach serial port from the mouse. */ + if (dev && dev->serial && dev->serial->sd) + memset(dev->serial->sd, 0, sizeof(serial_device_t)); + + free(dev); + mtouch_inst = NULL; +} + +static const device_config_t mtouch_config[] = { + // clang-format off + { + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "COM1", .value = 0 }, + { .description = "COM2", .value = 1 }, + { .description = "COM3", .value = 2 }, + { .description = "COM4", .value = 3 }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t mouse_mtouch_device = { + .name = "3M MicroTouch SMT3", + .internal_name = "microtouch_touchpen", + .flags = DEVICE_COM, + .local = 0, + .init = mtouch_init, + .close = mtouch_close, + .reset = NULL, + { .poll = mtouch_poll }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mtouch_config +}; + diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 786b86f41..e9c1d9b4d 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -73,6 +73,7 @@ extern const device_t mouse_ltserial_device; extern const device_t mouse_ps2_device; extern const device_t mouse_wacom_device; extern const device_t mouse_wacom_artpad_device; +extern const device_t mouse_mtouch_device; #endif extern void mouse_clear_x(void); diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index bc4cb9c13..590c025e8 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -250,7 +250,7 @@ RendererStack::enterEvent(QEvent *event) mousedata.mouse_tablet_in_proximity = 1; if (mouse_input_mode == 1) - QApplication::setOverrideCursor(Qt::BlankCursor); + QApplication::setOverrideCursor(Qt::CrossCursor); } void From 7277316c1b7ea38ab5562da0b5a0a4721c5a8532 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 4 May 2024 23:36:09 +0600 Subject: [PATCH 624/690] Cursor override fixes and preparation for overscan checking --- src/qt/qt_mainwindow.cpp | 3 ++- src/qt/qt_rendererstack.cpp | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index c48dfd052..112d1cf23 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -205,7 +205,8 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::hardResetCompleted, this, [this]() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); - QApplication::setOverrideCursor(Qt::ArrowCursor); + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); #ifdef USE_WACOM ui->menuTablet_tool->menuAction()->setVisible(mouse_input_mode >= 1); #else diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 590c025e8..d043f823c 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -114,7 +114,8 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) RendererStack::~RendererStack() { - QApplication::restoreOverrideCursor(); + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); delete ui; } @@ -123,7 +124,7 @@ qt_mouse_capture(int on) { if (!on) { mouse_capture = 0; - if (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); + while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); #ifdef __APPLE__ CGAssociateMouseAndMouseCursorPosition(true); #endif @@ -247,7 +248,7 @@ RendererStack::enterEvent(QEnterEvent *event) RendererStack::enterEvent(QEvent *event) #endif { - mousedata.mouse_tablet_in_proximity = 1; + mousedata.mouse_tablet_in_proximity = m_monitor_index + 1; if (mouse_input_mode == 1) QApplication::setOverrideCursor(Qt::CrossCursor); @@ -258,8 +259,10 @@ RendererStack::leaveEvent(QEvent *event) { mousedata.mouse_tablet_in_proximity = 0; - if (mouse_input_mode == 1 && QApplication::overrideCursor()) - QApplication::restoreOverrideCursor(); + if (mouse_input_mode == 1 && QApplication::overrideCursor()) { + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); + } if (QApplication::platformName().contains("wayland")) { event->accept(); return; From 754f304deb86299f64e284e7db7da1d46806c993 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 5 May 2024 13:06:35 +0600 Subject: [PATCH 625/690] Overscan handling --- src/device/mouse_microtouch_touchscreen.c | 37 ++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 50323210a..e063260ea 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -19,6 +19,7 @@ #include <86box/plat.h> #include <86box/fifo8.h> #include <86box/fifo.h> +#include <86box/video.h> /* Needed to account for overscan. */ enum mtouch_modes { @@ -65,7 +66,6 @@ void microtouch_process_commands(mouse_microtouch_t* mtouch) for (i = 0; i < strlen(mtouch->cmd); i++) { mtouch->cmd[i] = toupper(mtouch->cmd[i]); } - /* Re-enable and finish this if actually needed by TouchPen. */ if (mtouch->cmd[0] == 'Z' || (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O')) { fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); @@ -87,6 +87,18 @@ void microtouch_process_commands(mouse_microtouch_t* mtouch) fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); } + if (mtouch->cmd[0] == 'P' && mtouch->cmd[1] == 'F') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'P' && mtouch->cmd[1] == 'O') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } if (mtouch->cmd[0] == 'R') { mtouch->in_reset = true; mtouch->mode = MODE_TABLET; @@ -172,6 +184,29 @@ mtouch_poll(void *priv) abs_x = 0.0; if (abs_y <= 0.0) abs_y = 0.0; + if (enable_overscan) { + int index = mouse_tablet_in_proximity - 1; + if (mouse_tablet_in_proximity == -1) + mouse_tablet_in_proximity = 0; + + abs_x *= monitors[index].mon_unscaled_size_x - 1; + abs_y *= monitors[index].mon_efscrnsz_y - 1; + + if (abs_x <= (monitors[index].mon_overscan_x / 2.)) { + abs_x = (monitors[index].mon_overscan_x / 2.); + } + if (abs_y <= (monitors[index].mon_overscan_y / 2.)) { + abs_y = (monitors[index].mon_overscan_y / 2.); + } + abs_x -= (monitors[index].mon_overscan_x / 2.); + abs_y -= (monitors[index].mon_overscan_y / 2.); + abs_x = abs_x / (double)monitors[index].mon_xsize; + abs_y = abs_y / (double)monitors[index].mon_ysize; + if (abs_x >= 1.0) + abs_x = 1.0; + if (abs_y >= 1.0) + abs_y = 1.0; + } if (b & 1) { dev->abs_x = abs_x; dev->abs_y = abs_y; From d9fa8bbb4a1eab05b04ea536f300c6d4fc8bd056 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 5 May 2024 14:25:31 +0600 Subject: [PATCH 626/690] Implement calibration --- src/device/mouse_microtouch_touchscreen.c | 48 +++++++++++++++++------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index e063260ea..14d400fbc 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -37,6 +37,7 @@ typedef struct mouse_microtouch_t { int baud_rate_sel; int cmd_pos; int mode; + uint8_t cal_cntr; double rate; bool soh; bool in_reset; @@ -57,6 +58,17 @@ void microtouch_reset_complete(void *priv) fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); } +void microtouch_calibrate_timer(void *priv) +{ + mouse_microtouch_t *mtouch = (mouse_microtouch_t*)priv; + + if (!fifo8_num_used(&mtouch->resp)) { + mtouch->cal_cntr--; + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + } +} + void microtouch_process_commands(mouse_microtouch_t* mtouch) { int i = 0; @@ -83,22 +95,16 @@ void microtouch_process_commands(mouse_microtouch_t* mtouch) fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { + mtouch->mode = MODE_RAW; + mtouch->cal_cntr = 0; + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); } - if (mtouch->cmd[0] == 'P' && mtouch->cmd[1] == 'F') { - fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); - } - if (mtouch->cmd[0] == 'P' && mtouch->cmd[1] == 'O') { - fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { - fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); - } if (mtouch->cmd[0] == 'R') { mtouch->in_reset = true; mtouch->mode = MODE_TABLET; @@ -120,6 +126,15 @@ void microtouch_process_commands(mouse_microtouch_t* mtouch) fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); } + if (mtouch->cmd[0] == 'P') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + } + if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + mtouch->cal_cntr = 2; + } } void mtouch_write_to_host(void *priv) @@ -207,6 +222,15 @@ mtouch_poll(void *priv) if (abs_y >= 1.0) abs_y = 1.0; } + if (dev->cal_cntr && (!(dev->b & 1) && (b & 1))) { + dev->b |= 1; + } else if (dev->cal_cntr && ((dev->b & 1) && !(b & 1))) { + dev->b &= ~1; + microtouch_calibrate_timer(dev); + } + if (dev->cal_cntr) { + return 0; + } if (b & 1) { dev->abs_x = abs_x; dev->abs_y = abs_y; From 34ec412bae9694619da6c42a7270f9cbed1a0539 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 5 May 2024 14:36:42 +0600 Subject: [PATCH 627/690] Cleanups and copyright text --- src/device/mouse_microtouch_touchscreen.c | 29 ++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 14d400fbc..568b6b15b 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -1,15 +1,28 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 3M MicroTouch SMT3 emulation. + * + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345 + */ /* TODO: - MN, SS, SF commands (sensitivity-related). - GP/SP commands (formats are not documented at all). - GF, FQF, FQP (what are those for?) + GP/SP commands (formats are not documented at all, like anywhere). */ #include #include #include #include #include -#include #include #include <86box/86box.h> #include <86box/device.h> @@ -30,15 +43,11 @@ enum mtouch_modes typedef struct mouse_microtouch_t { double abs_x; double abs_y; - int oldb; int b; char cmd[512]; - int bits; - int baud_rate_sel; int cmd_pos; int mode; uint8_t cal_cntr; - double rate; bool soh; bool in_reset; serial_t *serial; @@ -108,6 +117,7 @@ void microtouch_process_commands(mouse_microtouch_t* mtouch) if (mtouch->cmd[0] == 'R') { mtouch->in_reset = true; mtouch->mode = MODE_TABLET; + mtouch->cal_cntr = 0; timer_on_auto(&mtouch->reset_timer, 500. * 1000.); } if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { @@ -164,9 +174,6 @@ no_write_to_machine: void mtouch_write(serial_t* serial, void* priv, uint8_t data) { mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; - if (!dev->soh && data == 0x11) { - pclog("\n"); - } if (data == '\x1'){ dev->soh = 1; } else if (dev->soh) { From 4fe7090047b47fc83fb540d2023c5a01172411ba Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 5 May 2024 14:55:42 +0600 Subject: [PATCH 628/690] Apply clang-format --- src/device/mouse_microtouch_touchscreen.c | 124 ++++++++++++---------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 568b6b15b..703a372c6 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -15,7 +15,7 @@ * Copyright 2024 Cacodemon345 */ -/* TODO: +/* TODO: GP/SP commands (formats are not documented at all, like anywhere). */ #include @@ -34,122 +34,125 @@ #include <86box/fifo.h> #include <86box/video.h> /* Needed to account for overscan. */ -enum mtouch_modes -{ +enum mtouch_modes { MODE_TABLET = 1, - MODE_RAW = 2 + MODE_RAW = 2 }; typedef struct mouse_microtouch_t { - double abs_x; - double abs_y; - int b; - char cmd[512]; - int cmd_pos; - int mode; - uint8_t cal_cntr; - bool soh; - bool in_reset; - serial_t *serial; - Fifo8 resp; - pc_timer_t host_to_serial_timer; - pc_timer_t reset_timer; + double abs_x; + double abs_y; + int b; + char cmd[512]; + int cmd_pos; + int mode; + uint8_t cal_cntr; + bool soh; + bool in_reset; + serial_t *serial; + Fifo8 resp; + pc_timer_t host_to_serial_timer; + pc_timer_t reset_timer; } mouse_microtouch_t; -static mouse_microtouch_t* mtouch_inst = NULL; +static mouse_microtouch_t *mtouch_inst = NULL; -void microtouch_reset_complete(void *priv) +void +microtouch_reset_complete(void *priv) { - mouse_microtouch_t *mtouch = (mouse_microtouch_t*)priv; + mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; - mtouch->in_reset = false; + mtouch->in_reset = false; fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } -void microtouch_calibrate_timer(void *priv) +void +microtouch_calibrate_timer(void *priv) { - mouse_microtouch_t *mtouch = (mouse_microtouch_t*)priv; + mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; if (!fifo8_num_used(&mtouch->resp)) { mtouch->cal_cntr--; fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2); } } -void microtouch_process_commands(mouse_microtouch_t* mtouch) +void +microtouch_process_commands(mouse_microtouch_t *mtouch) { - int i = 0; + int i = 0; mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; - mtouch->cmd_pos = 0; + mtouch->cmd_pos = 0; pclog("Command received: %s\n", mtouch->cmd); for (i = 0; i < strlen(mtouch->cmd); i++) { mtouch->cmd[i] = toupper(mtouch->cmd[i]); } if (mtouch->cmd[0] == 'Z' || (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O')) { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "QM****00\r", sizeof("QM****00\r") - 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "QM****00\r", sizeof("QM****00\r") - 1); } if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "Q10200\r", sizeof("Q10200\r") - 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "Q10200\r", sizeof("Q10200\r") - 1); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { mtouch->mode = MODE_TABLET; fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { - mtouch->mode = MODE_RAW; + mtouch->mode = MODE_RAW; mtouch->cal_cntr = 0; fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'R') { mtouch->in_reset = true; - mtouch->mode = MODE_TABLET; + mtouch->mode = MODE_TABLET; mtouch->cal_cntr = 0; timer_on_auto(&mtouch->reset_timer, 500. * 1000.); } if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'N' && mtouch->cmd[1] == 'M') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'Q') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2); } if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'F') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "1\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2); } if (mtouch->cmd[0] == 'P') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t*) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); mtouch->cal_cntr = 2; } } -void mtouch_write_to_host(void *priv) +void +mtouch_write_to_host(void *priv) { - mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { if (fifo_get_full(dev->serial->rcvr_fifo)) { goto no_write_to_machine; @@ -171,10 +174,11 @@ no_write_to_machine: timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) 9600.0) * (double) (1 + 8 + 1)); } -void mtouch_write(serial_t* serial, void* priv, uint8_t data) +void +mtouch_write(serial_t *serial, void *priv, uint8_t data) { - mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; - if (data == '\x1'){ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + if (data == '\x1') { dev->soh = 1; } else if (dev->soh) { if (data != '\r') { @@ -189,13 +193,13 @@ void mtouch_write(serial_t* serial, void* priv, uint8_t data) static int mtouch_poll(void *priv) { - mouse_microtouch_t *dev = (mouse_microtouch_t*)priv; + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; if (dev->mode != MODE_RAW && fifo8_num_free(&dev->resp) >= 10) { unsigned int abs_x_int = 0, abs_y_int = 0; - double abs_x; - double abs_y; - int b = mouse_get_buttons_ex(); + double abs_x; + double abs_y; + int b = mouse_get_buttons_ex(); mouse_get_abs_coords(&abs_x, &abs_y); dev->b |= b & 1; if (abs_x >= 1.0) @@ -222,8 +226,8 @@ mtouch_poll(void *priv) } abs_x -= (monitors[index].mon_overscan_x / 2.); abs_y -= (monitors[index].mon_overscan_y / 2.); - abs_x = abs_x / (double)monitors[index].mon_xsize; - abs_y = abs_y / (double)monitors[index].mon_ysize; + abs_x = abs_x / (double) monitors[index].mon_xsize; + abs_y = abs_y / (double) monitors[index].mon_ysize; if (abs_x >= 1.0) abs_x = 1.0; if (abs_y >= 1.0) @@ -242,7 +246,7 @@ mtouch_poll(void *priv) dev->abs_x = abs_x; dev->abs_y = abs_y; dev->b |= 1; - + abs_x_int = abs_x * 16383; abs_y_int = 16383 - abs_y * 16383; @@ -270,12 +274,14 @@ mtouch_poll(void *priv) return 0; } -static void mtouch_poll_global(void) +static void +mtouch_poll_global(void) { mtouch_poll(mtouch_inst); } -void* mtouch_init(const device_t* info) +void * +mtouch_init(const device_t *info) { mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t)); @@ -284,7 +290,7 @@ void* mtouch_init(const device_t* info) timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); timer_on_auto(&dev->host_to_serial_timer, (1000000. / 9600.) * 10); - dev->mode = MODE_TABLET; + dev->mode = MODE_TABLET; mouse_input_mode = 1; mouse_set_buttons(2); mouse_set_poll_ex(mtouch_poll_global); @@ -294,7 +300,8 @@ void* mtouch_init(const device_t* info) return dev; } -void mtouch_close(void* priv) +void +mtouch_close(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; @@ -342,4 +349,3 @@ const device_t mouse_mtouch_device = { .force_redraw = NULL, .config = mtouch_config }; - From fe5ce508639ec7c7134d1c6d692a0c638afb1ae2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 6 May 2024 16:42:42 +0600 Subject: [PATCH 629/690] Stubbed Get Parameter Block command --- src/device/mouse_microtouch_touchscreen.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 703a372c6..954d10ee4 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -147,6 +147,13 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); mtouch->cal_cntr = 2; } + if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); + } } void From 9faf4dc7650ecd8e22b1a36b93b4315966070e53 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 7 May 2024 00:21:52 +0600 Subject: [PATCH 630/690] Stubbed Set Parameter Block command --- src/device/mouse_microtouch_touchscreen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 954d10ee4..ca0f16dd4 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -150,10 +150,14 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2); - fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", sizeof("0000000000000000000000000\r") - 1); fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } + if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2); + } } void From c71ca84d815e8c8d2c319e5128b5789d798d9a94 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 7 May 2024 15:49:28 +0600 Subject: [PATCH 631/690] Emulate a TouchPen instead --- src/device/mouse_microtouch_touchscreen.c | 36 +++++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index ca0f16dd4..788413ffc 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -46,7 +46,7 @@ typedef struct mouse_microtouch_t { char cmd[512]; int cmd_pos; int mode; - uint8_t cal_cntr; + uint8_t cal_cntr, pen_mode; bool soh; bool in_reset; serial_t *serial; @@ -89,17 +89,22 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) for (i = 0; i < strlen(mtouch->cmd); i++) { mtouch->cmd[i] = toupper(mtouch->cmd[i]); } - if (mtouch->cmd[0] == 'Z' || (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O')) { + if (mtouch->cmd[0] == 'Z') { + fifo8_push(&mtouch->resp, 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { + mtouch->pen_mode = 1; fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t *) "QM****00\r", sizeof("QM****00\r") - 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "TP****00\r", sizeof("TP****00\r") - 1); } if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { fifo8_push(&mtouch->resp, 1); - fifo8_push_all(&mtouch->resp, (uint8_t *) "Q10200\r", sizeof("Q10200\r") - 1); + fifo8_push_all(&mtouch->resp, (uint8_t *) "P50200\r", sizeof("P50200\r") - 1); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { mtouch->mode = MODE_TABLET; @@ -120,6 +125,7 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) mtouch->in_reset = true; mtouch->mode = MODE_TABLET; mtouch->cal_cntr = 0; + mtouch->pen_mode = 3; timer_on_auto(&mtouch->reset_timer, 500. * 1000.); } if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { @@ -139,6 +145,8 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2); } if (mtouch->cmd[0] == 'P') { + if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; + else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2); } @@ -212,7 +220,8 @@ mtouch_poll(void *priv) double abs_y; int b = mouse_get_buttons_ex(); mouse_get_abs_coords(&abs_x, &abs_y); - dev->b |= b & 1; + dev->b |= !!(b & 3); + if (abs_x >= 1.0) abs_x = 1.0; if (abs_y >= 1.0) @@ -244,16 +253,16 @@ mtouch_poll(void *priv) if (abs_y >= 1.0) abs_y = 1.0; } - if (dev->cal_cntr && (!(dev->b & 1) && (b & 1))) { + if (dev->cal_cntr && (!(dev->b & 1) && !!(b & 3))) { dev->b |= 1; - } else if (dev->cal_cntr && ((dev->b & 1) && !(b & 1))) { + } else if (dev->cal_cntr && ((dev->b & 1) && !!(b & 3))) { dev->b &= ~1; microtouch_calibrate_timer(dev); } if (dev->cal_cntr) { return 0; } - if (b & 1) { + if (!!(b & 3)) { dev->abs_x = abs_x; dev->abs_y = abs_y; dev->b |= 1; @@ -261,21 +270,21 @@ mtouch_poll(void *priv) abs_x_int = abs_x * 16383; abs_y_int = 16383 - abs_y * 16383; - fifo8_push(&dev->resp, 0b11000000); + fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode & 2) ? ((1 << 5) | ((b & 3))) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); - } else if ((dev->b & 1) && !(b & 1)) { + } else if ((dev->b & 1) && !(b & 3)) { dev->b &= ~1; abs_x_int = dev->abs_x * 16383; abs_y_int = 16383 - dev->abs_y * 16383; - fifo8_push(&dev->resp, 0b11000000); + fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode & 2) ? ((1 << 5)) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); - fifo8_push(&dev->resp, 0b10000000); + fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode & 2) ? ((1 << 5)) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); @@ -302,6 +311,7 @@ mtouch_init(const device_t *info) timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); timer_on_auto(&dev->host_to_serial_timer, (1000000. / 9600.) * 10); dev->mode = MODE_TABLET; + dev->pen_mode = 3; mouse_input_mode = 1; mouse_set_buttons(2); mouse_set_poll_ex(mtouch_poll_global); @@ -348,7 +358,7 @@ static const device_config_t mtouch_config[] = { }; const device_t mouse_mtouch_device = { - .name = "3M MicroTouch SMT3", + .name = "3M MicroTouch TouchPen 4", .internal_name = "microtouch_touchpen", .flags = DEVICE_COM, .local = 0, From ef7b4044ef812420b54f29141fdce8f3410fa431 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 20 May 2024 13:05:35 +0600 Subject: [PATCH 632/690] Report finger touches if in Pen or Finger mode --- src/device/mouse_microtouch_touchscreen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 788413ffc..db889249e 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -270,7 +270,7 @@ mtouch_poll(void *priv) abs_x_int = abs_x * 16383; abs_y_int = 16383 - abs_y * 16383; - fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode & 2) ? ((1 << 5) | ((b & 3))) : 0)); + fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((b & 3))) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); @@ -279,12 +279,12 @@ mtouch_poll(void *priv) dev->b &= ~1; abs_x_int = dev->abs_x * 16383; abs_y_int = 16383 - dev->abs_y * 16383; - fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode & 2) ? ((1 << 5)) : 0)); + fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); - fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode & 2) ? ((1 << 5)) : 0)); + fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0)); fifo8_push(&dev->resp, abs_x_int & 0b1111111); fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); fifo8_push(&dev->resp, abs_y_int & 0b1111111); From 95d7fa828ba719a9abe5fc96c50d62497d433dfd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 12 Jun 2024 00:24:58 +0600 Subject: [PATCH 633/690] Fixes for calibration and baud rate workaround --- src/device/mouse_microtouch_touchscreen.c | 31 ++++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index db889249e..af5ef5bf0 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -15,8 +15,11 @@ * Copyright 2024 Cacodemon345 */ +/* Reference: https://www.touchwindow.com/mm5/drivers/mtsctlrm.pdf */ + /* TODO: - GP/SP commands (formats are not documented at all, like anywhere). + Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet). + - Dynamic baud rate selection from software following this. */ #include #include @@ -42,6 +45,7 @@ enum mtouch_modes { typedef struct mouse_microtouch_t { double abs_x; double abs_y; + double baud_rate; int b; char cmd[512]; int cmd_pos; @@ -83,9 +87,9 @@ void microtouch_process_commands(mouse_microtouch_t *mtouch) { int i = 0; + int fifo_used = fifo8_num_used(&mtouch->resp); mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; mtouch->cmd_pos = 0; - pclog("Command received: %s\n", mtouch->cmd); for (i = 0; i < strlen(mtouch->cmd); i++) { mtouch->cmd[i] = toupper(mtouch->cmd[i]); } @@ -166,6 +170,8 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) fifo8_push(&mtouch->resp, 1); fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2); } + if (fifo8_num_used(&mtouch->resp) != fifo_used) + pclog("Command received: %s\n", mtouch->cmd); } void @@ -255,7 +261,7 @@ mtouch_poll(void *priv) } if (dev->cal_cntr && (!(dev->b & 1) && !!(b & 3))) { dev->b |= 1; - } else if (dev->cal_cntr && ((dev->b & 1) && !!(b & 3))) { + } else if (dev->cal_cntr && ((dev->b & 1) && !(b & 3))) { dev->b &= ~1; microtouch_calibrate_timer(dev); } @@ -306,10 +312,11 @@ mtouch_init(const device_t *info) mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t)); dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev); + dev->baud_rate = device_get_config_int("baudrate"); fifo8_create(&dev->resp, 512); timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); - timer_on_auto(&dev->host_to_serial_timer, (1000000. / 9600.) * 10); + timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); dev->mode = MODE_TABLET; dev->pen_mode = 3; mouse_input_mode = 1; @@ -353,6 +360,22 @@ static const device_config_t mtouch_config[] = { { .description = "" } } }, + { + .name = "baudrate", + .description = "Baud Rate", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 9600, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "19200", .value = 19200 }, + { .description = "9600", .value = 9600 }, + { .description = "4800", .value = 4800 }, + { .description = "2400", .value = 2400 }, + { .description = "1200", .value = 1200 } + } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; From 969830ad8372aad57de7266fd8330d8c59eb1621 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Jun 2024 01:58:44 +0200 Subject: [PATCH 634/690] New recompiler: Add a sanity check, fixes crash with RapidCAD, fixes #4487 . --- src/cpu/386_dynarec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 8e9403899..a7dbd34a4 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -414,7 +414,8 @@ exec386_dynarec_dyn(void) int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f); - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) + if ((page->code_present_mask & mask) || + ((page->mem != page_ff) && (page->byte_code_present_mask[byte_offset] & byte_mask))) # else if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) # endif From 193838b7c2f2bf0b0b3d5f901fb699c6d73b835a Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 11 Jun 2024 20:06:04 -0400 Subject: [PATCH 635/690] Fix several uninitialized variables --- src/cdrom/cdrom_image_backend.c | 6 +++--- src/ini.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 482769799..fdfa4a4ab 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -696,9 +696,9 @@ static int cdi_cue_get_frame(uint64_t *frames, char **line) { char temp[128]; - int min; - int sec; - int fr; + int min = 0; + int sec = 0; + int fr = 0; int success; success = cdi_cue_get_buffer(temp, line, 0); diff --git a/src/ini.c b/src/ini.c index a792d356b..616245786 100644 --- a/src/ini.c +++ b/src/ini.c @@ -546,7 +546,7 @@ ini_section_get_int(ini_section_t self, const char *name, int def) { section_t *section = (section_t *) self; const entry_t *entry; - int value; + int value = 0; if (section == NULL) return def; @@ -565,7 +565,7 @@ ini_section_get_uint(ini_section_t self, const char *name, uint32_t def) { section_t *section = (section_t *) self; const entry_t *entry; - uint32_t value; + uint32_t value = 0; if (section == NULL) return def; @@ -585,7 +585,7 @@ ini_section_get_float(ini_section_t self, const char *name, float def) { section_t *section = (section_t *) self; const entry_t *entry; - float value; + float value = 0; if (section == NULL) return def; @@ -605,7 +605,7 @@ ini_section_get_double(ini_section_t self, const char *name, double def) { section_t *section = (section_t *) self; const entry_t *entry; - double value; + double value = 0; if (section == NULL) return def; @@ -624,7 +624,7 @@ ini_section_get_hex16(ini_section_t self, const char *name, int def) { section_t *section = (section_t *) self; const entry_t *entry; - unsigned int value; + unsigned int value = 0; if (section == NULL) return def; @@ -643,7 +643,7 @@ ini_section_get_hex20(ini_section_t self, const char *name, int def) { section_t *section = (section_t *) self; const entry_t *entry; - unsigned int value; + unsigned int value = 0; if (section == NULL) return def; From 9a9d73c1595a848ea543eb5c8aa069f29da2306e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 12 Jun 2024 20:06:29 +0200 Subject: [PATCH 636/690] More fixes to the Paradise/WD VGA cards Banking no longer goes beyond 0xfffff thanks to masking, fixes possible and in-coming glitches on said cards. --- src/video/vid_paradise.c | 186 +++++++++++---------------------------- 1 file changed, 50 insertions(+), 136 deletions(-) diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 30666e82c..2e4802fe5 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -38,8 +38,6 @@ typedef struct paradise_t { rom_t bios_rom; - uint8_t bank_mask; - enum { PVGA1A = 0, WD90C11, @@ -51,7 +49,6 @@ typedef struct paradise_t { uint32_t read_bank[4], write_bank[4]; int interlace; - int check; struct { uint8_t reg_block_ptr; @@ -109,16 +106,6 @@ paradise_in(uint16_t addr, void *priv) return 0xff; } switch (svga->gdcaddr) { - case 0x0b: - temp = svga->gdcreg[0x0b]; - if (paradise->type == WD90C30) { - if (paradise->vram_mask == ((512 << 10) - 1)) { - temp &= ~0x40; - temp |= 0xc0; - } - } - return temp; - case 0x0f: return (svga->gdcreg[0x0f] & 0x17) | 0x80; @@ -149,11 +136,6 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) svga_t *svga = ¶dise->svga; uint8_t old; - if (paradise->vram_mask <= ((512 << 10) - 1)) - paradise->bank_mask = 0x7f; - else - paradise->bank_mask = 0xff; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -189,21 +171,22 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) old = svga->gdcreg[svga->gdcaddr]; switch (svga->gdcaddr) { case 6: - if (old ^ (val & 0x0c)) { - switch (val & 0x0c) { - case 0x00: /*128k at A0000*/ + if ((val & 0xc) != (old & 0xc)) { + svga->gdcreg[6] = val; + switch (svga->gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; break; - case 0x04: /*64k at A0000*/ + case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; - case 0x08: /*32k at B0000*/ + case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; - case 0x0c: /*32k at B8000*/ + case 0xC: /*32k at B8000*/ mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; @@ -211,14 +194,13 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) default: break; } - svga->gdcreg[6] = val; paradise_remap(paradise); } return; case 9: case 0x0a: - svga->gdcreg[svga->gdcaddr] = val & paradise->bank_mask; + svga->gdcreg[svga->gdcaddr] = val; paradise_remap(paradise); return; case 0x0b: @@ -277,8 +259,6 @@ paradise_remap(paradise_t *paradise) { svga_t *svga = ¶dise->svga; - paradise->check = 0; - if (svga->seqregs[0x11] & 0x80) { paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); @@ -303,12 +283,12 @@ paradise_remap(paradise_t *paradise) paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } - if (((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4 && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[6] >> 2) & 3) == 1) - paradise->check = 1; - - if (paradise->bank_mask == 0x7f) { + if ((svga->gdcreg[0x0b] & 0xc0) < 0xc0) { paradise->read_bank[1] &= 0x7ffff; paradise->write_bank[1] &= 0x7ffff; + } else { + paradise->read_bank[1] &= 0xfffff; + paradise->write_bank[1] &= 0xfffff; } } @@ -386,36 +366,20 @@ paradise_write(uint32_t addr, uint8_t val, void *priv) /*Could be done in a better way but it works.*/ if (svga->gdcreg[0x0e] & 0x01) { - if (paradise->check) { + if (((svga->gdcreg[6] & 0x0c) == 0x04) && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) + if (prev_addr == 3) { + if ((addr & 0x30000) != 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else if (prev_addr == 2) { + if ((addr & 0x30000) != 0x20000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) + } else if (prev_addr == 1) { + if ((addr & 0x30000) != 0x10000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else { + if (addr & 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; } } @@ -439,36 +403,20 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv) /*Could be done in a better way but it works.*/ if (svga->gdcreg[0x0e] & 0x01) { - if (paradise->check) { + if (((svga->gdcreg[6] & 0x0c) == 0x04) && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) + if (prev_addr == 3) { + if ((addr & 0x30000) != 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else if (prev_addr == 2) { + if ((addr & 0x30000) != 0x20000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) + } else if (prev_addr == 1) { + if ((addr & 0x30000) != 0x10000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else { + if (addr & 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; } } @@ -484,44 +432,27 @@ paradise_read(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - if (!(svga->gdcreg[5] & 0x40)) { + if (!(svga->gdcreg[5] & 0x40)) return svga_read(addr, svga); - } addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ if (svga->gdcreg[0x0e] & 0x01) { - if (paradise->check) { + if (((svga->gdcreg[6] & 0x0c) == 0x04) && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) + if (prev_addr == 3) { + if ((addr & 0x30000) != 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else if (prev_addr == 2) { + if ((addr & 0x30000) != 0x20000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) + } else if (prev_addr == 1) { + if ((addr & 0x30000) != 0x10000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else { + if (addr & 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; } } @@ -536,44 +467,27 @@ paradise_readw(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - if (!(svga->gdcreg[5] & 0x40)) { + if (!(svga->gdcreg[5] & 0x40)) return svga_readw(addr, svga); - } addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ if (svga->gdcreg[0x0e] & 0x01) { - if (paradise->check) { + if (((svga->gdcreg[6] & 0x0c) == 0x04) && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) + if (prev_addr == 3) { + if ((addr & 0x30000) != 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else if (prev_addr == 2) { + if ((addr & 0x30000) != 0x20000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) + } else if (prev_addr == 1) { + if ((addr & 0x30000) != 0x10000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) + } else { + if (addr & 0x30000) addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; } } From a369bc2d05b38a0211884b53d7839e658d54cc56 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Jun 2024 20:46:27 +0200 Subject: [PATCH 637/690] Reimplement S3 ViRGE reset and move PCI TRC CPU reset to outside the recompiled block, fixes #2903. --- src/cpu/386_common.c | 2 + src/cpu/386_dynarec.c | 14 ++++ src/cpu/cpu.c | 4 +- src/cpu/x86.h | 2 + src/pci.c | 8 +++ src/video/vid_s3_virge.c | 136 +++++++++++---------------------------- 6 files changed, 68 insertions(+), 98 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 5e80ef4c3..d1d38006b 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -51,6 +51,8 @@ uint32_t dr[8]; uint32_t use32; int stack32; +int cpu_init = 0; + uint32_t *eal_r; uint32_t *eal_w; diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index a7dbd34a4..d8a33a624 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -350,6 +350,9 @@ exec386_dynarec_int(void) CPU_BLOCK_END(); } + if (cpu_init) + CPU_BLOCK_END(); + if (cpu_state.abrt) CPU_BLOCK_END(); if (smi_line) @@ -592,6 +595,9 @@ exec386_dynarec_dyn(void) # endif CPU_BLOCK_END(); + if (cpu_init) + CPU_BLOCK_END(); + if ((cpu_state.flags & T_FLAG) || (trap == 2)) CPU_BLOCK_END(); if (smi_line) @@ -689,6 +695,9 @@ exec386_dynarec_dyn(void) # endif CPU_BLOCK_END(); + if (cpu_init) + CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); if (smi_line) @@ -768,6 +777,11 @@ exec386_dynarec(int32_t cycs) exec386_dynarec_dyn(); } + if (cpu_init) { + cpu_init = 0; + resetx86(); + } + if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index e1e0e913d..20476eec9 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -29,6 +29,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" +#include "x86.h" #include "x87_sf.h" #include <86box/device.h> #include <86box/machine.h> @@ -504,7 +505,8 @@ cpu_set(void) acycs = 0; #endif - soft_reset_pci = 0; + soft_reset_pci = 0; + cpu_init = 0; cpu_alt_reset = 0; unmask_a20_in_smm = 0; diff --git a/src/cpu/x86.h b/src/cpu/x86.h index f52e430ac..327af8964 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -59,6 +59,8 @@ extern int nmi_enable; extern int oddeven; extern int inttype; +extern int cpu_init; + extern uint32_t use32; extern uint32_t rmdat; extern uint32_t easeg; diff --git a/src/pci.c b/src/pci.c index 6475efe90..b4f5eafe5 100644 --- a/src/pci.c +++ b/src/pci.c @@ -23,6 +23,7 @@ #include <86box/86box.h> #include <86box/machine.h> #include "cpu.h" +#include "x86.h" #include <86box/io.h> #include <86box/pic.h> #include <86box/mem.h> @@ -420,7 +421,14 @@ pci_trc_reset(uint8_t val) flushmmucache(); } +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + cpu_init = 1; + else + resetx86(); +#else resetx86(); +#endif } void diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 7982f816e..d62ebbbab 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -299,6 +299,8 @@ typedef struct virge_t { int onboard; } virge_t; +static virge_t *reset_state = NULL; + static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; static video_timings_t timing_diamond_stealth3d_3000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_virge_dx_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -4247,115 +4249,50 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } } +static void +s3_virge_disable_handlers(virge_t *dev) +{ + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, + s3_virge_out, NULL, NULL, dev); + + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->mmio_mapping); + mem_mapping_disable(&dev->new_mmio_mapping); + mem_mapping_disable(&dev->svga.mapping); + mem_mapping_disable(&dev->bios_rom.mapping); + + /* Save all the mappings and the timers because they are part of linked lists. */ + reset_state->linear_mapping = dev->linear_mapping; + reset_state->mmio_mapping = dev->mmio_mapping; + reset_state->new_mmio_mapping = dev->new_mmio_mapping; + reset_state->svga.mapping = dev->svga.mapping; + reset_state->bios_rom.mapping = dev->bios_rom.mapping; + + reset_state->svga.timer = dev->svga.timer; + reset_state->svga.timer8514 = dev->svga.timer8514; + + reset_state->tri_timer = dev->tri_timer; +} + static void s3_virge_reset(void *priv) { - virge_t *virge = (virge_t *) priv; - svga_t *svga = &virge->svga; + virge_t *dev = (virge_t *) priv; - memset(svga->crtc, 0x00, sizeof(svga->crtc)); - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ULL << 32; - svga->dispofftime = 1000ULL << 32; - svga->bpp = 8; + if (reset_state != NULL) { + s3_virge_disable_handlers(dev); + reset_state->pci_slot = dev->pci_slot; - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - - memset(virge->pci_regs, 0x00, 256); - - virge->pci_regs[PCI_REG_COMMAND] = 3; - virge->pci_regs[0x05] = 0; - virge->pci_regs[0x06] = 0; - virge->pci_regs[0x07] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; - - switch (virge->local) { - case S3_VIRGE_325: - case S3_DIAMOND_STEALTH3D_2000: - virge->fifo_slots_num = 8; - virge->svga.crtc[0x59] = 0x70; - break; - case S3_DIAMOND_STEALTH3D_3000: - case S3_STB_VELOCITY_3D: - virge->fifo_slots_num = 8; - virge->svga.crtc[0x59] = 0x70; - break; - case S3_VIRGE_GX2: - case S3_DIAMOND_STEALTH3D_4000: - virge->fifo_slots_num = 16; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; - - case S3_TRIO_3D2X: - virge->fifo_slots_num = 16; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; - - default: - virge->fifo_slots_num = 8; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; + *dev = *reset_state; } - - if (virge->chip == S3_VIRGEGX2) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5); - else { - switch (virge->memory_size) { - case 2: - if (virge->chip == S3_VIRGEVX) { - virge->svga.crtc[0x36] = (0 << 5); - } else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 8: - if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); - else - virge->svga.crtc[0x36] = (3 << 5); - break; - case 4: - if (virge->chip == S3_VIRGEVX) - virge->svga.crtc[0x36] = (1 << 5); - else if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5); - else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - - default: - break; - } - if (virge->local == S3_VIRGE_GX) - virge->svga.crtc[0x36] |= (1 << 2); - } - - virge->svga.crtc[0x37] = 1 | (7 << 5); - virge->svga.crtc[0x53] = 8; - - if (!virge->onboard) - mem_mapping_disable(&virge->bios_rom.mapping); - - s3_virge_updatemapping(virge); - - mem_mapping_disable(&virge->mmio_mapping); - mem_mapping_disable(&virge->new_mmio_mapping); } static void * s3_virge_init(const device_t *info) { const char *bios_fn; - virge_t *virge = malloc(sizeof(virge_t)); - - memset(virge, 0, sizeof(virge_t)); + virge_t *virge = calloc(1, sizeof(virge_t)); + reset_state = calloc(1, sizeof(virge_t)); virge->bilinear_enabled = device_get_config_int("bilinear"); virge->dithering_enabled = device_get_config_int("dithering"); @@ -4595,6 +4532,8 @@ s3_virge_init(const device_t *info) virge->local = info->local; + *reset_state = *virge; + return virge; } @@ -4615,6 +4554,9 @@ s3_virge_close(void *priv) ddc_close(virge->ddc); i2c_gpio_close(virge->i2c); + free(reset_state); + reset_state = NULL; + free(virge); } From df8830c219ccbb5ff2c151b797cffefd37edba27 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 12 Jun 2024 20:57:39 +0200 Subject: [PATCH 638/690] Fix warning. --- src/video/vid_paradise.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 2e4802fe5..f572521f2 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -76,7 +76,6 @@ paradise_in(uint16_t addr, void *priv) { paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; - uint8_t temp = 0; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; From f374ffde3670d8dbd648c341a3a1fe8423f53900 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Jun 2024 16:44:44 +0200 Subject: [PATCH 639/690] UM8886: Slight fixes. --- src/chipset/umc_8886.c | 50 ++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index 7a049b1cb..fb11af0e7 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -134,6 +134,36 @@ umc_8886_ide_handler(umc_8886_t *dev) } } +static void +umc_8886_bus_recalc(umc_8886_t *dev) +{ + switch (dev->pci_conf_sb[0x00][0xa4] & 0x03) { + case 0x00: + cpu_set_pci_speed(cpu_busspeed / 2); + break; + case 0x01: + cpu_set_pci_speed(cpu_busspeed); + break; + case 0x02: + cpu_set_pci_speed((cpu_busspeed * 2) / 3); + break; + } + + switch (dev->pci_conf_sb[0x00][0x56] & 0x03) { + default: + break; + case 0x00: + cpu_set_isa_pci_div(3); + break; + case 0x01: + cpu_set_isa_pci_div(4); + break; + case 0x02: + cpu_set_isa_pci_div(2); + break; + } +} + static void umc_8886_write(int func, int addr, uint8_t val, void *priv) { @@ -191,20 +221,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) case 0x56: dev->pci_conf_sb[func][addr] = val; - - switch (val & 3) { - case 0: - cpu_set_isa_pci_div(3); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(2); - break; - default: - break; - } + umc_8886_bus_recalc(dev); break; case 0xa2: @@ -225,7 +242,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) case 0xa4: dev->pci_conf_sb[func][addr] = val; - cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2)); + umc_8886_bus_recalc(dev); break; default: @@ -362,8 +379,7 @@ umc_8886_reset(void *priv) for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */ pci_set_irq_routing(i, PCI_IRQ_DISABLED); - cpu_set_isa_pci_div(3); - cpu_set_pci_speed(cpu_busspeed / 2); + umc_8886_bus_recalc(dev); } static void From fb267d1f8b4a51bdb1f552f5b7bd22e498443c16 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Jun 2024 19:01:57 +0200 Subject: [PATCH 640/690] Fix the DP8473 FDC flags, closes #4538. --- src/floppy/fdc.c | 14 +++++++++++++- src/include/86box/fdc.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 1a0aa2f10..4c1170eb9 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -931,6 +931,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->format_state = 0; break; case 0x0e: /*Dump registers*/ + if (fdc->flags & FDC_FLAG_NEC) { + fdc_bad_command(fdc); + break; + } fdc->lastdrive = fdc->drive; fdc->interrupt = 0x0e; fdc_callback(fdc); @@ -949,6 +953,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x10: /*Get version*/ case 0x14: /*Unlock*/ case 0x94: /*Lock*/ + if (fdc->flags & FDC_FLAG_NEC) { + fdc_bad_command(fdc); + break; + } fdc->lastdrive = fdc->drive; fdc->interrupt = fdc->command; fdc_callback(fdc); @@ -962,6 +970,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; case 0x13: /*Configure*/ + if (fdc->flags & FDC_FLAG_NEC) { + fdc_bad_command(fdc); + break; + } fdc->pnum = 0; fdc->ptot = 3; fdc->stat |= 0x90; @@ -2682,7 +2694,7 @@ const device_t fdc_dp8473_device = { .name = "NS DP8473 Floppy Drive Controller", .internal_name = "fdc_dp8473", .flags = 0, - .local = FDC_FLAG_AT | FDC_FLAG_NSC, + .local = FDC_FLAG_AT | FDC_FLAG_NEC | FDC_FLAG_NO_DSR_RESET, .init = fdc_init, .close = fdc_close, .reset = fdc_reset, diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 9529fde5c..6bb8f081e 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -57,6 +57,7 @@ extern int fdc_type; #define FDC_FLAG_QUA 0x3000 /* Is Quaternary */ #define FDC_FLAG_CHANNEL 0x3000 /* Channel mask */ #define FDC_FLAG_NO_DSR_RESET 0x4000 /* Has no DSR reset */ +#define FDC_FLAG_NEC 0x8000 /* Is NEC upd765-compatible */ typedef struct fdc_t { uint8_t dor; From e5f676d9b5ef77b8eff01a20b16431aef4af956f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Jun 2024 19:21:37 +0200 Subject: [PATCH 641/690] CD-ROM: Actually set the format variable of GPCMD_READ_DVD_STRUCTURE to cdb[7], fixes heap corruptions due to the format incorrectly mismatching the given buffer lengths, fixes #4522 . --- src/scsi/scsi_cdrom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 262d9600c..f6e4b9cf6 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -3000,6 +3000,7 @@ begin: if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { if (cdb[1] == 0) { + format = cdb[7]; ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); dev->buffer[0] = (ret >> 8); dev->buffer[1] = (ret & 0xff); From 7fd04ad942684a10a584d12aaaf459dda70df311 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 13 Jun 2024 23:53:03 -0300 Subject: [PATCH 642/690] VISO: Fix disc corruption caused by >2GB files on Windows --- src/cdrom/cdrom_image_viso.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 7ed68cd86..d75b5f301 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -46,6 +46,13 @@ # define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR) #endif +#ifdef __MINGW32__ +# define stat _stat64 +typedef struct __stat64 stat_t; +#else +typedef struct stat stat_t; +#endif + #define VISO_SKIP(p, n) \ { \ memset(p, 0x00, n); \ @@ -106,7 +113,7 @@ typedef struct _viso_entry_ { }; uint16_t pt_idx; - struct stat stats; + stat_t stats; struct _viso_entry_ *parent, *next, *next_dir, *first_child; @@ -830,7 +837,7 @@ viso_init(const char *dirname, int *error) strcpy(dir->path, dirname); if (stat(dirname, &dir->stats) != 0) { /* Use a blank structure if stat failed. */ - memset(&dir->stats, 0x00, sizeof(struct stat)); + memset(&dir->stats, 0x00, sizeof(stat_t)); } if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */ goto end; @@ -879,7 +886,7 @@ viso_init(const char *dirname, int *error) /* Stat the current directory or parent directory. */ if (stat(children_count ? dir->parent->path : dir->path, &entry->stats) != 0) { /* Use a blank structure if stat failed. */ - memset(&entry->stats, 0x00, sizeof(struct stat)); + memset(&entry->stats, 0x00, sizeof(stat_t)); } /* Set basename. */ @@ -909,7 +916,7 @@ viso_init(const char *dirname, int *error) /* Stat this child. */ if (stat(entry->path, &entry->stats) != 0) { /* Use a blank structure if stat failed. */ - memset(&entry->stats, 0x00, sizeof(struct stat)); + memset(&entry->stats, 0x00, sizeof(stat_t)); } /* Handle file size and El Torito boot code. */ @@ -1432,7 +1439,7 @@ next_entry: /* Allocate entry map for sector->file lookups. */ size_t orig_sector_size = viso->sector_size; while (1) { - cdrom_image_viso_log("VISO: Allocating entry map for %d %d-byte sectors\n", viso->entry_map_size, viso->sector_size); + cdrom_image_viso_log("VISO: Allocating entry map for %zu %zu-byte sectors\n", viso->entry_map_size, viso->sector_size); viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *)); if (viso->entry_map) { /* Successfully allocated. */ @@ -1444,7 +1451,7 @@ next_entry: /* If we don't have enough memory, double the sector size. */ viso->sector_size *= 2; - if (viso->sector_size == 0) /* give up if sectors become too large */ + if ((viso->sector_size < VISO_SECTOR_SIZE) || (viso->sector_size > (1 << 30))) /* give up if sectors become too large */ goto end; /* Go through files, recalculating the entry map size. */ @@ -1515,10 +1522,10 @@ next_entry: entry->data_offset = ((uint64_t) viso->all_sectors) * viso->sector_size; /* Determine how many sectors this file will take. */ - uint32_t size = entry->stats.st_size / viso->sector_size; + size_t size = entry->stats.st_size / viso->sector_size; if (entry->stats.st_size % viso->sector_size) size++; /* round up to the next sector */ - cdrom_image_viso_log("[%08X] %s => %" PRIu32 " + %" PRIu32 " sectors\n", entry, entry->path, viso->all_sectors, size); + cdrom_image_viso_log("[%08X] %s => %zu + %zu sectors\n", entry, entry->path, viso->all_sectors, size); /* Allocate sectors to this file. */ viso->all_sectors += size; @@ -1537,7 +1544,7 @@ next_entry: viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp); /* Metadata processing is finished, read it back to memory. */ - cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size); + cdrom_image_viso_log("VISO: Reading back %zu %zu-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size); viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size); if (!viso->metadata) goto end; From 05226efe3df80a54b2ef5669eb2a85efc487bf28 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 14 Jun 2024 00:50:08 -0300 Subject: [PATCH 643/690] VISO: Type flexibility and macro cleanups --- src/cdrom/cdrom_image_viso.c | 50 +++++++++++++++++------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index d75b5f301..90bd83cf7 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -46,35 +46,35 @@ # define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR) #endif -#ifdef __MINGW32__ -# define stat _stat64 +#ifdef _WIN32 +# define stat _stat64 typedef struct __stat64 stat_t; #else typedef struct stat stat_t; #endif -#define VISO_SKIP(p, n) \ - { \ - memset(p, 0x00, n); \ - p += n; \ +#define VISO_SKIP(p, n) \ + { \ + memset((p), 0x00, (n)); \ + (p) += (n); \ } #define VISO_TIME_VALID(t) ((t) > 0) /* ISO 9660 defines "both endian" data formats, which are stored as little endian followed by big endian. */ -#define VISO_LBE_16(p, x) \ - { \ - *((uint16_t *) p) = cpu_to_le16(x); \ - p += 2; \ - *((uint16_t *) p) = cpu_to_be16(x); \ - p += 2; \ +#define VISO_LBE_16(p, x) \ + { \ + *((uint16_t *) (p)) = cpu_to_le16((x)); \ + (p) += 2; \ + *((uint16_t *) (p)) = cpu_to_be16((x)); \ + (p) += 2; \ } -#define VISO_LBE_32(p, x) \ - { \ - *((uint32_t *) p) = cpu_to_le32(x); \ - p += 4; \ - *((uint32_t *) p) = cpu_to_be32(x); \ - p += 4; \ +#define VISO_LBE_32(p, x) \ + { \ + *((uint32_t *) (p)) = cpu_to_le32((x)); \ + (p) += 4; \ + *((uint32_t *) (p)) = cpu_to_be32((x)); \ + (p) += 4; \ } #define VISO_SECTOR_SIZE COOKED_SECTOR_SIZE @@ -503,10 +503,6 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type) *p++ = 0; /* extended attribute length */ VISO_SKIP(p, 8); /* sector offset */ VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */ -#ifdef _WIN32 - if (entry->stats.st_mtime < 0) - pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path); -#endif p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */ *p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */ @@ -678,9 +674,9 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) /* Handle reads in a sector by sector basis. */ while (count > 0) { /* Determine the current sector, offset and remainder. */ - uint32_t sector = seek / viso->sector_size; - uint32_t sector_offset = seek % viso->sector_size; - uint32_t sector_remain = MIN(count, viso->sector_size - sector_offset); + size_t sector = seek / viso->sector_size; + size_t sector_offset = seek % viso->sector_size; + size_t sector_remain = MIN(count, viso->sector_size - sector_offset); /* Handle sector. */ if (sector < viso->metadata_sectors) { @@ -1549,8 +1545,8 @@ next_entry: if (!viso->metadata) goto end; fseeko64(viso->tf.fp, 0, SEEK_SET); - uint64_t metadata_size = viso->metadata_sectors * viso->sector_size; - uint64_t metadata_remain = metadata_size; + size_t metadata_size = viso->metadata_sectors * viso->sector_size; + size_t metadata_remain = metadata_size; while (metadata_remain > 0) metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.fp); From b997b9df3e18fa5075e45f35f1586b01db317ae6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 15 Jun 2024 16:59:02 +0200 Subject: [PATCH 644/690] CD-ROM image backend: Fix handling of CD-XA Mode 2 Form 1 images with a sector size of 2336. --- src/cdrom/cdrom_image_backend.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index fdfa4a4ab..5cdb2c988 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -509,11 +509,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form) uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */ if (sector_size == RAW_SECTOR_SIZE) { - if (!mode2 || (form == 0)) - seek += 16; - else + if (mode2 && (form > 0)) seek += 24; - } + else + seek += 16; + } else if (form > 0) + seek += 8; file->read(file, pvd, seek, COOKED_SECTOR_SIZE); @@ -582,6 +583,10 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) trk.sector_size = 2328; trk.mode2 = 1; trk.form = 2; + } else if (cdi_can_read_pvd(trk.file, 2336, 1, 1)) { + trk.sector_size = 2336; + trk.mode2 = 1; + trk.form = 1; } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) { trk.sector_size = RAW_SECTOR_SIZE; trk.mode2 = 1; @@ -908,6 +913,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) trk.attr = DATA_TRACK; trk.mode2 = 1; } else if (!strcmp(type, "MODE2/2336")) { + trk.form = 1; trk.sector_size = 2336; trk.attr = DATA_TRACK; trk.mode2 = 1; From bf105c6f2904c33139e4118e8488efacd3103b3b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 15 Jun 2024 17:27:19 +0200 Subject: [PATCH 645/690] CD-ROM image backend: Skip 8 bytes on every sector on non-raw CD-XA Mode 2 images. --- src/cdrom/cdrom_image_backend.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 5cdb2c988..003afb58c 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -764,6 +764,8 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u if (cur->number != 1) return 0; cur->skip = skip * cur->sector_size; + if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0)) + cur->skip += 8; cur->start += cur_pregap; *total_pregap = cur_pregap; cdi_track_push_back(cdi, cur); @@ -786,6 +788,8 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u cur->start += prev->start + prev->length + cur_pregap; cur->skip = skip * cur->sector_size; + if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0)) + cur->skip += 8; *shift += prev->start + prev->length; *total_pregap = cur_pregap; } From 382b941ff99aa3ff78a969cbd494c87647a595b4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 15 Jun 2024 17:40:41 +0200 Subject: [PATCH 646/690] CD-ROM image backend: Add the 8-byte skip also to ISO image loading. --- src/cdrom/cdrom_image_backend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 003afb58c..9ce78e5b4 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -587,6 +587,7 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) trk.sector_size = 2336; trk.mode2 = 1; trk.form = 1; + trk.skip = 8; } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) { trk.sector_size = RAW_SECTOR_SIZE; trk.mode2 = 1; From c9176b2d91616f03124a6ac66b116894e69cc55c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 16 Jun 2024 14:16:53 +0600 Subject: [PATCH 647/690] Changes --- src/qt/qt_main.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1523d9a62..dda682641 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -17,10 +17,6 @@ * Copyright 2021-2022 Cacodemon345 * Copyright 2021-2022 Teemu Korhonen */ - -#ifdef _WIN32 -#define UNICODE 1 -#endif #include #include #include @@ -224,13 +220,13 @@ main(int argc, char *argv[]) #ifdef Q_OS_WINDOWS # if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) - HWND winbox = FindWindow(L"TWinBoxMain", NULL); + HWND winbox = FindWindowW(L"TWinBoxMain", NULL); if (winbox && - FindWindowEx(winbox, NULL, L"TToolBar", NULL) && - FindWindowEx(winbox, NULL, L"TListBox", NULL) && - FindWindowEx(winbox, NULL, L"TStatusBar", NULL) && - (winbox = FindWindowEx(winbox, NULL, L"TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ - FindWindowEx(winbox, NULL, L"TTabSheet", NULL)) + FindWindowExW(winbox, NULL, L"TToolBar", NULL) && + FindWindowExW(winbox, NULL, L"TListBox", NULL) && + FindWindowExW(winbox, NULL, L"TStatusBar", NULL) && + (winbox = FindWindowExW(winbox, NULL, L"TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ + FindWindowExW(winbox, NULL, L"TTabSheet", NULL)) # endif { QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("WinBox is no longer supported"), From 2b3d3ad5bd201900146c316c24b024aae2b87228 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 18 Jun 2024 20:05:44 +0600 Subject: [PATCH 648/690] Make sure timers don't go completely out of sync upon altering TSC via WRMSR --- src/cpu/cpu.c | 13 +++++++------ src/include/86box/timer.h | 3 +++ src/timer.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 20476eec9..0ff54f61c 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -40,6 +40,7 @@ #include <86box/nmi.h> #include <86box/pic.h> #include <86box/pci.h> +#include <86box/timer.h> #include <86box/gdbstub.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -3492,7 +3493,7 @@ cpu_WRMSR(void) break; /* Time Stamp Counter */ case 0x10: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* Performance Monitor - Control and Event Select */ case 0x11: @@ -3568,7 +3569,7 @@ cpu_WRMSR(void) break; /* Time Stamp Counter */ case 0x10: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ case 0xc1: @@ -3664,7 +3665,7 @@ cpu_WRMSR(void) break; /* Time Stamp Counter */ case 0x00000010: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* Array Access Register */ case 0x00000082: @@ -3834,7 +3835,7 @@ amd_k_invalid_wrmsr: /* Time Stamp Counter */ case 0x00000010: case 0x80000010: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* Performance Monitor - Control and Event Select */ case 0x00000011: @@ -3919,7 +3920,7 @@ pentium_invalid_wrmsr: msr.tr5 = EAX & 0x008f0f3b; /* Time Stamp Counter */ case 0x10: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* Performance Monitor - Control and Event Select */ case 0x11: @@ -3952,7 +3953,7 @@ pentium_invalid_wrmsr: break; /* Time Stamp Counter */ case 0x10: - tsc = EAX | ((uint64_t) EDX << 32); + timer_set_new_tsc(EAX | ((uint64_t) EDX << 32)); break; /* Unknown */ case 0x18: diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index 91f903a0f..25aff6b2f 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -185,6 +185,9 @@ timer_set_p(pc_timer_t *timer, void *priv) extern void timer_stop(pc_timer_t *timer); extern void timer_on_auto(pc_timer_t *timer, double period); +/* Change TSC, taking into account the timers. */ +extern void timer_set_new_tsc(uint64_t new_tsc); + #ifdef __cplusplus } #endif diff --git a/src/timer.c b/src/timer.c index d7102ffc3..6ddf8ebb5 100644 --- a/src/timer.c +++ b/src/timer.c @@ -253,3 +253,31 @@ timer_on_auto(pc_timer_t *timer, double period) else timer_stop(timer); } + +void +timer_set_new_tsc(uint64_t new_tsc) +{ + pc_timer_t *timer = NULL; + /* Run timers already expired. */ +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + + if (!timer_head) { + tsc = new_tsc; + return; + } + + timer = timer_head; + timer_target = new_tsc + (int32_t)(timer_get_ts_int(timer_head) - (uint32_t)tsc); + + while (timer) { + int32_t offset_from_current_tsc = (int32_t)(timer_get_ts_int(timer) - (uint32_t)tsc); + timer->ts.ts32.integer = new_tsc + offset_from_current_tsc; + + timer = timer->next; + } + + tsc = new_tsc; +} From a44936f3e1757aec048a3ba01cf7c1b4e2212528 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 21 Jun 2024 15:36:28 +0600 Subject: [PATCH 649/690] Add Generic PCL Printer --- src/include/86box/plat.h | 4 +- src/include/86box/prt_devs.h | 1 + src/lpt.c | 1 + src/printer/prt_ps.c | 129 +++++++++++++++++++++++++++++------ src/qt/qt_platform.cpp | 9 ++- src/unix/unix.c | 4 ++ 6 files changed, 126 insertions(+), 22 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 975133f6c..26f5d5cc8 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -47,7 +47,9 @@ enum { STRING_HW_NOT_AVAILABLE_MACHINE, /* "Machine \"%hs\" is not available..." */ STRING_HW_NOT_AVAILABLE_VIDEO, /* "Video card \"%hs\" is not available..." */ STRING_HW_NOT_AVAILABLE_VIDEO2, /* "Video card #2 \"%hs\" is not available..." */ - STRING_MONITOR_SLEEP /* "Monitor in sleep mode" */ + STRING_MONITOR_SLEEP, /* "Monitor in sleep mode" */ + STRING_GHOSTPCL_ERROR_TITLE, /* "Unable to initialize GhostPCL" */ + STRING_GHOSTPCL_ERROR_DESC /* "gpcl6dll32.dll/gpcl6dll64.dll/libgpcl6 is required..." */ }; /* The Win32 API uses _wcsicmp. */ diff --git a/src/include/86box/prt_devs.h b/src/include/86box/prt_devs.h index 3d9d6673a..02920e9b0 100644 --- a/src/include/86box/prt_devs.h +++ b/src/include/86box/prt_devs.h @@ -4,5 +4,6 @@ extern const lpt_device_t lpt_prt_text_device; extern const lpt_device_t lpt_prt_escp_device; extern const lpt_device_t lpt_prt_ps_device; +extern const lpt_device_t lpt_prt_pcl_device; #endif /*EMU_PRT_DEVS_H*/ diff --git a/src/lpt.c b/src/lpt.c index 419e5ad3d..d0647c0e6 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -42,6 +42,7 @@ static const struct { {"text_prt", &lpt_prt_text_device }, {"dot_matrix", &lpt_prt_escp_device }, {"postscript", &lpt_prt_ps_device }, + {"pcl", &lpt_prt_pcl_device }, {"plip", &lpt_plip_device }, {"dongle_savquest", &lpt_hasp_savquest_device }, {"", NULL } diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index e6362019f..3e6612ce1 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -6,13 +6,16 @@ * * This file is part of the 86Box distribution. * - * Implementation of a generic PostScript printer. + * Implementation of a generic PostScript printer and a + * generic PCL 5e printer. * * * * Authors: David Hrdlička, + * Cacodemon345 * * Copyright 2019 David Hrdlička. + * Copyright 2024 Cacodemon345. */ #include @@ -44,15 +47,20 @@ #ifdef _WIN32 # if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) # define PATH_GHOSTSCRIPT_DLL "gsdll32.dll" +# define PATH_GHOSTPCL_DLL "gpcl6dll32.dll" # else # define PATH_GHOSTSCRIPT_DLL "gsdll64.dll" +# define PATH_GHOSTPCL_DLL "gpcl6dll64.dll" # endif #elif defined __APPLE__ # define PATH_GHOSTSCRIPT_DLL "libgs.dylib" +# define PATH_GHOSTPCL_DLL "libgpcl6.dylib" #else # define PATH_GHOSTSCRIPT_DLL "libgs.so.9" # define PATH_GHOSTSCRIPT_DLL_ALT1 "libgs.so.10" # define PATH_GHOSTSCRIPT_DLL_ALT2 "libgs.so" +# define PATH_GHOSTPCL_DLL "libgpcl6.so.10" +# define PATH_GHOSTPCL_DLL_ALT "libgpcl6.so" #endif #define POSTSCRIPT_BUFFER_LENGTH 65536 @@ -72,6 +80,8 @@ typedef struct ps_t { bool int_pending; bool error; bool autofeed; + bool pcl; + bool pcl_escape; uint8_t ctrl; char printer_path[260]; @@ -141,28 +151,32 @@ pulse_timer(void *priv) static int convert_to_pdf(ps_t *dev) { - volatile int code; + volatile int code, arg = 0; void *instance = NULL; char input_fn[1024]; char output_fn[1024]; - char *gsargv[9]; + char *gsargv[11]; strcpy(input_fn, dev->printer_path); path_slash(input_fn); strcat(input_fn, dev->filename); strcpy(output_fn, input_fn); - strcpy(output_fn + strlen(output_fn) - 3, ".pdf"); + strcpy(output_fn + strlen(output_fn) - (dev->pcl ? 4 : 3), ".pdf"); - gsargv[0] = ""; - gsargv[1] = "-dNOPAUSE"; - gsargv[2] = "-dBATCH"; - gsargv[3] = "-dSAFER"; - gsargv[4] = "-sDEVICE=pdfwrite"; - gsargv[5] = "-q"; - gsargv[6] = "-o"; - gsargv[7] = output_fn; - gsargv[8] = input_fn; + gsargv[arg++] = ""; + gsargv[arg++] = "-dNOPAUSE"; + gsargv[arg++] = "-dBATCH"; + gsargv[arg++] = "-dSAFER"; + gsargv[arg++] = "-sDEVICE=pdfwrite"; + if (dev->pcl) { + gsargv[arg++] = "-LPCL"; + gsargv[arg++] = "-lPCL5E"; + } + gsargv[arg++] = "-q"; + gsargv[arg++] = "-o"; + gsargv[arg++] = output_fn; + gsargv[arg++] = input_fn; code = gsapi_new_instance(&instance, dev); if (code < 0) @@ -171,7 +185,7 @@ convert_to_pdf(ps_t *dev) code = gsapi_set_arg_encoding(instance, GS_ARG_ENCODING_UTF8); if (code == 0) - code = gsapi_init_with_args(instance, 9, gsargv); + code = gsapi_init_with_args(instance, arg, gsargv); if (code == 0 || code == gs_error_Quit) code = gsapi_exit(instance); @@ -198,19 +212,22 @@ write_buffer(ps_t *dev, bool finish) return; if (dev->filename[0] == 0) - plat_tempfile(dev->filename, NULL, ".ps"); + plat_tempfile(dev->filename, NULL, dev->pcl ? ".pcl" : ".ps"); strcpy(path, dev->printer_path); path_slash(path); strcat(path, dev->filename); - fp = plat_fopen(path, "a"); + fp = plat_fopen(path, dev->pcl ? "ab" : "a"); if (fp == NULL) return; fseek(fp, 0, SEEK_END); - fprintf(fp, "%.*s", POSTSCRIPT_BUFFER_LENGTH, dev->buffer); + if (dev->pcl) + fwrite(dev->buffer, 1, dev->buffer_pos, fp); + else + fprintf(fp, "%.*s", POSTSCRIPT_BUFFER_LENGTH, dev->buffer); fclose(fp); @@ -249,8 +266,25 @@ ps_write_data(uint8_t val, void *priv) static void process_data(ps_t *dev) { - /* Check for non-printable characters */ - if ((dev->data < 0x20) || (dev->data == 0x7f)) { + /* On PCL, check for escape sequences. */ + if (dev->pcl) { + if (dev->data == 0x1B) + dev->pcl_escape = true; + else if (dev->pcl_escape) { + dev->pcl_escape = false; + if (dev->data == 0xE) { + dev->buffer[dev->buffer_pos++] = dev->data; + dev->buffer[dev->buffer_pos] = 0; + + if (dev->buffer_pos > 2) + write_buffer(dev, true); + + return; + } + } + } + /* On PostScript, check for non-printable characters. */ + else if ((dev->data < 0x20) || (dev->data == 0x7f)) { switch (dev->data) { /* The following characters are considered white-space by the PostScript specification */ @@ -376,6 +410,51 @@ ps_init(void *lpt) return dev; } +static void * +pcl_init(void *lpt) +{ + ps_t *dev; + gsapi_revision_t rev; + + dev = (ps_t *) malloc(sizeof(ps_t)); + memset(dev, 0x00, sizeof(ps_t)); + dev->ctrl = 0x04; + dev->lpt = lpt; + dev->pcl = true; + + /* Try loading the DLL. */ + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); +#ifdef PATH_GHOSTPCL_DLL_ALT + if (ghostscript_handle == NULL) { + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT, ghostscript_imports); + } +#endif + if (ghostscript_handle == NULL) { + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTPCL_ERROR_TITLE), plat_get_string(STRING_GHOSTPCL_ERROR_DESC)); + } else { + if (gsapi_revision(&rev, sizeof(rev)) == 0) { + pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); + } else { + dynld_close(ghostscript_handle); + ghostscript_handle = NULL; + } + } + + /* Cache print folder path. */ + memset(dev->printer_path, 0x00, sizeof(dev->printer_path)); + path_append_filename(dev->printer_path, usr_path, "printer"); + if (!plat_dir_check(dev->printer_path)) + plat_dir_create(dev->printer_path); + path_slash(dev->printer_path); + + timer_add(&dev->pulse_timer, pulse_timer, dev, 0); + timer_add(&dev->timeout_timer, timeout_timer, dev, 0); + + reset_ps(dev); + + return dev; +} + static void ps_close(void *priv) { @@ -406,3 +485,15 @@ const lpt_device_t lpt_prt_ps_device = { .read_status = ps_read_status, .read_ctrl = NULL }; + +const lpt_device_t lpt_prt_pcl_device = { + .name = "Generic PCL5e Printer", + .internal_name = "pcl", + .init = pcl_init, + .close = ps_close, + .write_data = ps_write_data, + .write_ctrl = ps_write_ctrl, + .read_data = NULL, + .read_status = ps_read_status, + .read_ctrl = NULL +}; diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index edfefa39f..a200e38ec 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -585,14 +585,17 @@ c16stombs(char dst[], const uint16_t src[], int len) #ifdef _WIN32 # if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) -# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GPCL "gpcl6dll64.dll" # else -# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_GPCL "gpcl6dll32.dll" # endif # define LIB_NAME_PCAP "Npcap" # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" +# define LIB_NAME_GPCL "libgpcl6" # define LIB_NAME_PCAP "libpcap" # define MOUSE_CAPTURE_KEYSEQ "Ctrl+End" #endif @@ -613,6 +616,8 @@ ProgSettings::reloadStrings() translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure %1 is installed and that you are on a %1-compatible network connection.").arg(LIB_NAME_PCAP).toStdWString(); translatedstrings[STRING_GHOSTSCRIPT_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = QCoreApplication::translate("", "%1 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.").arg(LIB_NAME_GS).toStdWString(); + translatedstrings[STRING_GHOSTPCL_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize GhostPCL").toStdWString(); + translatedstrings[STRING_GHOSTPCL_ERROR_DESC] = QCoreApplication::translate("", "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files.").arg(LIB_NAME_GPCL).toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); diff --git a/src/unix/unix.c b/src/unix/unix.c index 58cb1448f..e08b82133 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -266,6 +266,10 @@ plat_get_string(int i) return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; case STRING_GHOSTSCRIPT_ERROR_TITLE: return L"Unable to initialize Ghostscript"; + case STRING_GHOSTPCL_ERROR_TITLE: + return L"Unable to initialize GhostPCL"; + case STRING_GHOSTPCL_ERROR_DESC: + return L"libgpcl6 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files."; case STRING_HW_NOT_AVAILABLE_MACHINE: return L"Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine."; case STRING_HW_NOT_AVAILABLE_VIDEO: From 26d9d7131ac6e3067b71abf841a2107f594068d6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Jun 2024 00:09:52 +0200 Subject: [PATCH 650/690] Mask out the upper 3 bits at MCR write, the serial ports now pass Check-It 2.1's MCR test. --- src/device/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/serial.c b/src/device/serial.c index ab26fc622..2a61347a1 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -597,7 +597,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) serial_reset_fifo(dev); if (dev->sd && dev->sd->dtr_callback && (val ^ dev->mctrl) & 1) dev->sd->dtr_callback(dev, val & 1, dev->sd->priv); - dev->mctrl = val; + dev->mctrl = val & 0x1f; if (val & 0x10) { new_msr = (val & 0x0c) << 4; new_msr |= (val & 0x02) ? 0x10 : 0; From 77c6296084b189417c48fb4655dd86f471d3402b Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 21 Jun 2024 18:08:44 -0400 Subject: [PATCH 651/690] Fix up scancode table formatting (Part 1) --- src/device/keyboard_at.c | 1116 +++++++++++++++++++++++------------ src/device/keyboard_xt.c | 515 ++++++++-------- src/machine/m_amstrad.c | 374 ++++++++---- src/machine/m_tandy.c | 515 ++++++++-------- src/machine/m_xt_olivetti.c | 1030 ++++++++++++++++---------------- 5 files changed, 2029 insertions(+), 1521 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 7accb2fd6..aea35e995 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -81,397 +81,769 @@ static uint16_t bat_counter = 0; static const scancode scancode_set1[512] = { // clang-format off - { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ - { { 0x04,0},{ 0x84,0} }, { { 0x05,0},{ 0x85,0} }, { { 0x06,0},{ 0x86,0} }, { { 0x07,0},{ 0x87,0} }, /*004*/ - { { 0x08,0},{ 0x88,0} }, { { 0x09,0},{ 0x89,0} }, { { 0x0a,0},{ 0x8a,0} }, { { 0x0b,0},{ 0x8b,0} }, /*008*/ - { { 0x0c,0},{ 0x8c,0} }, { { 0x0d,0},{ 0x8d,0} }, { { 0x0e,0},{ 0x8e,0} }, { { 0x0f,0},{ 0x8f,0} }, /*00c*/ - { { 0x10,0},{ 0x90,0} }, { { 0x11,0},{ 0x91,0} }, { { 0x12,0},{ 0x92,0} }, { { 0x13,0},{ 0x93,0} }, /*010*/ - { { 0x14,0},{ 0x94,0} }, { { 0x15,0},{ 0x95,0} }, { { 0x16,0},{ 0x96,0} }, { { 0x17,0},{ 0x97,0} }, /*014*/ - { { 0x18,0},{ 0x98,0} }, { { 0x19,0},{ 0x99,0} }, { { 0x1a,0},{ 0x9a,0} }, { { 0x1b,0},{ 0x9b,0} }, /*018*/ - { { 0x1c,0},{ 0x9c,0} }, { { 0x1d,0},{ 0x9d,0} }, { { 0x1e,0},{ 0x9e,0} }, { { 0x1f,0},{ 0x9f,0} }, /*01c*/ - { { 0x20,0},{ 0xa0,0} }, { { 0x21,0},{ 0xa1,0} }, { { 0x22,0},{ 0xa2,0} }, { { 0x23,0},{ 0xa3,0} }, /*020*/ - { { 0x24,0},{ 0xa4,0} }, { { 0x25,0},{ 0xa5,0} }, { { 0x26,0},{ 0xa6,0} }, { { 0x27,0},{ 0xa7,0} }, /*024*/ - { { 0x28,0},{ 0xa8,0} }, { { 0x29,0},{ 0xa9,0} }, { { 0x2a,0},{ 0xaa,0} }, { { 0x2b,0},{ 0xab,0} }, /*028*/ - { { 0x2c,0},{ 0xac,0} }, { { 0x2d,0},{ 0xad,0} }, { { 0x2e,0},{ 0xae,0} }, { { 0x2f,0},{ 0xaf,0} }, /*02c*/ - { { 0x30,0},{ 0xb0,0} }, { { 0x31,0},{ 0xb1,0} }, { { 0x32,0},{ 0xb2,0} }, { { 0x33,0},{ 0xb3,0} }, /*030*/ - { { 0x34,0},{ 0xb4,0} }, { { 0x35,0},{ 0xb5,0} }, { { 0x36,0},{ 0xb6,0} }, { { 0x37,0},{ 0xb7,0} }, /*034*/ - { { 0x38,0},{ 0xb8,0} }, { { 0x39,0},{ 0xb9,0} }, { { 0x3a,0},{ 0xba,0} }, { { 0x3b,0},{ 0xbb,0} }, /*038*/ - { { 0x3c,0},{ 0xbc,0} }, { { 0x3d,0},{ 0xbd,0} }, { { 0x3e,0},{ 0xbe,0} }, { { 0x3f,0},{ 0xbf,0} }, /*03c*/ - { { 0x40,0},{ 0xc0,0} }, { { 0x41,0},{ 0xc1,0} }, { { 0x42,0},{ 0xc2,0} }, { { 0x43,0},{ 0xc3,0} }, /*040*/ - { { 0x44,0},{ 0xc4,0} }, { { 0x45,0},{ 0xc5,0} }, { { 0x46,0},{ 0xc6,0} }, { { 0x47,0},{ 0xc7,0} }, /*044*/ - { { 0x48,0},{ 0xc8,0} }, { { 0x49,0},{ 0xc9,0} }, { { 0x4a,0},{ 0xca,0} }, { { 0x4b,0},{ 0xcb,0} }, /*048*/ - { { 0x4c,0},{ 0xcc,0} }, { { 0x4d,0},{ 0xcd,0} }, { { 0x4e,0},{ 0xce,0} }, { { 0x4f,0},{ 0xcf,0} }, /*04c*/ - { { 0x50,0},{ 0xd0,0} }, { { 0x51,0},{ 0xd1,0} }, { { 0x52,0},{ 0xd2,0} }, { { 0x53,0},{ 0xd3,0} }, /*050*/ - { { 0x54,0},{ 0xd4,0} }, { { 0x55,0},{ 0xd5,0} }, { { 0x56,0},{ 0xd6,0} }, { { 0x57,0},{ 0xd7,0} }, /*054*/ - { { 0x58,0},{ 0xd8,0} }, { { 0x59,0},{ 0xd9,0} }, { { 0x5a,0},{ 0xda,0} }, { { 0x5b,0},{ 0xdb,0} }, /*058*/ - { { 0x5c,0},{ 0xdc,0} }, { { 0x5d,0},{ 0xdd,0} }, { { 0x5e,0},{ 0xde,0} }, { { 0x5f,0},{ 0xdf,0} }, /*05c*/ - { { 0x60,0},{ 0xe0,0} }, { { 0x61,0},{ 0xe1,0} }, { { 0x62,0},{ 0xe2,0} }, { { 0x63,0},{ 0xe3,0} }, /*060*/ - { { 0x64,0},{ 0xe4,0} }, { { 0x65,0},{ 0xe5,0} }, { { 0x66,0},{ 0xe6,0} }, { { 0x67,0},{ 0xe7,0} }, /*064*/ - { { 0x68,0},{ 0xe8,0} }, { { 0x69,0},{ 0xe9,0} }, { { 0x6a,0},{ 0xea,0} }, { { 0x6b,0},{ 0xeb,0} }, /*068*/ - { { 0x6c,0},{ 0xec,0} }, { { 0x6d,0},{ 0xed,0} }, { { 0x6e,0},{ 0xee,0} }, { { 0x6f,0},{ 0xef,0} }, /*06c*/ - { { 0x70,0},{ 0xf0,0} }, { { 0x71,0},{ 0xf1,0} }, { { 0x72,0},{ 0xf2,0} }, { { 0x73,0},{ 0xf3,0} }, /*070*/ - { { 0x74,0},{ 0xf4,0} }, { { 0x75,0},{ 0xf5,0} }, { { 0x76,0},{ 0xf6,0} }, { { 0x77,0},{ 0xf7,0} }, /*074*/ - { { 0x78,0},{ 0xf8,0} }, { { 0x79,0},{ 0xf9,0} }, { { 0x7a,0},{ 0xfa,0} }, { { 0x7b,0},{ 0xfb,0} }, /*078*/ - { { 0x7c,0},{ 0xfc,0} }, { { 0x7d,0},{ 0xfd,0} }, { { 0x7e,0},{ 0xfe,0} }, { { 0x7f,0},{ 0xff,0} }, /*07c*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ + { { 0x54, 0 }, { 0xd4, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 054 */ + { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x57, 0 }, { 0xd7, 0 } }, /* 056 */ + { { 0x58, 0 }, { 0xd8, 0 } }, { { 0x59, 0 }, { 0xd9, 0 } }, /* 058 */ + { { 0x5a, 0 }, { 0xda, 0 } }, { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05a */ + { { 0x5c, 0 }, { 0xdc, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05c */ + { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05e */ + { { 0x60, 0 }, { 0xe0, 0 } }, { { 0x61, 0 }, { 0xe1, 0 } }, /* 060 */ + { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 062 */ + { { 0x64, 0 }, { 0xe4, 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 064 */ + { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x67, 0 }, { 0xe7, 0 } }, /* 066 */ + { { 0x68, 0 }, { 0xe8, 0 } }, { { 0x69, 0 }, { 0xe9, 0 } }, /* 068 */ + { { 0x6a, 0 }, { 0xea, 0 } }, { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06a */ + { { 0x6c, 0 }, { 0xec, 0 } }, { { 0x6d, 0 }, { 0xed, 0 } }, /* 06c */ + { { 0x6e, 0 }, { 0xee, 0 } }, { { 0x6f, 0 }, { 0xef, 0 } }, /* 06e */ + { { 0x70, 0 }, { 0xf0, 0 } }, { { 0x71, 0 }, { 0xf1, 0 } }, /* 070 */ + { { 0x72, 0 }, { 0xf2, 0 } }, { { 0x73, 0 }, { 0xf3, 0 } }, /* 072 */ + { { 0x74, 0 }, { 0xf4, 0 } }, { { 0x75, 0 }, { 0xf5, 0 } }, /* 074 */ + { { 0x76, 0 }, { 0xf6, 0 } }, { { 0x77, 0 }, { 0xf7, 0 } }, /* 076 */ + { { 0x78, 0 }, { 0xf8, 0 } }, { { 0x79, 0 }, { 0xf9, 0 } }, /* 078 */ + { { 0x7a, 0 }, { 0xfa, 0 } }, { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07a */ + { { 0x7c, 0 }, { 0xfc, 0 } }, { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07c */ + { { 0x7e, 0 }, { 0xfe, 0 } }, { { 0x7f, 0 }, { 0xff, 0 } }, /* 07e */ - { { 0x80,0},{ 0} }, { { 0x81,0},{ 0} }, { { 0x82,0},{ 0} }, { { 0},{ 0} }, /*080*/ - { { 0},{ 0} }, { { 0x85,0},{ 0} }, { { 0x86,0},{ 0} }, { { 0x87,0},{ 0} }, /*084*/ - { { 0x88,0},{ 0} }, { { 0x89,0},{ 0} }, { { 0x8a,0},{ 0} }, { { 0x8b,0},{ 0} }, /*088*/ - { { 0x8c,0},{ 0} }, { { 0x8d,0},{ 0} }, { { 0x8e,0},{ 0} }, { { 0x8f,0},{ 0} }, /*08c*/ - { { 0x90,0},{ 0} }, { { 0x91,0},{ 0} }, { { 0x92,0},{ 0} }, { { 0x93,0},{ 0} }, /*090*/ - { { 0x94,0},{ 0} }, { { 0x95,0},{ 0} }, { { 0x96,0},{ 0} }, { { 0x97,0},{ 0} }, /*094*/ - { { 0x98,0},{ 0} }, { { 0x99,0},{ 0} }, { { 0x9a,0},{ 0} }, { { 0x9b,0},{ 0} }, /*098*/ - { { 0x9c,0},{ 0} }, { { 0x9d,0},{ 0} }, { { 0x9e,0},{ 0} }, { { 0x9f,0},{ 0} }, /*09c*/ - { { 0xa0,0},{ 0} }, { { 0xa1,0},{ 0} }, { { 0xa2,0},{ 0} }, { { 0xa3,0},{ 0} }, /*0a0*/ - { { 0xa4,0},{ 0} }, { { 0xa5,0},{ 0} }, { { 0xa6,0},{ 0} }, { { 0xa7,0},{ 0} }, /*0a4*/ - { { 0xa8,0},{ 0} }, { { 0xa9,0},{ 0} }, { { 0xaa,0},{ 0} }, { { 0xab,0},{ 0} }, /*0a8*/ - { { 0xac,0},{ 0} }, { { 0xad,0},{ 0} }, { { 0xae,0},{ 0} }, { { 0xaf,0},{ 0} }, /*0ac*/ - { { 0xb0,0},{ 0} }, { { 0xb1,0},{ 0} }, { { 0xb2,0},{ 0} }, { { 0xb3,0},{ 0} }, /*0b0*/ - { { 0xb4,0},{ 0} }, { { 0xb5,0},{ 0} }, { { 0xb6,0},{ 0} }, { { 0xb7,0},{ 0} }, /*0b4*/ - { { 0xb8,0},{ 0} }, { { 0xb9,0},{ 0} }, { { 0xba,0},{ 0} }, { { 0xbb,0},{ 0} }, /*0b8*/ - { { 0xbc,0},{ 0} }, { { 0xbd,0},{ 0} }, { { 0xbe,0},{ 0} }, { { 0xbf,0},{ 0} }, /*0bc*/ - { { 0xc0,0},{ 0} }, { { 0xc1,0},{ 0} }, { { 0xc2,0},{ 0} }, { { 0xc3,0},{ 0} }, /*0c0*/ - { { 0xc4,0},{ 0} }, { { 0xc5,0},{ 0} }, { { 0xc6,0},{ 0} }, { { 0xc7,0},{ 0} }, /*0c4*/ - { { 0xc8,0},{ 0} }, { { 0xc9,0},{ 0} }, { { 0xca,0},{ 0} }, { { 0xcb,0},{ 0} }, /*0c8*/ - { { 0xcc,0},{ 0} }, { { 0xcd,0},{ 0} }, { { 0xce,0},{ 0} }, { { 0xcf,0},{ 0} }, /*0cc*/ - { { 0xd0,0},{ 0} }, { { 0xd1,0},{ 0} }, { { 0xd2,0},{ 0} }, { { 0xd3,0},{ 0} }, /*0d0*/ - { { 0xd4,0},{ 0} }, { { 0xd5,0},{ 0} }, { { 0xd6,0},{ 0} }, { { 0xd7,0},{ 0} }, /*0d4*/ - { { 0xd8,0},{ 0} }, { { 0xd9,0},{ 0} }, { { 0xda,0},{ 0} }, { { 0xdb,0},{ 0} }, /*0d8*/ - { { 0xdc,0},{ 0} }, { { 0xdd,0},{ 0} }, { { 0xde,0},{ 0} }, { { 0xdf,0},{ 0} }, /*0dc*/ - { { 0xe0,0},{ 0} }, { { 0xe1,0},{ 0} }, { { 0xe2,0},{ 0} }, { { 0xe3,0},{ 0} }, /*0e0*/ - { { 0xe4,0},{ 0} }, { { 0xe5,0},{ 0} }, { { 0xe6,0},{ 0} }, { { 0xe7,0},{ 0} }, /*0e4*/ - { { 0xe8,0},{ 0} }, { { 0xe9,0},{ 0} }, { { 0xea,0},{ 0} }, { { 0xeb,0},{ 0} }, /*0e8*/ - { { 0xec,0},{ 0} }, { { 0xed,0},{ 0} }, { { 0xee,0},{ 0} }, { { 0xef,0},{ 0} }, /*0ec*/ - { { 0},{ 0} }, { { 0xf1,0},{ 0} }, { { 0xf2,0},{ 0} }, { { 0xf3,0},{ 0} }, /*0f0*/ - { { 0xf4,0},{ 0} }, { { 0xf5,0},{ 0} }, { { 0xf6,0},{ 0} }, { { 0xf7,0},{ 0} }, /*0f4*/ - { { 0xf8,0},{ 0} }, { { 0xf9,0},{ 0} }, { { 0xfa,0},{ 0} }, { { 0xfb,0},{ 0} }, /*0f8*/ - { { 0xfc,0},{ 0} }, { { 0xfd,0},{ 0} }, { { 0xfe,0},{ 0} }, { { 0xff,0},{ 0} }, /*0fc*/ + { { 0x80, 0 }, { 0 } }, { { 0x81, 0 }, { 0 } }, /* 080 */ + { { 0x82, 0 }, { 0 } }, { { 0 } ,{ 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0x85, 0 }, { 0 } }, /* 084 */ + { { 0x86, 0 }, { 0 } }, { { 0x87, 0 }, { 0 } }, /* 086 */ + { { 0x88, 0 }, { 0 } }, { { 0x89, 0 }, { 0 } }, /* 088 */ + { { 0x8a, 0 }, { 0 } }, { { 0x8b, 0 }, { 0 } }, /* 08a */ + { { 0x8c, 0 }, { 0 } }, { { 0x8d, 0 }, { 0 } }, /* 08c */ + { { 0x8e, 0 }, { 0 } }, { { 0x8f, 0 }, { 0 } }, /* 08e */ + { { 0x90, 0 }, { 0 } }, { { 0x91, 0 }, { 0 } }, /* 090 */ + { { 0x92, 0 }, { 0 } }, { { 0x93, 0 }, { 0 } }, /* 092 */ + { { 0x94, 0 }, { 0 } }, { { 0x95, 0 }, { 0 } }, /* 094 */ + { { 0x96, 0 }, { 0 } }, { { 0x97, 0 }, { 0 } }, /* 096 */ + { { 0x98, 0 }, { 0 } }, { { 0x99, 0 }, { 0 } }, /* 098 */ + { { 0x9a, 0 }, { 0 } }, { { 0x9b, 0 }, { 0 } }, /* 09a */ + { { 0x9c, 0 }, { 0 } }, { { 0x9d, 0 }, { 0 } }, /* 09c */ + { { 0x9e, 0 }, { 0 } }, { { 0x9f, 0 }, { 0 } }, /* 09e */ + { { 0xa0, 0 }, { 0 } }, { { 0xa1, 0 }, { 0 } }, /* 0a0 */ + { { 0xa2, 0 }, { 0 } }, { { 0xa3, 0 }, { 0 } }, /* 0a2 */ + { { 0xa4, 0 }, { 0 } }, { { 0xa5, 0 }, { 0 } }, /* 0a4 */ + { { 0xa6, 0 }, { 0 } }, { { 0xa7, 0 }, { 0 } }, /* 0a6 */ + { { 0xa8, 0 }, { 0 } }, { { 0xa9, 0 }, { 0 } }, /* 0a8 */ + { { 0xaa, 0 }, { 0 } }, { { 0xab, 0 }, { 0 } }, /* 0aa */ + { { 0xac, 0 }, { 0 } }, { { 0xad, 0 }, { 0 } }, /* 0ac */ + { { 0xae, 0 }, { 0 } }, { { 0xaf, 0 }, { 0 } }, /* 0ae */ + { { 0xb0, 0 }, { 0 } }, { { 0xb1, 0 }, { 0 } }, /* 0b0 */ + { { 0xb2, 0 }, { 0 } }, { { 0xb3, 0 }, { 0 } }, /* 0b2 */ + { { 0xb4, 0 }, { 0 } }, { { 0xb5, 0 }, { 0 } }, /* 0b4 */ + { { 0xb6, 0 }, { 0 } }, { { 0xb7, 0 }, { 0 } }, /* 0b6 */ + { { 0xb8, 0 }, { 0 } }, { { 0xb9, 0 }, { 0 } }, /* 0b8 */ + { { 0xba, 0 }, { 0 } }, { { 0xbb, 0 }, { 0 } }, /* 0ba */ + { { 0xbc, 0 }, { 0 } }, { { 0xbd, 0 }, { 0 } }, /* 0bc */ + { { 0xbe, 0 }, { 0 } }, { { 0xbf, 0 }, { 0 } }, /* 0be */ + { { 0xc0, 0 }, { 0 } }, { { 0xc1, 0 }, { 0 } }, /* 0c0 */ + { { 0xc2, 0 }, { 0 } }, { { 0xc3, 0 }, { 0 } }, /* 0c2 */ + { { 0xc4, 0 }, { 0 } }, { { 0xc5, 0 }, { 0 } }, /* 0c4 */ + { { 0xc6, 0 }, { 0 } }, { { 0xc7, 0 }, { 0 } }, /* 0c6 */ + { { 0xc8, 0 }, { 0 } }, { { 0xc9, 0 }, { 0 } }, /* 0c8 */ + { { 0xca, 0 }, { 0 } }, { { 0xcb, 0 }, { 0 } }, /* 0ca */ + { { 0xcc, 0 }, { 0 } }, { { 0xcd, 0 }, { 0 } }, /* 0cc */ + { { 0xce, 0 }, { 0 } }, { { 0xcf, 0 }, { 0 } }, /* 0ce */ + { { 0xd0, 0 }, { 0 } }, { { 0xd1, 0 }, { 0 } }, /* 0d0 */ + { { 0xd2, 0 }, { 0 } }, { { 0xd3, 0 }, { 0 } }, /* 0d2 */ + { { 0xd4, 0 }, { 0 } }, { { 0xd5, 0 }, { 0 } }, /* 0d4 */ + { { 0xd6, 0 }, { 0 } }, { { 0xd7, 0 }, { 0 } }, /* 0d6 */ + { { 0xd8, 0 }, { 0 } }, { { 0xd9, 0 }, { 0 } }, /* 0d8 */ + { { 0xda, 0 }, { 0 } }, { { 0xdb, 0 }, { 0 } }, /* 0da */ + { { 0xdc, 0 }, { 0 } }, { { 0xdd, 0 }, { 0 } }, /* 0dc */ + { { 0xde, 0 }, { 0 } }, { { 0xdf, 0 }, { 0 } }, /* 0de */ + { { 0xe0, 0 }, { 0 } }, { { 0xe1, 0 }, { 0 } }, /* 0e0 */ + { { 0xe2, 0 }, { 0 } }, { { 0xe3, 0 }, { 0 } }, /* 0e2 */ + { { 0xe4, 0 }, { 0 } }, { { 0xe5, 0 }, { 0 } }, /* 0e4 */ + { { 0xe6, 0 }, { 0 } }, { { 0xe7, 0 }, { 0 } }, /* 0e6 */ + { { 0xe8, 0 }, { 0 } }, { { 0xe9, 0 }, { 0 } }, /* 0e8 */ + { { 0xea, 0 }, { 0 } }, { { 0xeb, 0 }, { 0 } }, /* 0ea */ + { { 0xec, 0 }, { 0 } }, { { 0xed, 0 }, { 0 } }, /* 0ec */ + { { 0xee, 0 }, { 0 } }, { { 0xef, 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0 } }, /* 0f0 */ + { { 0xf2, 0 }, { 0 } }, { { 0xf3, 0 }, { 0 } }, /* 0f2 */ + { { 0xf4, 0 }, { 0 } }, { { 0xf5, 0 }, { 0 } }, /* 0f4 */ + { { 0xf6, 0 }, { 0 } }, { { 0xf7, 0 }, { 0 } }, /* 0f6 */ + { { 0xf8, 0 }, { 0 } }, { { 0xf9, 0 }, { 0 } }, /* 0f8 */ + { { 0xfa, 0 }, { 0 } }, { { 0xfb, 0 }, { 0 } }, /* 0fa */ + { { 0xfc, 0 }, { 0 } }, { { 0xfd, 0 }, { 0 } }, /* 0fc */ + { { 0xfe, 0 }, { 0 } }, { { 0xff, 0 }, { 0 } }, /* 0fe */ - { {0xe1,0x1d,0},{0xe1, 0x9d,0} }, { {0xe0,0x01,0},{0xe0, 0x81,0} }, { {0xe0,0x02,0},{0xe0, 0x82,0} }, { {0xe0,0x03,0},{0xe0, 0x83,0} }, /*100*/ - { {0xe0,0x04,0},{0xe0, 0x84,0} }, { {0xe0,0x05,0},{0xe0, 0x85,0} }, { {0xe0,0x06,0},{0xe0, 0x86,0} }, { {0xe0,0x07,0},{0xe0, 0x87,0} }, /*104*/ - { {0xe0,0x08,0},{0xe0, 0x88,0} }, { {0xe0,0x09,0},{0xe0, 0x89,0} }, { {0xe0,0x0a,0},{0xe0, 0x8a,0} }, { {0xe0,0x0b,0},{0xe0, 0x8b,0} }, /*108*/ - { {0xe0,0x0c,0},{0xe0, 0x8c,0} }, { { 0},{ 0} }, { {0xe0,0x0e,0},{0xe0, 0x8e,0} }, { {0xe0,0x0f,0},{0xe0, 0x8f,0} }, /*10c*/ - { {0xe0,0x10,0},{0xe0, 0x90,0} }, { {0xe0,0x11,0},{0xe0, 0x91,0} }, { {0xe0,0x12,0},{0xe0, 0x92,0} }, { {0xe0,0x13,0},{0xe0, 0x93,0} }, /*110*/ - { {0xe0,0x14,0},{0xe0, 0x94,0} }, { {0xe0,0x15,0},{0xe0, 0x95,0} }, { {0xe0,0x16,0},{0xe0, 0x96,0} }, { {0xe0,0x17,0},{0xe0, 0x97,0} }, /*114*/ - { {0xe0,0x18,0},{0xe0, 0x98,0} }, { {0xe0,0x19,0},{0xe0, 0x99,0} }, { {0xe0,0x1a,0},{0xe0, 0x9a,0} }, { {0xe0,0x1b,0},{0xe0, 0x9b,0} }, /*118*/ - { {0xe0,0x1c,0},{0xe0, 0x9c,0} }, { {0xe0,0x1d,0},{0xe0, 0x9d,0} }, { {0xe0,0x1e,0},{0xe0, 0x9e,0} }, { {0xe0,0x1f,0},{0xe0, 0x9f,0} }, /*11c*/ - { {0xe0,0x20,0},{0xe0, 0xa0,0} }, { {0xe0,0x21,0},{0xe0, 0xa1,0} }, { {0xe0,0x22,0},{0xe0, 0xa2,0} }, { {0xe0,0x23,0},{0xe0, 0xa3,0} }, /*120*/ - { {0xe0,0x24,0},{0xe0, 0xa4,0} }, { {0xe0,0x25,0},{0xe0, 0xa5,0} }, { {0xe0,0x26,0},{0xe0, 0xa6,0} }, { { 0},{ 0} }, /*124*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ - { {0xe0,0x2c,0},{0xe0, 0xac,0} }, { {0xe0,0x2d,0},{0xe0, 0xad,0} }, { {0xe0,0x2e,0},{0xe0, 0xae,0} }, { {0xe0,0x2f,0},{0xe0, 0xaf,0} }, /*12c*/ - { {0xe0,0x30,0},{0xe0, 0xb0,0} }, { {0xe0,0x31,0},{0xe0, 0xb1,0} }, { {0xe0,0x32,0},{0xe0, 0xb2,0} }, { { 0},{ 0} }, /*130*/ - { {0xe0,0x34,0},{0xe0, 0xb4,0} }, { {0xe0,0x35,0},{0xe0, 0xb5,0} }, { { 0},{ 0} }, { {0xe0,0x37,0},{0xe0, 0xb7,0} }, /*134*/ - { {0xe0,0x38,0},{0xe0, 0xb8,0} }, { { 0},{ 0} }, { {0xe0,0x3a,0},{0xe0, 0xba,0} }, { {0xe0,0x3b,0},{0xe0, 0xbb,0} }, /*138*/ - { {0xe0,0x3c,0},{0xe0, 0xbc,0} }, { {0xe0,0x3d,0},{0xe0, 0xbd,0} }, { {0xe0,0x3e,0},{0xe0, 0xbe,0} }, { {0xe0,0x3f,0},{0xe0, 0xbf,0} }, /*13c*/ - { {0xe0,0x40,0},{0xe0, 0xc0,0} }, { {0xe0,0x41,0},{0xe0, 0xc1,0} }, { {0xe0,0x42,0},{0xe0, 0xc2,0} }, { {0xe0,0x43,0},{0xe0, 0xc3,0} }, /*140*/ - { {0xe0,0x44,0},{0xe0, 0xc4,0} }, { { 0},{ 0} }, { {0xe0,0x46,0},{0xe0, 0xc6,0} }, { {0xe0,0x47,0},{0xe0, 0xc7,0} }, /*144*/ - { {0xe0,0x48,0},{0xe0, 0xc8,0} }, { {0xe0,0x49,0},{0xe0, 0xc9,0} }, { { 0},{ 0} }, { {0xe0,0x4b,0},{0xe0, 0xcb,0} }, /*148*/ - { {0xe0,0x4c,0},{0xe0, 0xcc,0} }, { {0xe0,0x4d,0},{0xe0, 0xcd,0} }, { {0xe0,0x4e,0},{0xe0, 0xce,0} }, { {0xe0,0x4f,0},{0xe0, 0xcf,0} }, /*14c*/ - { {0xe0,0x50,0},{0xe0, 0xd0,0} }, { {0xe0,0x51,0},{0xe0, 0xd1,0} }, { {0xe0,0x52,0},{0xe0, 0xd2,0} }, { {0xe0,0x53,0},{0xe0, 0xd3,0} }, /*150*/ - { { 0},{ 0} }, { {0xe0,0x55,0},{0xe0, 0xd5,0} }, { { 0},{ 0} }, { {0xe0,0x57,0},{0xe0, 0xd7,0} }, /*154*/ - { {0xe0,0x58,0},{0xe0, 0xd8,0} }, { {0xe0,0x59,0},{0xe0, 0xd9,0} }, { {0xe0,0x5a,0},{0xe0, 0xaa,0} }, { {0xe0,0x5b,0},{0xe0, 0xdb,0} }, /*158*/ - { {0xe0,0x5c,0},{0xe0, 0xdc,0} }, { {0xe0,0x5d,0},{0xe0, 0xdd,0} }, { {0xe0,0x5e,0},{0xe0, 0xee,0} }, { {0xe0,0x5f,0},{0xe0, 0xdf,0} }, /*15c*/ - { { 0},{ 0} }, { {0xe0,0x61,0},{0xe0, 0xe1,0} }, { {0xe0,0x62,0},{0xe0, 0xe2,0} }, { {0xe0,0x63,0},{0xe0, 0xe3,0} }, /*160*/ - { {0xe0,0x64,0},{0xe0, 0xe4,0} }, { {0xe0,0x65,0},{0xe0, 0xe5,0} }, { {0xe0,0x66,0},{0xe0, 0xe6,0} }, { {0xe0,0x67,0},{0xe0, 0xe7,0} }, /*164*/ - { {0xe0,0x68,0},{0xe0, 0xe8,0} }, { {0xe0,0x69,0},{0xe0, 0xe9,0} }, { {0xe0,0x6a,0},{0xe0, 0xea,0} }, { {0xe0,0x6b,0},{0xe0, 0xeb,0} }, /*168*/ - { {0xe0,0x6c,0},{0xe0, 0xec,0} }, { {0xe0,0x6d,0},{0xe0, 0xed,0} }, { {0xe0,0x6e,0},{0xe0, 0xee,0} }, { { 0},{ 0} }, /*16c*/ - { {0xe0,0x70,0},{0xe0, 0xf0,0} }, { {0xe0,0x71,0},{0xe0, 0xf1,0} }, { {0xe0,0x72,0},{0xe0, 0xf2,0} }, { {0xe0,0x73,0},{0xe0, 0xf3,0} }, /*170*/ - { {0xe0,0x74,0},{0xe0, 0xf4,0} }, { {0xe0,0x75,0},{0xe0, 0xf5,0} }, { { 0},{ 0} }, { {0xe0,0x77,0},{0xe0, 0xf7,0} }, /*174*/ - { {0xe0,0x78,0},{0xe0, 0xf8,0} }, { {0xe0,0x79,0},{0xe0, 0xf9,0} }, { {0xe0,0x7a,0},{0xe0, 0xfa,0} }, { {0xe0,0x7b,0},{0xe0, 0xfb,0} }, /*178*/ - { {0xe0,0x7c,0},{0xe0, 0xfc,0} }, { {0xe0,0x7d,0},{0xe0, 0xfd,0} }, { {0xe0,0x7e,0},{0xe0, 0xfe,0} }, { {0xe0,0x7f,0},{0xe0, 0xff,0} }, /*17c*/ + { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 100 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 102 */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 104 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 106 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 108 */ + { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10a */ + { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10e */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 110 */ + { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 112 */ + { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 114 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 116 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 118 */ + { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11a */ + { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11c */ + { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11e */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 120 */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 122 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 124 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12c */ + { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12e */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 130 */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 136 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ + { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13a */ + { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13c */ + { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13e */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 140 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 142 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 146 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14a */ + { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14c */ + { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14e */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 150 */ + { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 156 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 158 */ + { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15a */ + { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15c */ + { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 160 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 162 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 164 */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 166 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 168 */ + { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16a */ + { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16c */ + { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 170 */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 172 */ + { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 176 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 178 */ + { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17a */ + { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17c */ + { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17e */ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ - { { 0},{ 0} }, { {0xe0,0xe1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{ 0} }, { { 0},{ 0} }, /*1ec*/ - { { 0},{ 0} }, { {0xe0,0xf1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{ 0} }, { {0xe0,0xff,0},{ 0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0xe0, 0xee, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0xe0, 0xfe, 0 }, { 0 } }, { { 0xe0, 0xff, 0 }, { 0 } } /* 1fe */ // clang-format on }; static const scancode scancode_set2[512] = { // clang-format off - { { 0},{ 0} }, { { 0x76,0},{ 0xF0,0x76,0} }, { { 0x16,0},{ 0xF0,0x16,0} }, { { 0x1E,0},{ 0xF0,0x1E,0} }, /*000*/ - { { 0x26,0},{ 0xF0,0x26,0} }, { { 0x25,0},{ 0xF0,0x25,0} }, { { 0x2E,0},{ 0xF0,0x2E,0} }, { { 0x36,0},{ 0xF0,0x36,0} }, /*004*/ - { { 0x3D,0},{ 0xF0,0x3D,0} }, { { 0x3E,0},{ 0xF0,0x3E,0} }, { { 0x46,0},{ 0xF0,0x46,0} }, { { 0x45,0},{ 0xF0,0x45,0} }, /*008*/ - { { 0x4E,0},{ 0xF0,0x4E,0} }, { { 0x55,0},{ 0xF0,0x55,0} }, { { 0x66,0},{ 0xF0,0x66,0} }, { { 0x0D,0},{ 0xF0,0x0D,0} }, /*00c*/ - { { 0x15,0},{ 0xF0,0x15,0} }, { { 0x1D,0},{ 0xF0,0x1D,0} }, { { 0x24,0},{ 0xF0,0x24,0} }, { { 0x2D,0},{ 0xF0,0x2D,0} }, /*010*/ - { { 0x2C,0},{ 0xF0,0x2C,0} }, { { 0x35,0},{ 0xF0,0x35,0} }, { { 0x3C,0},{ 0xF0,0x3C,0} }, { { 0x43,0},{ 0xF0,0x43,0} }, /*014*/ - { { 0x44,0},{ 0xF0,0x44,0} }, { { 0x4D,0},{ 0xF0,0x4D,0} }, { { 0x54,0},{ 0xF0,0x54,0} }, { { 0x5B,0},{ 0xF0,0x5B,0} }, /*018*/ - { { 0x5A,0},{ 0xF0,0x5A,0} }, { { 0x14,0},{ 0xF0,0x14,0} }, { { 0x1C,0},{ 0xF0,0x1C,0} }, { { 0x1B,0},{ 0xF0,0x1B,0} }, /*01c*/ - { { 0x23,0},{ 0xF0,0x23,0} }, { { 0x2B,0},{ 0xF0,0x2B,0} }, { { 0x34,0},{ 0xF0,0x34,0} }, { { 0x33,0},{ 0xF0,0x33,0} }, /*020*/ - { { 0x3B,0},{ 0xF0,0x3B,0} }, { { 0x42,0},{ 0xF0,0x42,0} }, { { 0x4B,0},{ 0xF0,0x4B,0} }, { { 0x4C,0},{ 0xF0,0x4C,0} }, /*024*/ - { { 0x52,0},{ 0xF0,0x52,0} }, { { 0x0E,0},{ 0xF0,0x0E,0} }, { { 0x12,0},{ 0xF0,0x12,0} }, { { 0x5D,0},{ 0xF0,0x5D,0} }, /*028*/ - { { 0x1A,0},{ 0xF0,0x1A,0} }, { { 0x22,0},{ 0xF0,0x22,0} }, { { 0x21,0},{ 0xF0,0x21,0} }, { { 0x2A,0},{ 0xF0,0x2A,0} }, /*02c*/ - { { 0x32,0},{ 0xF0,0x32,0} }, { { 0x31,0},{ 0xF0,0x31,0} }, { { 0x3A,0},{ 0xF0,0x3A,0} }, { { 0x41,0},{ 0xF0,0x41,0} }, /*030*/ - { { 0x49,0},{ 0xF0,0x49,0} }, { { 0x4A,0},{ 0xF0,0x4A,0} }, { { 0x59,0},{ 0xF0,0x59,0} }, { { 0x7C,0},{ 0xF0,0x7C,0} }, /*034*/ - { { 0x11,0},{ 0xF0,0x11,0} }, { { 0x29,0},{ 0xF0,0x29,0} }, { { 0x58,0},{ 0xF0,0x58,0} }, { { 0x05,0},{ 0xF0,0x05,0} }, /*038*/ - { { 0x06,0},{ 0xF0,0x06,0} }, { { 0x04,0},{ 0xF0,0x04,0} }, { { 0x0C,0},{ 0xF0,0x0C,0} }, { { 0x03,0},{ 0xF0,0x03,0} }, /*03c*/ - { { 0x0B,0},{ 0xF0,0x0B,0} }, { { 0x83,0},{ 0xF0,0x83,0} }, { { 0x0A,0},{ 0xF0,0x0A,0} }, { { 0x01,0},{ 0xF0,0x01,0} }, /*040*/ - { { 0x09,0},{ 0xF0,0x09,0} }, { { 0x77,0},{ 0xF0,0x77,0} }, { { 0x7E,0},{ 0xF0,0x7E,0} }, { { 0x6C,0},{ 0xF0,0x6C,0} }, /*044*/ - { { 0x75,0},{ 0xF0,0x75,0} }, { { 0x7D,0},{ 0xF0,0x7D,0} }, { { 0x7B,0},{ 0xF0,0x7B,0} }, { { 0x6B,0},{ 0xF0,0x6B,0} }, /*048*/ - { { 0x73,0},{ 0xF0,0x73,0} }, { { 0x74,0},{ 0xF0,0x74,0} }, { { 0x79,0},{ 0xF0,0x79,0} }, { { 0x69,0},{ 0xF0,0x69,0} }, /*04c*/ - { { 0x72,0},{ 0xF0,0x72,0} }, { { 0x7A,0},{ 0xF0,0x7A,0} }, { { 0x70,0},{ 0xF0,0x70,0} }, { { 0x71,0},{ 0xF0,0x71,0} }, /*050*/ - { { 0x84,0},{ 0xF0,0x84,0} }, { { 0x60,0},{ 0xF0,0x60,0} }, { { 0x61,0},{ 0xF0,0x61,0} }, { { 0x78,0},{ 0xF0,0x78,0} }, /*054*/ - { { 0x07,0},{ 0xF0,0x07,0} }, { { 0x0F,0},{ 0xF0,0x0F,0} }, { { 0x17,0},{ 0xF0,0x17,0} }, { { 0x1F,0},{ 0xF0,0x1F,0} }, /*058*/ - { { 0x27,0},{ 0xF0,0x27,0} }, { { 0x2F,0},{ 0xF0,0x2F,0} }, { { 0x37,0},{ 0xF0,0x37,0} }, { { 0x3F,0},{ 0xF0,0x3F,0} }, /*05c*/ - { { 0x47,0},{ 0xF0,0x47,0} }, { { 0x4F,0},{ 0xF0,0x4F,0} }, { { 0x56,0},{ 0xF0,0x56,0} }, { { 0x5E,0},{ 0xF0,0x5E,0} }, /*060*/ - { { 0x08,0},{ 0xF0,0x08,0} }, { { 0x10,0},{ 0xF0,0x10,0} }, { { 0x18,0},{ 0xF0,0x18,0} }, { { 0x20,0},{ 0xF0,0x20,0} }, /*064*/ - { { 0x28,0},{ 0xF0,0x28,0} }, { { 0x30,0},{ 0xF0,0x30,0} }, { { 0x38,0},{ 0xF0,0x38,0} }, { { 0x40,0},{ 0xF0,0x40,0} }, /*068*/ - { { 0x48,0},{ 0xF0,0x48,0} }, { { 0x50,0},{ 0xF0,0x50,0} }, { { 0x57,0},{ 0xF0,0x57,0} }, { { 0x6F,0},{ 0xF0,0x6F,0} }, /*06c*/ - { { 0x13,0},{ 0xF0,0x13,0} }, { { 0x19,0},{ 0xF0,0x19,0} }, { { 0x39,0},{ 0xF0,0x39,0} }, { { 0x51,0},{ 0xF0,0x51,0} }, /*070*/ - { { 0x53,0},{ 0xF0,0x53,0} }, { { 0x5C,0},{ 0xF0,0x5C,0} }, { { 0x5F,0},{ 0xF0,0x5F,0} }, { { 0x62,0},{ 0xF0,0x62,0} }, /*074*/ - { { 0x63,0},{ 0xF0,0x63,0} }, { { 0x64,0},{ 0xF0,0x64,0} }, { { 0x65,0},{ 0xF0,0x65,0} }, { { 0x67,0},{ 0xF0,0x67,0} }, /*078*/ - { { 0x68,0},{ 0xF0,0x68,0} }, { { 0x6A,0},{ 0xF0,0x6A,0} }, { { 0x6D,0},{ 0xF0,0x6D,0} }, { { 0x6E,0},{ 0xF0,0x6E,0} }, /*07c*/ + { { 0 }, { 0 } }, { { 0x76, 0 }, { 0xF0, 0x76, 0 } }, /* 000 */ + { { 0x16, 0 }, { 0xF0, 0x16, 0 } }, { { 0x1E, 0 }, { 0xF0, 0x1E, 0 } }, /* 002 */ + { { 0x26, 0 }, { 0xF0, 0x26, 0 } }, { { 0x25, 0 }, { 0xF0, 0x25, 0 } }, + { { 0x2E, 0 }, { 0xF0, 0x2E, 0 } }, { { 0x36, 0 }, { 0xF0, 0x36, 0 } }, /* 004 */ + { { 0x3D, 0 }, { 0xF0, 0x3D, 0 } }, { { 0x3E, 0 }, { 0xF0, 0x3E, 0 } }, + { { 0x46, 0 }, { 0xF0, 0x46, 0 } }, { { 0x45, 0 }, { 0xF0, 0x45, 0 } }, /* 008 */ + { { 0x4E, 0 }, { 0xF0, 0x4E, 0 } }, { { 0x55, 0 }, { 0xF0, 0x55, 0 } }, + { { 0x66, 0 }, { 0xF0, 0x66, 0 } }, { { 0x0D, 0 }, { 0xF0, 0x0D, 0 } }, /* 00c */ + { { 0x15, 0 }, { 0xF0, 0x15, 0 } }, { { 0x1D, 0 }, { 0xF0, 0x1D, 0 } }, + { { 0x24, 0 }, { 0xF0, 0x24, 0 } }, { { 0x2D, 0 }, { 0xF0, 0x2D, 0 } }, /* 010 */ + { { 0x2C, 0 }, { 0xF0, 0x2C, 0 } }, { { 0x35, 0 }, { 0xF0, 0x35, 0 } }, + { { 0x3C, 0 }, { 0xF0, 0x3C, 0 } }, { { 0x43, 0 }, { 0xF0, 0x43, 0 } }, /* 014 */ + { { 0x44, 0 }, { 0xF0, 0x44, 0 } }, { { 0x4D, 0 }, { 0xF0, 0x4D, 0 } }, + { { 0x54, 0 }, { 0xF0, 0x54, 0 } }, { { 0x5B, 0 }, { 0xF0, 0x5B, 0 } }, /* 018 */ + { { 0x5A, 0 }, { 0xF0, 0x5A, 0 } }, { { 0x14, 0 }, { 0xF0, 0x14, 0 } }, + { { 0x1C, 0 }, { 0xF0, 0x1C, 0 } }, { { 0x1B, 0 }, { 0xF0, 0x1B, 0 } }, /* 01c */ + { { 0x23, 0 }, { 0xF0, 0x23, 0 } }, { { 0x2B, 0 }, { 0xF0, 0x2B, 0 } }, + { { 0x34, 0 }, { 0xF0, 0x34, 0 } }, { { 0x33, 0 }, { 0xF0, 0x33, 0 } }, /* 020 */ + { { 0x3B, 0 }, { 0xF0, 0x3B, 0 } }, { { 0x42, 0 }, { 0xF0, 0x42, 0 } }, + { { 0x4B, 0 }, { 0xF0, 0x4B, 0 } }, { { 0x4C, 0 }, { 0xF0, 0x4C, 0 } }, /* 024 */ + { { 0x52, 0 }, { 0xF0, 0x52, 0 } }, { { 0x0E, 0 }, { 0xF0, 0x0E, 0 } }, + { { 0x12, 0 }, { 0xF0, 0x12, 0 } }, { { 0x5D, 0 }, { 0xF0, 0x5D, 0 } }, /* 028 */ + { { 0x1A, 0 }, { 0xF0, 0x1A, 0 } }, { { 0x22, 0 }, { 0xF0, 0x22, 0 } }, + { { 0x21, 0 }, { 0xF0, 0x21, 0 } }, { { 0x2A, 0 }, { 0xF0, 0x2A, 0 } }, /* 02c */ + { { 0x32, 0 }, { 0xF0, 0x32, 0 } }, { { 0x31, 0 }, { 0xF0, 0x31, 0 } }, + { { 0x3A, 0 }, { 0xF0, 0x3A, 0 } }, { { 0x41, 0 }, { 0xF0, 0x41, 0 } }, /* 030 */ + { { 0x49, 0 }, { 0xF0, 0x49, 0 } }, { { 0x4A, 0 }, { 0xF0, 0x4A, 0 } }, + { { 0x59, 0 }, { 0xF0, 0x59, 0 } }, { { 0x7C, 0 }, { 0xF0, 0x7C, 0 } }, /* 034 */ + { { 0x11, 0 }, { 0xF0, 0x11, 0 } }, { { 0x29, 0 }, { 0xF0, 0x29, 0 } }, + { { 0x58, 0 }, { 0xF0, 0x58, 0 } }, { { 0x05, 0 }, { 0xF0, 0x05, 0 } }, /* 038 */ + { { 0x06, 0 }, { 0xF0, 0x06, 0 } }, { { 0x04, 0 }, { 0xF0, 0x04, 0 } }, + { { 0x0C, 0 }, { 0xF0, 0x0C, 0 } }, { { 0x03, 0 }, { 0xF0, 0x03, 0 } }, /* 03c */ + { { 0x0B, 0 }, { 0xF0, 0x0B, 0 } }, { { 0x83, 0 }, { 0xF0, 0x83, 0 } }, + { { 0x0A, 0 }, { 0xF0, 0x0A, 0 } }, { { 0x01, 0 }, { 0xF0, 0x01, 0 } }, /* 040 */ + { { 0x09, 0 }, { 0xF0, 0x09, 0 } }, { { 0x77, 0 }, { 0xF0, 0x77, 0 } }, + { { 0x7E, 0 }, { 0xF0, 0x7E, 0 } }, { { 0x6C, 0 }, { 0xF0, 0x6C, 0 } }, /* 044 */ + { { 0x75, 0 }, { 0xF0, 0x75, 0 } }, { { 0x7D, 0 }, { 0xF0, 0x7D, 0 } }, + { { 0x7B, 0 }, { 0xF0, 0x7B, 0 } }, { { 0x6B, 0 }, { 0xF0, 0x6B, 0 } }, /* 048 */ + { { 0x73, 0 }, { 0xF0, 0x73, 0 } }, { { 0x74, 0 }, { 0xF0, 0x74, 0 } }, + { { 0x79, 0 }, { 0xF0, 0x79, 0 } }, { { 0x69, 0 }, { 0xF0, 0x69, 0 } }, /* 04c */ + { { 0x72, 0 }, { 0xF0, 0x72, 0 } }, { { 0x7A, 0 }, { 0xF0, 0x7A, 0 } }, + { { 0x70, 0 }, { 0xF0, 0x70, 0 } }, { { 0x71, 0 }, { 0xF0, 0x71, 0 } }, /* 050 */ + { { 0x84, 0 }, { 0xF0, 0x84, 0 } }, { { 0x60, 0 }, { 0xF0, 0x60, 0 } }, + { { 0x61, 0 }, { 0xF0, 0x61, 0 } }, { { 0x78, 0 }, { 0xF0, 0x78, 0 } }, /* 054 */ + { { 0x07, 0 }, { 0xF0, 0x07, 0 } }, { { 0x0F, 0 }, { 0xF0, 0x0F, 0 } }, + { { 0x17, 0 }, { 0xF0, 0x17, 0 } }, { { 0x1F, 0 }, { 0xF0, 0x1F, 0 } }, /* 058 */ + { { 0x27, 0 }, { 0xF0, 0x27, 0 } }, { { 0x2F, 0 }, { 0xF0, 0x2F, 0 } }, + { { 0x37, 0 }, { 0xF0, 0x37, 0 } }, { { 0x3F, 0 }, { 0xF0, 0x3F, 0 } }, /* 05c */ + { { 0x47, 0 }, { 0xF0, 0x47, 0 } }, { { 0x4F, 0 }, { 0xF0, 0x4F, 0 } }, + { { 0x56, 0 }, { 0xF0, 0x56, 0 } }, { { 0x5E, 0 }, { 0xF0, 0x5E, 0 } }, /* 060 */ + { { 0x08, 0 }, { 0xF0, 0x08, 0 } }, { { 0x10, 0 }, { 0xF0, 0x10, 0 } }, + { { 0x18, 0 }, { 0xF0, 0x18, 0 } }, { { 0x20, 0 }, { 0xF0, 0x20, 0 } }, /* 064 */ + { { 0x28, 0 }, { 0xF0, 0x28, 0 } }, { { 0x30, 0 }, { 0xF0, 0x30, 0 } }, + { { 0x38, 0 }, { 0xF0, 0x38, 0 } }, { { 0x40, 0 }, { 0xF0, 0x40, 0 } }, /* 068 */ + { { 0x48, 0 }, { 0xF0, 0x48, 0 } }, { { 0x50, 0 }, { 0xF0, 0x50, 0 } }, + { { 0x57, 0 }, { 0xF0, 0x57, 0 } }, { { 0x6F, 0 }, { 0xF0, 0x6F, 0 } }, /* 06c */ + { { 0x13, 0 }, { 0xF0, 0x13, 0 } }, { { 0x19, 0 }, { 0xF0, 0x19, 0 } }, + { { 0x39, 0 }, { 0xF0, 0x39, 0 } }, { { 0x51, 0 }, { 0xF0, 0x51, 0 } }, /* 070 */ + { { 0x53, 0 }, { 0xF0, 0x53, 0 } }, { { 0x5C, 0 }, { 0xF0, 0x5C, 0 } }, + { { 0x5F, 0 }, { 0xF0, 0x5F, 0 } }, { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 074 */ + { { 0x63, 0 }, { 0xF0, 0x63, 0 } }, { { 0x64, 0 }, { 0xF0, 0x64, 0 } }, + { { 0x65, 0 }, { 0xF0, 0x65, 0 } }, { { 0x67, 0 }, { 0xF0, 0x67, 0 } }, /* 078 */ + { { 0x68, 0 }, { 0xF0, 0x68, 0 } }, { { 0x6A, 0 }, { 0xF0, 0x6A, 0 } }, + { { 0x6D, 0 }, { 0xF0, 0x6D, 0 } }, { { 0x6E, 0 }, { 0xF0, 0x6E, 0 } }, /* 07c */ - { { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/ - { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/ - { { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/ - { { 0x8c,0},{ 0xf0,0x8c,0} }, { { 0x8d,0},{ 0xf0,0x8d,0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/ - { { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/ - { { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/ - { { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/ - { { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/ - { { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/ - { { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/ - { { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/ - { { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/ - { { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/ - { { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/ - { { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/ - { { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/ - { { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/ - { { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/ - { { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/ - { { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/ - { { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/ - { { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/ - { { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/ - { { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/ - { { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/ - { { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/ - { { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/ - { { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/ - { { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/ - { { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/ - { { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/ - { { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/ + { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 080 */ + { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, + { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 084 */ + { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, + { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 088 */ + { { 0x8c, 0 }, { 0xf0, 0x8c, 0 } }, { { 0x8d, 0 }, { 0xf0, 0x8d, 0 } }, + { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08c */ + { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, + { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 090 */ + { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, + { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 094 */ + { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, + { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 098 */ + { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, + { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09c */ + { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, + { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a0 */ + { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, + { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a4 */ + { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, + { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0a8 */ + { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, + { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0ac */ + { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, + { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b0 */ + { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, + { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b4 */ + { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, + { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0b8 */ + { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, + { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bc */ + { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, + { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c0 */ + { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, + { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c4 */ + { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, + { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0c8 */ + { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, + { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cc */ + { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, + { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d0 */ + { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, + { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d4 */ + { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, + { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0d8 */ + { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, + { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0dc */ + { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, + { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e0 */ + { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, + { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e4 */ + { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, + { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0e8 */ + { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, + { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, + { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f0 */ + { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, + { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f4 */ + { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, + { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0f8 */ + { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, + { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0fc */ - { {0xe1,0x14,0},{0xe1,0xf0,0x14,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/ - { {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/ - { {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/ - { {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/ - { {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/ - { {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/ - { {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/ - { {0xe0,0x5A,0},{0xe0,0xF0,0x5A,0} }, { {0xe0,0x14,0},{0xe0,0xF0,0x14,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/ - { {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/ - { {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ - { {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/ - { {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/ - { {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { {0xe0,0x4A,0},{0xe0,0xF0,0x4A,0} }, { { 0},{ 0} }, { {0xe0,0x7C,0},{0xe0,0xF0,0x7C,0} }, /*134*/ - { {0xe0,0x11,0},{0xe0,0xF0,0x11,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/ - { {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/ - { {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/ - { {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { {0xe0,0x6C,0},{0xe0,0xF0,0x6C,0} }, /*144*/ - { {0xe0,0x75,0},{0xe0,0xF0,0x75,0} }, { {0xe0,0x7D,0},{0xe0,0xF0,0x7D,0} }, { { 0},{ 0} }, { {0xe0,0x6B,0},{0xe0,0xF0,0x6B,0} }, /*148*/ - { {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { {0xe0,0x74,0},{0xe0,0xF0,0x74,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { {0xe0,0x69,0},{0xe0,0xF0,0x69,0} }, /*14c*/ - { {0xe0,0x72,0},{0xe0,0xF0,0x72,0} }, { {0xe0,0x7A,0},{0xe0,0xF0,0x7A,0} }, { {0xe0,0x70,0},{0xe0,0xF0,0x70,0} }, { {0xe0,0x71,0},{0xe0,0xF0,0x71,0} }, /*150*/ - { { 0},{ 0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/ - { {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { {0xe0,0x1F,0},{0xe0,0xF0,0x1F,0} }, /*158*/ - { {0xe0,0x27,0},{0xe0,0xF0,0x27,0} }, { {0xe0,0x2F,0},{0xe0,0xF0,0x2F,0} }, { {0xe0,0x37,0},{0xe0,0xF0,0x37,0} }, { {0xe0,0x3F,0},{0xe0,0xF0,0x3F,0} }, /*15c*/ - { { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { {0xe0,0x5E,0},{0xe0,0xF0,0x5E,0} }, /*160*/ - { {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/ - { {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/ - { {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/ - { {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/ - { {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/ - { {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/ - { {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/ + { { 0xe1, 0x14, 0 }, { 0xe1, 0xf0, 0x14, 0 } }, { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 100 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 102 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, + { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 104 */ + { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, + { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 108 */ + { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10c */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, + { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 110 */ + { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, + { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 114 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, + { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 118 */ + { { 0xe0, 0x5A, 0 }, { 0xe0, 0xF0, 0x5A, 0 } }, { { 0xe0, 0x14, 0 }, { 0xe0, 0xF0, 0x14, 0 } }, + { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11c */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, + { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 120 */ + { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, + { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, + { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12c */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, + { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, { { 0xe0, 0x4A, 0 }, { 0xe0, 0xF0, 0x4A, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x7C, 0 }, { 0xe0, 0xF0, 0x7C, 0 } }, /* 134 */ + { { 0xe0, 0x11, 0 }, { 0xe0, 0xF0, 0x11, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 138 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, + { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13c */ + { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, + { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 140 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, { { 0xe0, 0x6C, 0 }, { 0xe0, 0xF0, 0x6C, 0 } }, /* 144 */ + { { 0xe0, 0x75, 0 }, { 0xe0, 0xF0, 0x75, 0 } }, { { 0xe0, 0x7D, 0 }, { 0xe0, 0xF0, 0x7D, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x6B, 0 }, { 0xe0, 0xF0, 0x6B, 0 } }, /* 148 */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, { { 0xe0, 0x74, 0 }, { 0xe0, 0xF0, 0x74, 0 } }, + { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xF0, 0x69, 0 } }, /* 14c */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xF0, 0x72, 0 } }, { { 0xe0, 0x7A, 0 }, { 0xe0, 0xF0, 0x7A, 0 } }, + { { 0xe0, 0x70, 0 }, { 0xe0, 0xF0, 0x70, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xF0, 0x71, 0 } }, /* 150 */ + { { 0 }, { 0 } }, { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 154 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, + { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, { { 0xe0, 0x1F, 0 }, { 0xe0, 0xF0, 0x1F, 0 } }, /* 158 */ + { { 0xe0, 0x27, 0 }, { 0xe0, 0xF0, 0x27, 0 } }, { { 0xe0, 0x2F, 0 }, { 0xe0, 0xF0, 0x2F, 0 } }, + { { 0xe0, 0x37, 0 }, { 0xe0, 0xF0, 0x37, 0 } }, { { 0xe0, 0x3F, 0 }, { 0xe0, 0xF0, 0x3F, 0 } }, /* 15c */ + { { 0 }, { 0 } }, { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, + { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, { { 0xe0, 0x5E, 0 }, { 0xe0, 0xF0, 0x5E, 0 } }, /* 160 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, + { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 164 */ + { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, + { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 168 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, + { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, + { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 170 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 174 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, + { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 178 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, + { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17c */ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ - { { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/ - { { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1fc */ // clang-format on }; static const scancode scancode_set3[512] = { // clang-format off - { { 0},{ 0} }, { { 0x08,0},{ 0xf0,0x08,0} }, { { 0x16,0},{ 0xf0,0x16,0} }, { { 0x1E,0},{ 0xf0,0x1E,0} }, /*000*/ - { { 0x26,0},{ 0xf0,0x26,0} }, { { 0x25,0},{ 0xf0,0x25,0} }, { { 0x2E,0},{ 0xf0,0x2E,0} }, { { 0x36,0},{ 0xf0,0x36,0} }, /*004*/ - { { 0x3D,0},{ 0xf0,0x3D,0} }, { { 0x3E,0},{ 0xf0,0x3E,0} }, { { 0x46,0},{ 0xf0,0x46,0} }, { { 0x45,0},{ 0xf0,0x45,0} }, /*008*/ - { { 0x4E,0},{ 0xf0,0x4E,0} }, { { 0x55,0},{ 0xf0,0x55,0} }, { { 0x66,0},{ 0xf0,0x66,0} }, { { 0x0D,0},{ 0xf0,0x0D,0} }, /*00c*/ - { { 0x15,0},{ 0xf0,0x15,0} }, { { 0x1D,0},{ 0xf0,0x1D,0} }, { { 0x24,0},{ 0xf0,0x24,0} }, { { 0x2D,0},{ 0xf0,0x2D,0} }, /*010*/ - { { 0x2C,0},{ 0xf0,0x2C,0} }, { { 0x35,0},{ 0xf0,0x35,0} }, { { 0x3C,0},{ 0xf0,0x3C,0} }, { { 0x43,0},{ 0xf0,0x43,0} }, /*014*/ - { { 0x44,0},{ 0xf0,0x44,0} }, { { 0x4D,0},{ 0xf0,0x4D,0} }, { { 0x54,0},{ 0xf0,0x54,0} }, { { 0x5B,0},{ 0xf0,0x5B,0} }, /*018*/ - { { 0x5A,0},{ 0xf0,0x5A,0} }, { { 0x11,0},{ 0xf0,0x11,0} }, { { 0x1C,0},{ 0xf0,0x1C,0} }, { { 0x1B,0},{ 0xf0,0x1B,0} }, /*01c*/ - { { 0x23,0},{ 0xf0,0x23,0} }, { { 0x2B,0},{ 0xf0,0x2B,0} }, { { 0x34,0},{ 0xf0,0x34,0} }, { { 0x33,0},{ 0xf0,0x33,0} }, /*020*/ - { { 0x3B,0},{ 0xf0,0x3B,0} }, { { 0x42,0},{ 0xf0,0x42,0} }, { { 0x4B,0},{ 0xf0,0x4B,0} }, { { 0x4C,0},{ 0xf0,0x4C,0} }, /*024*/ - { { 0x52,0},{ 0xf0,0x52,0} }, { { 0x0E,0},{ 0xf0,0x0E,0} }, { { 0x12,0},{ 0xf0,0x12,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, /*028*/ - { { 0x1A,0},{ 0xf0,0x1A,0} }, { { 0x22,0},{ 0xf0,0x22,0} }, { { 0x21,0},{ 0xf0,0x21,0} }, { { 0x2A,0},{ 0xf0,0x2A,0} }, /*02c*/ - { { 0x32,0},{ 0xf0,0x32,0} }, { { 0x31,0},{ 0xf0,0x31,0} }, { { 0x3A,0},{ 0xf0,0x3A,0} }, { { 0x41,0},{ 0xf0,0x41,0} }, /*030*/ - { { 0x49,0},{ 0xf0,0x49,0} }, { { 0x4A,0},{ 0xf0,0x4A,0} }, { { 0x59,0},{ 0xf0,0x59,0} }, { { 0x7E,0},{ 0xf0,0x7E,0} }, /*034*/ - { { 0x19,0},{ 0xf0,0x19,0} }, { { 0x29,0},{ 0xf0,0x29,0} }, { { 0x14,0},{ 0xf0,0x14,0} }, { { 0x07,0},{ 0xf0,0x07,0} }, /*038*/ - { { 0x0F,0},{ 0xf0,0x0F,0} }, { { 0x17,0},{ 0xf0,0x17,0} }, { { 0x1F,0},{ 0xf0,0x1F,0} }, { { 0x27,0},{ 0xf0,0x27,0} }, /*03c*/ - { { 0x2F,0},{ 0xf0,0x2F,0} }, { { 0x37,0},{ 0xf0,0x37,0} }, { { 0x3F,0},{ 0xf0,0x3F,0} }, { { 0x47,0},{ 0xf0,0x47,0} }, /*040*/ - { { 0x4F,0},{ 0xf0,0x4F,0} }, { { 0x76,0},{ 0xf0,0x76,0} }, { { 0x5F,0},{ 0xf0,0x5F,0} }, { { 0x6C,0},{ 0xf0,0x6C,0} }, /*044*/ - { { 0x75,0},{ 0xf0,0x75,0} }, { { 0x7D,0},{ 0xf0,0x7D,0} }, { { 0x84,0},{ 0xf0,0x84,0} }, { { 0x6B,0},{ 0xf0,0x6B,0} }, /*048*/ - { { 0x73,0},{ 0xf0,0x73,0} }, { { 0x74,0},{ 0xf0,0x74,0} }, { { 0x7C,0},{ 0xf0,0x7C,0} }, { { 0x69,0},{ 0xf0,0x69,0} }, /*04c*/ - { { 0x72,0},{ 0xf0,0x72,0} }, { { 0x7A,0},{ 0xf0,0x7A,0} }, { { 0x70,0},{ 0xf0,0x70,0} }, { { 0x71,0},{ 0xf0,0x71,0} }, /*050*/ - { { 0x57,0},{ 0xf0,0x57,0} }, { { 0x60,0},{ 0xf0,0x60,0} }, { { 0},{ 0} }, { { 0x56,0},{ 0xf0,0x56,0} }, /*054*/ - { { 0x5E,0},{ 0xf0,0x5E,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*058*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*05c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*060*/ - { { 0},{ 0} }, { { 0x10,0},{ 0xf0,0x10,0} }, { { 0x18,0},{ 0xf0,0x18,0} }, { { 0x20,0},{ 0xf0,0x20,0} }, /*064*/ - { { 0x28,0},{ 0xf0,0x28,0} }, { { 0x30,0},{ 0xf0,0x30,0} }, { { 0x38,0},{ 0xf0,0x38,0} }, { { 0x40,0},{ 0xf0,0x40,0} }, /*068*/ - { { 0x48,0},{ 0xf0,0x48,0} }, { { 0x50,0},{ 0xf0,0x50,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*06c*/ - { { 0x87,0},{ 0xf0,0x87,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0x51,0},{ 0xf0,0x51,0} }, /*070*/ - { { 0x53,0},{ 0xf0,0x53,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, { { 0},{ 0} }, { { 0x62,0},{ 0xf0,0x62,0} }, /*074*/ - { { 0x63,0},{ 0xf0,0x63,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x85,0} }, /*078*/ - { { 0x68,0},{ 0xf0,0x68,0} }, { { 0x13,0},{ 0xf0,0x13,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*07c*/ + { { 0 }, { 0 } }, { { 0x08, 0 }, { 0xf0, 0x08, 0 } }, /* 000 */ + { { 0x16, 0 }, { 0xf0, 0x16, 0 } }, { { 0x1E, 0 }, { 0xf0, 0x1E, 0 } }, /* 002 */ + { { 0x26, 0 }, { 0xf0, 0x26, 0 } }, { { 0x25, 0 }, { 0xf0, 0x25, 0 } }, + { { 0x2E, 0 }, { 0xf0, 0x2E, 0 } }, { { 0x36, 0 }, { 0xf0, 0x36, 0 } }, /* 004 */ + { { 0x3D, 0 }, { 0xf0, 0x3D, 0 } }, { { 0x3E, 0 }, { 0xf0, 0x3E, 0 } }, + { { 0x46, 0 }, { 0xf0, 0x46, 0 } }, { { 0x45, 0 }, { 0xf0, 0x45, 0 } }, /* 008 */ + { { 0x4E, 0 }, { 0xf0, 0x4E, 0 } }, { { 0x55, 0 }, { 0xf0, 0x55, 0 } }, + { { 0x66, 0 }, { 0xf0, 0x66, 0 } }, { { 0x0D, 0 }, { 0xf0, 0x0D, 0 } }, /* 00c */ + { { 0x15, 0 }, { 0xf0, 0x15, 0 } }, { { 0x1D, 0 }, { 0xf0, 0x1D, 0 } }, + { { 0x24, 0 }, { 0xf0, 0x24, 0 } }, { { 0x2D, 0 }, { 0xf0, 0x2D, 0 } }, /* 010 */ + { { 0x2C, 0 }, { 0xf0, 0x2C, 0 } }, { { 0x35, 0 }, { 0xf0, 0x35, 0 } }, + { { 0x3C, 0 }, { 0xf0, 0x3C, 0 } }, { { 0x43, 0 }, { 0xf0, 0x43, 0 } }, /* 014 */ + { { 0x44, 0 }, { 0xf0, 0x44, 0 } }, { { 0x4D, 0 }, { 0xf0, 0x4D, 0 } }, + { { 0x54, 0 }, { 0xf0, 0x54, 0 } }, { { 0x5B, 0 }, { 0xf0, 0x5B, 0 } }, /* 018 */ + { { 0x5A, 0 }, { 0xf0, 0x5A, 0 } }, { { 0x11, 0 }, { 0xf0, 0x11, 0 } }, + { { 0x1C, 0 }, { 0xf0, 0x1C, 0 } }, { { 0x1B, 0 }, { 0xf0, 0x1B, 0 } }, /* 01c */ + { { 0x23, 0 }, { 0xf0, 0x23, 0 } }, { { 0x2B, 0 }, { 0xf0, 0x2B, 0 } }, + { { 0x34, 0 }, { 0xf0, 0x34, 0 } }, { { 0x33, 0 }, { 0xf0, 0x33, 0 } }, /* 020 */ + { { 0x3B, 0 }, { 0xf0, 0x3B, 0 } }, { { 0x42, 0 }, { 0xf0, 0x42, 0 } }, + { { 0x4B, 0 }, { 0xf0, 0x4B, 0 } }, { { 0x4C, 0 }, { 0xf0, 0x4C, 0 } }, /* 024 */ + { { 0x52, 0 }, { 0xf0, 0x52, 0 } }, { { 0x0E, 0 }, { 0xf0, 0x0E, 0 } }, + { { 0x12, 0 }, { 0xf0, 0x12, 0 } }, { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 028 */ + { { 0x1A, 0 }, { 0xf0, 0x1A, 0 } }, { { 0x22, 0 }, { 0xf0, 0x22, 0 } }, + { { 0x21, 0 }, { 0xf0, 0x21, 0 } }, { { 0x2A, 0 }, { 0xf0, 0x2A, 0 } }, /* 02c */ + { { 0x32, 0 }, { 0xf0, 0x32, 0 } }, { { 0x31, 0 }, { 0xf0, 0x31, 0 } }, + { { 0x3A, 0 }, { 0xf0, 0x3A, 0 } }, { { 0x41, 0 }, { 0xf0, 0x41, 0 } }, /* 030 */ + { { 0x49, 0 }, { 0xf0, 0x49, 0 } }, { { 0x4A, 0 }, { 0xf0, 0x4A, 0 } }, + { { 0x59, 0 }, { 0xf0, 0x59, 0 } }, { { 0x7E, 0 }, { 0xf0, 0x7E, 0 } }, /* 034 */ + { { 0x19, 0 }, { 0xf0, 0x19, 0 } }, { { 0x29, 0 }, { 0xf0, 0x29, 0 } }, + { { 0x14, 0 }, { 0xf0, 0x14, 0 } }, { { 0x07, 0 }, { 0xf0, 0x07, 0 } }, /* 038 */ + { { 0x0F, 0 }, { 0xf0, 0x0F, 0 } }, { { 0x17, 0 }, { 0xf0, 0x17, 0 } }, + { { 0x1F, 0 }, { 0xf0, 0x1F, 0 } }, { { 0x27, 0 }, { 0xf0, 0x27, 0 } }, /* 03c */ + { { 0x2F, 0 }, { 0xf0, 0x2F, 0 } }, { { 0x37, 0 }, { 0xf0, 0x37, 0 } }, + { { 0x3F, 0 }, { 0xf0, 0x3F, 0 } }, { { 0x47, 0 }, { 0xf0, 0x47, 0 } }, /* 040 */ + { { 0x4F, 0 }, { 0xf0, 0x4F, 0 } }, { { 0x76, 0 }, { 0xf0, 0x76, 0 } }, + { { 0x5F, 0 }, { 0xf0, 0x5F, 0 } }, { { 0x6C, 0 }, { 0xf0, 0x6C, 0 } }, /* 044 */ + { { 0x75, 0 }, { 0xf0, 0x75, 0 } }, { { 0x7D, 0 }, { 0xf0, 0x7D, 0 } }, + { { 0x84, 0 }, { 0xf0, 0x84, 0 } }, { { 0x6B, 0 }, { 0xf0, 0x6B, 0 } }, /* 048 */ + { { 0x73, 0 }, { 0xf0, 0x73, 0 } }, { { 0x74, 0 }, { 0xf0, 0x74, 0 } }, + { { 0x7C, 0 }, { 0xf0, 0x7C, 0 } }, { { 0x69, 0 }, { 0xf0, 0x69, 0 } }, /* 04c */ + { { 0x72, 0 }, { 0xf0, 0x72, 0 } }, { { 0x7A, 0 }, { 0xf0, 0x7A, 0 } }, + { { 0x70, 0 }, { 0xf0, 0x70, 0 } }, { { 0x71, 0 }, { 0xf0, 0x71, 0 } }, /* 050 */ + { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, + { { 0 }, { 0 } }, { { 0x56, 0 }, { 0xf0, 0x56, 0 } }, /* 054 */ + { { 0x5E, 0 }, { 0xf0, 0x5E, 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, { { 0x10, 0 }, { 0xf0, 0x10, 0 } }, + { { 0x18, 0 }, { 0xf0, 0x18, 0 } }, { { 0x20, 0 }, { 0xf0, 0x20, 0 } }, /* 064 */ + { { 0x28, 0 }, { 0xf0, 0x28, 0 } }, { { 0x30, 0 }, { 0xf0, 0x30, 0 } }, + { { 0x38, 0 }, { 0xf0, 0x38, 0 } }, { { 0x40, 0 }, { 0xf0, 0x40, 0 } }, /* 068 */ + { { 0x48, 0 }, { 0xf0, 0x48, 0 } }, { { 0x50, 0 }, { 0xf0, 0x50, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ + { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0x51, 0 }, { 0xf0, 0x51, 0 } }, /* 070 */ + { { 0x53, 0 }, { 0xf0, 0x53, 0 } }, { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, + { { 0 }, { 0 } }, { { 0x62, 0 }, { 0xf0, 0x62, 0 } }, /* 074 */ + { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, + { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x85, 0 } }, /* 078 */ + { { 0x68, 0 }, { 0xf0, 0x68, 0 } }, { { 0x13, 0 }, { 0xf0, 0x13, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - { { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/ - { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/ - { { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/ - { { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/ - { { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/ - { { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/ - { { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/ - { { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/ - { { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/ - { { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/ - { { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/ - { { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/ - { { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/ - { { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/ - { { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/ - { { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/ - { { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/ - { { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/ - { { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/ - { { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/ - { { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/ - { { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/ - { { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/ - { { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/ - { { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/ - { { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/ - { { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/ - { { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/ - { { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/ - { { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/ - { { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/ + { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 080 */ + { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, + { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 084 */ + { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, + { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 088 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08c */ + { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, + { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 090 */ + { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, + { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 094 */ + { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, + { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 098 */ + { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, + { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09c */ + { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, + { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a0 */ + { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, + { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a4 */ + { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, + { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0a8 */ + { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, + { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0ac */ + { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, + { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b0 */ + { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, + { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b4 */ + { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, + { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0b8 */ + { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, + { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bc */ + { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, + { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c0 */ + { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, + { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c4 */ + { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, + { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0c8 */ + { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, + { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cc */ + { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, + { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d0 */ + { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, + { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d4 */ + { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, + { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0d8 */ + { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, + { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0dc */ + { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, + { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e0 */ + { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, + { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e4 */ + { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, + { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0e8 */ + { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, + { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, + { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f0 */ + { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, + { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f4 */ + { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, + { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0f8 */ + { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, + { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0fc */ - { { 0x62,0},{ 0xF0,0x62,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/ - { {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/ - { {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/ - { {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/ - { {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/ - { {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/ - { {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/ - { { 0x79,0},{ 0xf0,0x79,0} }, { { 0x58,0},{ 0xf0,0x58,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/ - { {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/ - { {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ - { {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/ - { {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/ - { {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { { 0x77,0},{ 0xf0,0x77,0} }, { { 0},{ 0} }, { { 0x57,0},{ 0xf0,0x57,0} }, /*134*/ - { { 0x39,0},{ 0xf0,0x39,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/ - { {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/ - { {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/ - { {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { { 0x6E,0},{ 0xf0,0x6E,0} }, /*144*/ - { { 0x63,0},{ 0xf0,0x63,0} }, { { 0x6F,0},{ 0xf0,0x6F,0} }, { { 0},{ 0} }, { { 0x61,0},{ 0xf0,0x61,0} }, /*148*/ - { {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { { 0x6A,0},{ 0xf0,0x6A,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { { 0x65,0},{ 0xf0,0x65,0} }, /*14c*/ - { { 0x60,0},{ 0xf0,0x60,0} }, { { 0x6D,0},{ 0xf0,0x6D,0} }, { { 0x67,0},{ 0xf0,0x67,0} }, { { 0x64,0},{ 0xf0,0x64,0} }, /*150*/ - { { 0xd4,0},{ 0xf0,0xD4,0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/ - { {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { { 0x8B,0},{ 0xf0,0x8B,0} }, /*158*/ - { { 0x8C,0},{ 0xf0,0x8C,0} }, { { 0x8D,0},{ 0xf0,0x8D,0} }, { { 0},{ 0} }, { { 0x7F,0},{ 0xf0,0x7F,0} }, /*15c*/ - { { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { { 0},{ 0} }, /*160*/ - { {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/ - { {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/ - { {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/ - { {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/ - { {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/ - { {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/ - { {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/ + { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 100 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 102 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, + { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 104 */ + { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, + { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 108 */ + { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10c */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, + { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 110 */ + { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, + { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 114 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, + { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 118 */ + { { 0x79, 0 }, { 0xf0, 0x79, 0 } }, { { 0x58, 0 }, { 0xf0, 0x58, 0 } }, + { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11c */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, + { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 120 */ + { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, + { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, + { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12c */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, + { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, { { 0x77, 0 }, { 0xf0, 0x77, 0 } }, + { { 0 }, { 0 } }, { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 134 */ + { { 0x39, 0 }, { 0xf0, 0x39, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 138 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, + { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13c */ + { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, + { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 140 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, { { 0x6E, 0 }, { 0xf0, 0x6E, 0 } }, /* 144 */ + { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, { { 0x6F, 0 }, { 0xf0, 0x6F, 0 } }, + { { 0 }, { 0 } }, { { 0x61, 0 }, { 0xf0, 0x61, 0 } }, /* 148 */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, { { 0x6A, 0 }, { 0xf0, 0x6A, 0 } }, + { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, { { 0x65, 0 }, { 0xf0, 0x65, 0 } }, /* 14c */ + { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, { { 0x6D, 0 }, { 0xf0, 0x6D, 0 } }, + { { 0x67, 0 }, { 0xf0, 0x67, 0 } }, { { 0x64, 0 }, { 0xf0, 0x64, 0 } }, /* 150 */ + { { 0xd4, 0 }, { 0xf0, 0xD4, 0 } }, { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 154 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, + { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, { { 0x8B, 0 }, { 0xf0, 0x8B, 0 } }, /* 158 */ + { { 0x8C, 0 }, { 0xf0, 0x8C, 0 } }, { { 0x8D, 0 }, { 0xf0, 0x8D, 0 } }, + { { 0 }, { 0 } }, { { 0x7F, 0 }, { 0xf0, 0x7F, 0 } }, /* 15c */ + { { 0 }, { 0 } }, { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, + { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, { { 0 }, { 0 } }, /* 160 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, + { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 164 */ + { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, + { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 168 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, + { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, + { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 170 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, + { { 0 }, { 0 } }, { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 174 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, + { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 178 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, + { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17c */ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ - { { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/ - { { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, + { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1fc */ // clang-format on }; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index f65a6dffc..c2404231f 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -90,262 +90,265 @@ typedef struct xtkbd_t { /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ const scancode scancode_xt[512] = { // clang-format off - { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, - { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, - { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, - { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, - { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, - { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, - { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, - { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, - { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, - { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, - { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, - { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, - { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, - { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, - { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, - { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, - { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, - { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, - { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, - { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, - { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, - { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, - { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, - { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, - { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, - { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, - { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, - { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, - { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, - { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, - { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, - { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, - { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, - { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*054*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*058*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*05c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*060*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*064*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*068*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*06c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*070*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*074*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*078*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*07c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*080*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*084*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*088*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*08c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*090*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*094*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*098*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*09c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0fc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*100*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*104*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*108*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*10c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*110*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*114*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*118*/ - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0}, {0} }, { {0}, {0} }, /*11c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*120*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*124*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*128*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*12c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*130*/ - { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, - { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ - { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*138*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*13c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*140*/ - { {0}, {0} }, { {0}, {0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*144*/ - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0}, {0} }, { {0x4b, 0}, {0xcb, 0} }, /*148*/ - { {0}, {0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*14c*/ - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*150*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*154*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*158*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*15c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*160*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*164*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*168*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*16c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*170*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*174*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*148*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*17c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*180*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*184*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*88*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*18c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*190*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*194*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*198*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*19c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14a */ + { { 0 }, { 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14c */ + { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ // clang-format on }; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index dfeb1fa0f..772a3a261 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2350,133 +2350,257 @@ ams_read(uint16_t port, void *priv) static const scancode scancode_pc200[512] = { // clang-format off - { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ - { { 0x04,0},{ 0x84,0} }, { { 0x05,0},{ 0x85,0} }, { { 0x06,0},{ 0x86,0} }, { { 0x07,0},{ 0x87,0} }, /*004*/ - { { 0x08,0},{ 0x88,0} }, { { 0x09,0},{ 0x89,0} }, { { 0x0a,0},{ 0x8a,0} }, { { 0x0b,0},{ 0x8b,0} }, /*008*/ - { { 0x0c,0},{ 0x8c,0} }, { { 0x0d,0},{ 0x8d,0} }, { { 0x0e,0},{ 0x8e,0} }, { { 0x0f,0},{ 0x8f,0} }, /*00c*/ - { { 0x10,0},{ 0x90,0} }, { { 0x11,0},{ 0x91,0} }, { { 0x12,0},{ 0x92,0} }, { { 0x13,0},{ 0x93,0} }, /*010*/ - { { 0x14,0},{ 0x94,0} }, { { 0x15,0},{ 0x95,0} }, { { 0x16,0},{ 0x96,0} }, { { 0x17,0},{ 0x97,0} }, /*014*/ - { { 0x18,0},{ 0x98,0} }, { { 0x19,0},{ 0x99,0} }, { { 0x1a,0},{ 0x9a,0} }, { { 0x1b,0},{ 0x9b,0} }, /*018*/ - { { 0x1c,0},{ 0x9c,0} }, { { 0x1d,0},{ 0x9d,0} }, { { 0x1e,0},{ 0x9e,0} }, { { 0x1f,0},{ 0x9f,0} }, /*01c*/ - { { 0x20,0},{ 0xa0,0} }, { { 0x21,0},{ 0xa1,0} }, { { 0x22,0},{ 0xa2,0} }, { { 0x23,0},{ 0xa3,0} }, /*020*/ - { { 0x24,0},{ 0xa4,0} }, { { 0x25,0},{ 0xa5,0} }, { { 0x26,0},{ 0xa6,0} }, { { 0x27,0},{ 0xa7,0} }, /*024*/ - { { 0x28,0},{ 0xa8,0} }, { { 0x29,0},{ 0xa9,0} }, { { 0x2a,0},{ 0xaa,0} }, { { 0x2b,0},{ 0xab,0} }, /*028*/ - { { 0x2c,0},{ 0xac,0} }, { { 0x2d,0},{ 0xad,0} }, { { 0x2e,0},{ 0xae,0} }, { { 0x2f,0},{ 0xaf,0} }, /*02c*/ - { { 0x30,0},{ 0xb0,0} }, { { 0x31,0},{ 0xb1,0} }, { { 0x32,0},{ 0xb2,0} }, { { 0x33,0},{ 0xb3,0} }, /*030*/ - { { 0x34,0},{ 0xb4,0} }, { { 0x35,0},{ 0xb5,0} }, { { 0x36,0},{ 0xb6,0} }, { { 0x37,0},{ 0xb7,0} }, /*034*/ - { { 0x38,0},{ 0xb8,0} }, { { 0x39,0},{ 0xb9,0} }, { { 0x3a,0},{ 0xba,0} }, { { 0x3b,0},{ 0xbb,0} }, /*038*/ - { { 0x3c,0},{ 0xbc,0} }, { { 0x3d,0},{ 0xbd,0} }, { { 0x3e,0},{ 0xbe,0} }, { { 0x3f,0},{ 0xbf,0} }, /*03c*/ - { { 0x40,0},{ 0xc0,0} }, { { 0x41,0},{ 0xc1,0} }, { { 0x42,0},{ 0xc2,0} }, { { 0x43,0},{ 0xc3,0} }, /*040*/ - { { 0x44,0},{ 0xc4,0} }, { { 0x45,0},{ 0xc5,0} }, { { 0x46,0},{ 0xc6,0} }, { { 0x47,0},{ 0xc7,0} }, /*044*/ - { { 0x48,0},{ 0xc8,0} }, { { 0x49,0},{ 0xc9,0} }, { { 0x4a,0},{ 0xca,0} }, { { 0x4b,0},{ 0xcb,0} }, /*048*/ - { { 0x4c,0},{ 0xcc,0} }, { { 0x4d,0},{ 0xcd,0} }, { { 0x4e,0},{ 0xce,0} }, { { 0x4f,0},{ 0xcf,0} }, /*04c*/ - { { 0x50,0},{ 0xd0,0} }, { { 0x51,0},{ 0xd1,0} }, { { 0x52,0},{ 0xd2,0} }, { { 0x53,0},{ 0xd3,0} }, /*050*/ - { { 0x54,0},{ 0xd4,0} }, { { 0x55,0},{ 0xd5,0} }, { { 0x56,0},{ 0xd6,0} }, { { 0x57,0},{ 0xd7,0} }, /*054*/ - { { 0x58,0},{ 0xd8,0} }, { { 0x59,0},{ 0xd9,0} }, { { 0x5a,0},{ 0xda,0} }, { { 0x5b,0},{ 0xdb,0} }, /*058*/ - { { 0x5c,0},{ 0xdc,0} }, { { 0x5d,0},{ 0xdd,0} }, { { 0x5e,0},{ 0xde,0} }, { { 0x5f,0},{ 0xdf,0} }, /*05c*/ - { { 0x60,0},{ 0xe0,0} }, { { 0x61,0},{ 0xe1,0} }, { { 0x62,0},{ 0xe2,0} }, { { 0x63,0},{ 0xe3,0} }, /*060*/ - { { 0x64,0},{ 0xe4,0} }, { { 0x65,0},{ 0xe5,0} }, { { 0x66,0},{ 0xe6,0} }, { { 0x67,0},{ 0xe7,0} }, /*064*/ - { { 0x68,0},{ 0xe8,0} }, { { 0x69,0},{ 0xe9,0} }, { { 0x6a,0},{ 0xea,0} }, { { 0x6b,0},{ 0xeb,0} }, /*068*/ - { { 0x6c,0},{ 0xec,0} }, { { 0x6d,0},{ 0xed,0} }, { { 0x6e,0},{ 0xee,0} }, { { 0x6f,0},{ 0xef,0} }, /*06c*/ - { { 0x70,0},{ 0xf0,0} }, { { 0x71,0},{ 0xf1,0} }, { { 0x72,0},{ 0xf2,0} }, { { 0x73,0},{ 0xf3,0} }, /*070*/ - { { 0x74,0},{ 0xf4,0} }, { { 0x75,0},{ 0xf5,0} }, { { 0x76,0},{ 0xf6,0} }, { { 0x77,0},{ 0xf7,0} }, /*074*/ - { { 0x78,0},{ 0xf8,0} }, { { 0x79,0},{ 0xf9,0} }, { { 0x7a,0},{ 0xfa,0} }, { { 0x7b,0},{ 0xfb,0} }, /*078*/ - { { 0x7c,0},{ 0xfc,0} }, { { 0x7d,0},{ 0xfd,0} }, { { 0x7e,0},{ 0xfe,0} }, { { 0x7f,0},{ 0xff,0} }, /*07c*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ + { { 0x54, 0 }, { 0xd4, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 054 */ + { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x57, 0 }, { 0xd7, 0 } }, /* 056 */ + { { 0x58, 0 }, { 0xd8, 0 } }, { { 0x59, 0 }, { 0xd9, 0 } }, /* 058 */ + { { 0x5a, 0 }, { 0xda, 0 } }, { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05a */ + { { 0x5c, 0 }, { 0xdc, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05c */ + { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05e */ + { { 0x60, 0 }, { 0xe0, 0 } }, { { 0x61, 0 }, { 0xe1, 0 } }, /* 060 */ + { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 062 */ + { { 0x64, 0 }, { 0xe4, 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 064 */ + { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x67, 0 }, { 0xe7, 0 } }, /* 066 */ + { { 0x68, 0 }, { 0xe8, 0 } }, { { 0x69, 0 }, { 0xe9, 0 } }, /* 068 */ + { { 0x6a, 0 }, { 0xea, 0 } }, { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06a */ + { { 0x6c, 0 }, { 0xec, 0 } }, { { 0x6d, 0 }, { 0xed, 0 } }, /* 06c */ + { { 0x6e, 0 }, { 0xee, 0 } }, { { 0x6f, 0 }, { 0xef, 0 } }, /* 06e */ + { { 0x70, 0 }, { 0xf0, 0 } }, { { 0x71, 0 }, { 0xf1, 0 } }, /* 070 */ + { { 0x72, 0 }, { 0xf2, 0 } }, { { 0x73, 0 }, { 0xf3, 0 } }, /* 072 */ + { { 0x74, 0 }, { 0xf4, 0 } }, { { 0x75, 0 }, { 0xf5, 0 } }, /* 074 */ + { { 0x76, 0 }, { 0xf6, 0 } }, { { 0x77, 0 }, { 0xf7, 0 } }, /* 076 */ + { { 0x78, 0 }, { 0xf8, 0 } }, { { 0x79, 0 }, { 0xf9, 0 } }, /* 078 */ + { { 0x7a, 0 }, { 0xfa, 0 } }, { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07a */ + { { 0x7c, 0 }, { 0xfc, 0 } }, { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07c */ + { { 0x7e, 0 }, { 0xfe, 0 } }, { { 0x7f, 0 }, { 0xff, 0 } }, /* 07e */ - { { 0x80,0},{ 0} }, { { 0x81,0},{ 0} }, { { 0x82,0},{ 0} }, { { 0},{ 0} }, /*080*/ - { { 0},{ 0} }, { { 0x85,0},{ 0} }, { { 0x86,0},{ 0} }, { { 0x87,0},{ 0} }, /*084*/ - { { 0x88,0},{ 0} }, { { 0x89,0},{ 0} }, { { 0x8a,0},{ 0} }, { { 0x8b,0},{ 0} }, /*088*/ - { { 0x8c,0},{ 0} }, { { 0x8d,0},{ 0} }, { { 0x8e,0},{ 0} }, { { 0x8f,0},{ 0} }, /*08c*/ - { { 0x90,0},{ 0} }, { { 0x91,0},{ 0} }, { { 0x92,0},{ 0} }, { { 0x93,0},{ 0} }, /*090*/ - { { 0x94,0},{ 0} }, { { 0x95,0},{ 0} }, { { 0x96,0},{ 0} }, { { 0x97,0},{ 0} }, /*094*/ - { { 0x98,0},{ 0} }, { { 0x99,0},{ 0} }, { { 0x9a,0},{ 0} }, { { 0x9b,0},{ 0} }, /*098*/ - { { 0x9c,0},{ 0} }, { { 0x9d,0},{ 0} }, { { 0x9e,0},{ 0} }, { { 0x9f,0},{ 0} }, /*09c*/ - { { 0xa0,0},{ 0} }, { { 0xa1,0},{ 0} }, { { 0xa2,0},{ 0} }, { { 0xa3,0},{ 0} }, /*0a0*/ - { { 0xa4,0},{ 0} }, { { 0xa5,0},{ 0} }, { { 0xa6,0},{ 0} }, { { 0xa7,0},{ 0} }, /*0a4*/ - { { 0xa8,0},{ 0} }, { { 0xa9,0},{ 0} }, { { 0xaa,0},{ 0} }, { { 0xab,0},{ 0} }, /*0a8*/ - { { 0xac,0},{ 0} }, { { 0xad,0},{ 0} }, { { 0xae,0},{ 0} }, { { 0xaf,0},{ 0} }, /*0ac*/ - { { 0xb0,0},{ 0} }, { { 0xb1,0},{ 0} }, { { 0xb2,0},{ 0} }, { { 0xb3,0},{ 0} }, /*0b0*/ - { { 0xb4,0},{ 0} }, { { 0xb5,0},{ 0} }, { { 0xb6,0},{ 0} }, { { 0xb7,0},{ 0} }, /*0b4*/ - { { 0xb8,0},{ 0} }, { { 0xb9,0},{ 0} }, { { 0xba,0},{ 0} }, { { 0xbb,0},{ 0} }, /*0b8*/ - { { 0xbc,0},{ 0} }, { { 0xbd,0},{ 0} }, { { 0xbe,0},{ 0} }, { { 0xbf,0},{ 0} }, /*0bc*/ - { { 0xc0,0},{ 0} }, { { 0xc1,0},{ 0} }, { { 0xc2,0},{ 0} }, { { 0xc3,0},{ 0} }, /*0c0*/ - { { 0xc4,0},{ 0} }, { { 0xc5,0},{ 0} }, { { 0xc6,0},{ 0} }, { { 0xc7,0},{ 0} }, /*0c4*/ - { { 0xc8,0},{ 0} }, { { 0xc9,0},{ 0} }, { { 0xca,0},{ 0} }, { { 0xcb,0},{ 0} }, /*0c8*/ - { { 0xcc,0},{ 0} }, { { 0xcd,0},{ 0} }, { { 0xce,0},{ 0} }, { { 0xcf,0},{ 0} }, /*0cc*/ - { { 0xd0,0},{ 0} }, { { 0xd1,0},{ 0} }, { { 0xd2,0},{ 0} }, { { 0xd3,0},{ 0} }, /*0d0*/ - { { 0xd4,0},{ 0} }, { { 0xd5,0},{ 0} }, { { 0xd6,0},{ 0} }, { { 0xd7,0},{ 0} }, /*0d4*/ - { { 0xd8,0},{ 0} }, { { 0xd9,0},{ 0} }, { { 0xda,0},{ 0} }, { { 0xdb,0},{ 0} }, /*0d8*/ - { { 0xdc,0},{ 0} }, { { 0xdd,0},{ 0} }, { { 0xde,0},{ 0} }, { { 0xdf,0},{ 0} }, /*0dc*/ - { { 0xe0,0},{ 0} }, { { 0xe1,0},{ 0} }, { { 0xe2,0},{ 0} }, { { 0xe3,0},{ 0} }, /*0e0*/ - { { 0xe4,0},{ 0} }, { { 0xe5,0},{ 0} }, { { 0xe6,0},{ 0} }, { { 0xe7,0},{ 0} }, /*0e4*/ - { { 0xe8,0},{ 0} }, { { 0xe9,0},{ 0} }, { { 0xea,0},{ 0} }, { { 0xeb,0},{ 0} }, /*0e8*/ - { { 0xec,0},{ 0} }, { { 0xed,0},{ 0} }, { { 0xee,0},{ 0} }, { { 0xef,0},{ 0} }, /*0ec*/ - { { 0},{ 0} }, { { 0xf1,0},{ 0} }, { { 0xf2,0},{ 0} }, { { 0xf3,0},{ 0} }, /*0f0*/ - { { 0xf4,0},{ 0} }, { { 0xf5,0},{ 0} }, { { 0xf6,0},{ 0} }, { { 0xf7,0},{ 0} }, /*0f4*/ - { { 0xf8,0},{ 0} }, { { 0xf9,0},{ 0} }, { { 0xfa,0},{ 0} }, { { 0xfb,0},{ 0} }, /*0f8*/ - { { 0xfc,0},{ 0} }, { { 0xfd,0},{ 0} }, { { 0xfe,0},{ 0} }, { { 0xff,0},{ 0} }, /*0fc*/ + { { 0x80, 0 }, { 0 } }, { { 0x81, 0 }, { 0 } }, /* 080 */ + { { 0x82, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0x85, 0 }, { 0 } }, /* 084 */ + { { 0x86, 0 }, { 0 } }, { { 0x87, 0 }, { 0 } }, /* 086 */ + { { 0x88, 0 }, { 0 } }, { { 0x89, 0 }, { 0 } }, /* 088 */ + { { 0x8a, 0 }, { 0 } }, { { 0x8b, 0 }, { 0 } }, /* 08a */ + { { 0x8c, 0 }, { 0 } }, { { 0x8d, 0 }, { 0 } }, /* 08c */ + { { 0x8e, 0 }, { 0 } }, { { 0x8f, 0 }, { 0 } }, /* 08e */ + { { 0x90, 0 }, { 0 } }, { { 0x91, 0 }, { 0 } }, /* 090 */ + { { 0x92, 0 }, { 0 } }, { { 0x93, 0 }, { 0 } }, /* 092 */ + { { 0x94, 0 }, { 0 } }, { { 0x95, 0 }, { 0 } }, /* 094 */ + { { 0x96, 0 }, { 0 } }, { { 0x97, 0 }, { 0 } }, /* 096 */ + { { 0x98, 0 }, { 0 } }, { { 0x99, 0 }, { 0 } }, /* 098 */ + { { 0x9a, 0 }, { 0 } }, { { 0x9b, 0 }, { 0 } }, /* 09a */ + { { 0x9c, 0 }, { 0 } }, { { 0x9d, 0 }, { 0 } }, /* 09c */ + { { 0x9e, 0 }, { 0 } }, { { 0x9f, 0 }, { 0 } }, /* 09e */ + { { 0xa0, 0 }, { 0 } }, { { 0xa1, 0 }, { 0 } }, /* 0a0 */ + { { 0xa2, 0 }, { 0 } }, { { 0xa3, 0 }, { 0 } }, /* 0a2 */ + { { 0xa4, 0 }, { 0 } }, { { 0xa5, 0 }, { 0 } }, /* 0a4 */ + { { 0xa6, 0 }, { 0 } }, { { 0xa7, 0 }, { 0 } }, /* 0a6 */ + { { 0xa8, 0 }, { 0 } }, { { 0xa9, 0 }, { 0 } }, /* 0a8 */ + { { 0xaa, 0 }, { 0 } }, { { 0xab, 0 }, { 0 } }, /* 0aa */ + { { 0xac, 0 }, { 0 } }, { { 0xad, 0 }, { 0 } }, /* 0ac */ + { { 0xae, 0 }, { 0 } }, { { 0xaf, 0 }, { 0 } }, /* 0ae */ + { { 0xb0, 0 }, { 0 } }, { { 0xb1, 0 }, { 0 } }, /* 0b0 */ + { { 0xb2, 0 }, { 0 } }, { { 0xb3, 0 }, { 0 } }, /* 0b2 */ + { { 0xb4, 0 }, { 0 } }, { { 0xb5, 0 }, { 0 } }, /* 0b4 */ + { { 0xb6, 0 }, { 0 } }, { { 0xb7, 0 }, { 0 } }, /* 0b6 */ + { { 0xb8, 0 }, { 0 } }, { { 0xb9, 0 }, { 0 } }, /* 0b8 */ + { { 0xba, 0 }, { 0 } }, { { 0xbb, 0 }, { 0 } }, /* 0ba */ + { { 0xbc, 0 }, { 0 } }, { { 0xbd, 0 }, { 0 } }, /* 0bc */ + { { 0xbe, 0 }, { 0 } }, { { 0xbf, 0 }, { 0 } }, /* 0be */ + { { 0xc0, 0 }, { 0 } }, { { 0xc1, 0 }, { 0 } }, /* 0c0 */ + { { 0xc2, 0 }, { 0 } }, { { 0xc3, 0 }, { 0 } }, /* 0c2 */ + { { 0xc4, 0 }, { 0 } }, { { 0xc5, 0 }, { 0 } }, /* 0c4 */ + { { 0xc6, 0 }, { 0 } }, { { 0xc7, 0 }, { 0 } }, /* 0c6 */ + { { 0xc8, 0 }, { 0 } }, { { 0xc9, 0 }, { 0 } }, /* 0c8 */ + { { 0xca, 0 }, { 0 } }, { { 0xcb, 0 }, { 0 } }, /* 0ca */ + { { 0xcc, 0 }, { 0 } }, { { 0xcd, 0 }, { 0 } }, /* 0cc */ + { { 0xce, 0 }, { 0 } }, { { 0xcf, 0 }, { 0 } }, /* 0ce */ + { { 0xd0, 0 }, { 0 } }, { { 0xd1, 0 }, { 0 } }, /* 0d0 */ + { { 0xd2, 0 }, { 0 } }, { { 0xd3, 0 }, { 0 } }, /* 0d2 */ + { { 0xd4, 0 }, { 0 } }, { { 0xd5, 0 }, { 0 } }, /* 0d4 */ + { { 0xd6, 0 }, { 0 } }, { { 0xd7, 0 }, { 0 } }, /* 0d6 */ + { { 0xd8, 0 }, { 0 } }, { { 0xd9, 0 }, { 0 } }, /* 0d8 */ + { { 0xda, 0 }, { 0 } }, { { 0xdb, 0 }, { 0 } }, /* 0da */ + { { 0xdc, 0 }, { 0 } }, { { 0xdd, 0 }, { 0 } }, /* 0dc */ + { { 0xde, 0 }, { 0 } }, { { 0xdf, 0 }, { 0 } }, /* 0de */ + { { 0xe0, 0 }, { 0 } }, { { 0xe1, 0 }, { 0 } }, /* 0e0 */ + { { 0xe2, 0 }, { 0 } }, { { 0xe3, 0 }, { 0 } }, /* 0e2 */ + { { 0xe4, 0 }, { 0 } }, { { 0xe5, 0 }, { 0 } }, /* 0e4 */ + { { 0xe6, 0 }, { 0 } }, { { 0xe7, 0 }, { 0 } }, /* 0e6 */ + { { 0xe8, 0 }, { 0 } }, { { 0xe9, 0 }, { 0 } }, /* 0e8 */ + { { 0xea, 0 }, { 0 } }, { { 0xeb, 0 }, { 0 } }, /* 0ea */ + { { 0xec, 0 }, { 0 } }, { { 0xed, 0 }, { 0 } }, /* 0ec */ + { { 0xee, 0 }, { 0 } }, { { 0xef, 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0 } }, /* 0f0 */ + { { 0xf2, 0 }, { 0 } }, { { 0xf3, 0 }, { 0 } }, /* 0f2 */ + { { 0xf4, 0 }, { 0 } }, { { 0xf5, 0 }, { 0 } }, /* 0f4 */ + { { 0xf6, 0 }, { 0 } }, { { 0xf7, 0 }, { 0 } }, /* 0f6 */ + { { 0xf8, 0 }, { 0 } }, { { 0xf9, 0 }, { 0 } }, /* 0f8 */ + { { 0xfa, 0 }, { 0 } }, { { 0xfb, 0 }, { 0 } }, /* 0fa */ + { { 0xfc, 0 }, { 0 } }, { { 0xfd, 0 }, { 0 } }, /* 0fc */ + { { 0xfe, 0 }, { 0 } }, { { 0xff, 0 }, { 0 } }, /* 0fe */ - { {0xe1,0x1d,0},{0xe1, 0x9d,0} }, { {0xe0,0x01,0},{0xe0, 0x81,0} }, { {0xe0,0x02,0},{0xe0, 0x82,0} }, { {0xe0,0x03,0},{0xe0, 0x83,0} }, /*100*/ - { {0xe0,0x04,0},{0xe0, 0x84,0} }, { {0xe0,0x05,0},{0xe0, 0x85,0} }, { {0xe0,0x06,0},{0xe0, 0x86,0} }, { {0xe0,0x07,0},{0xe0, 0x87,0} }, /*104*/ - { {0xe0,0x08,0},{0xe0, 0x88,0} }, { {0xe0,0x09,0},{0xe0, 0x89,0} }, { {0xe0,0x0a,0},{0xe0, 0x8a,0} }, { {0xe0,0x0b,0},{0xe0, 0x8b,0} }, /*108*/ - { {0xe0,0x0c,0},{0xe0, 0x8c,0} }, { { 0},{ 0} }, { {0xe0,0x0e,0},{0xe0, 0x8e,0} }, { {0xe0,0x0f,0},{0xe0, 0x8f,0} }, /*10c*/ - { {0xe0,0x10,0},{0xe0, 0x90,0} }, { {0xe0,0x11,0},{0xe0, 0x91,0} }, { {0xe0,0x12,0},{0xe0, 0x92,0} }, { {0xe0,0x13,0},{0xe0, 0x93,0} }, /*110*/ - { {0xe0,0x14,0},{0xe0, 0x94,0} }, { {0xe0,0x15,0},{0xe0, 0x95,0} }, { {0xe0,0x16,0},{0xe0, 0x96,0} }, { {0xe0,0x17,0},{0xe0, 0x97,0} }, /*114*/ - { {0xe0,0x18,0},{0xe0, 0x98,0} }, { {0xe0,0x19,0},{0xe0, 0x99,0} }, { {0xe0,0x1a,0},{0xe0, 0x9a,0} }, { {0xe0,0x1b,0},{0xe0, 0x9b,0} }, /*118*/ - { {0xe0,0x1c,0},{0xe0, 0x9c,0} }, { {0xe0,0x1d,0},{0xe0, 0x9d,0} }, { {0xe0,0x1e,0},{0xe0, 0x9e,0} }, { {0xe0,0x1f,0},{0xe0, 0x9f,0} }, /*11c*/ - { {0xe0,0x20,0},{0xe0, 0xa0,0} }, { {0xe0,0x21,0},{0xe0, 0xa1,0} }, { {0xe0,0x22,0},{0xe0, 0xa2,0} }, { {0xe0,0x23,0},{0xe0, 0xa3,0} }, /*120*/ - { {0xe0,0x24,0},{0xe0, 0xa4,0} }, { {0xe0,0x25,0},{0xe0, 0xa5,0} }, { {0xe0,0x26,0},{0xe0, 0xa6,0} }, { { 0},{ 0} }, /*124*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ - { {0xe0,0x2c,0},{0xe0, 0xac,0} }, { {0xe0,0x2d,0},{0xe0, 0xad,0} }, { {0xe0,0x2e,0},{0xe0, 0xae,0} }, { {0xe0,0x2f,0},{0xe0, 0xaf,0} }, /*12c*/ - { {0xe0,0x30,0},{0xe0, 0xb0,0} }, { {0xe0,0x31,0},{0xe0, 0xb1,0} }, { {0xe0,0x32,0},{0xe0, 0xb2,0} }, { { 0},{ 0} }, /*130*/ - { {0xe0,0x34,0},{0xe0, 0xb4,0} }, { {0xe0,0x35,0},{0xe0, 0xb5,0} }, { { 0},{ 0} }, { {0xe0,0x37,0},{0xe0, 0xb7,0} }, /*134*/ - { {0xe0,0x38,0},{0xe0, 0xb8,0} }, { { 0},{ 0} }, { {0xe0,0x3a,0},{0xe0, 0xba,0} }, { {0xe0,0x3b,0},{0xe0, 0xbb,0} }, /*138*/ - { {0xe0,0x3c,0},{0xe0, 0xbc,0} }, { {0xe0,0x3d,0},{0xe0, 0xbd,0} }, { {0xe0,0x3e,0},{0xe0, 0xbe,0} }, { {0xe0,0x3f,0},{0xe0, 0xbf,0} }, /*13c*/ - { {0xe0,0x40,0},{0xe0, 0xc0,0} }, { {0xe0,0x41,0},{0xe0, 0xc1,0} }, { {0xe0,0x42,0},{0xe0, 0xc2,0} }, { {0xe0,0x43,0},{0xe0, 0xc3,0} }, /*140*/ - { {0xe0,0x44,0},{0xe0, 0xc4,0} }, { { 0},{ 0} }, { {0xe0,0x46,0},{0xe0, 0xc6,0} }, { {0xe0,0x47,0},{0xe0, 0xc7,0} }, /*144*/ - { {0xe0,0x48,0},{0xe0, 0xc8,0} }, { {0xe0,0x49,0},{0xe0, 0xc9,0} }, { { 0},{ 0} }, { {0xe0,0x4b,0},{0xe0, 0xcb,0} }, /*148*/ - { {0xe0,0x4c,0},{0xe0, 0xcc,0} }, { {0xe0,0x4d,0},{0xe0, 0xcd,0} }, { {0xe0,0x4e,0},{0xe0, 0xce,0} }, { {0xe0,0x4f,0},{0xe0, 0xcf,0} }, /*14c*/ - { {0xe0,0x50,0},{0xe0, 0xd0,0} }, { {0xe0,0x51,0},{0xe0, 0xd1,0} }, { {0xe0,0x52,0},{0xe0, 0xd2,0} }, { {0xe0,0x53,0},{0xe0, 0xd3,0} }, /*150*/ - { { 0},{ 0} }, { {0xe0,0x55,0},{0xe0, 0xd5,0} }, { { 0},{ 0} }, { {0xe0,0x57,0},{0xe0, 0xd7,0} }, /*154*/ - { {0xe0,0x58,0},{0xe0, 0xd8,0} }, { {0xe0,0x59,0},{0xe0, 0xd9,0} }, { {0xe0,0x5a,0},{0xe0, 0xaa,0} }, { {0xe0,0x5b,0},{0xe0, 0xdb,0} }, /*158*/ - { {0xe0,0x5c,0},{0xe0, 0xdc,0} }, { {0xe0,0x5d,0},{0xe0, 0xdd,0} }, { {0xe0,0x5e,0},{0xe0, 0xee,0} }, { {0xe0,0x5f,0},{0xe0, 0xdf,0} }, /*15c*/ - { { 0},{ 0} }, { {0xe0,0x61,0},{0xe0, 0xe1,0} }, { {0xe0,0x62,0},{0xe0, 0xe2,0} }, { {0xe0,0x63,0},{0xe0, 0xe3,0} }, /*160*/ - { {0xe0,0x64,0},{0xe0, 0xe4,0} }, { {0xe0,0x65,0},{0xe0, 0xe5,0} }, { {0xe0,0x66,0},{0xe0, 0xe6,0} }, { {0xe0,0x67,0},{0xe0, 0xe7,0} }, /*164*/ - { {0xe0,0x68,0},{0xe0, 0xe8,0} }, { {0xe0,0x69,0},{0xe0, 0xe9,0} }, { {0xe0,0x6a,0},{0xe0, 0xea,0} }, { {0xe0,0x6b,0},{0xe0, 0xeb,0} }, /*168*/ - { {0xe0,0x6c,0},{0xe0, 0xec,0} }, { {0xe0,0x6d,0},{0xe0, 0xed,0} }, { {0xe0,0x6e,0},{0xe0, 0xee,0} }, { { 0},{ 0} }, /*16c*/ - { {0xe0,0x70,0},{0xe0, 0xf0,0} }, { {0xe0,0x71,0},{0xe0, 0xf1,0} }, { {0xe0,0x72,0},{0xe0, 0xf2,0} }, { {0xe0,0x73,0},{0xe0, 0xf3,0} }, /*170*/ - { {0xe0,0x74,0},{0xe0, 0xf4,0} }, { {0xe0,0x75,0},{0xe0, 0xf5,0} }, { { 0},{ 0} }, { {0xe0,0x77,0},{0xe0, 0xf7,0} }, /*174*/ - { {0xe0,0x78,0},{0xe0, 0xf8,0} }, { {0xe0,0x79,0},{0xe0, 0xf9,0} }, { {0xe0,0x7a,0},{0xe0, 0xfa,0} }, { {0xe0,0x7b,0},{0xe0, 0xfb,0} }, /*178*/ - { {0xe0,0x7c,0},{0xe0, 0xfc,0} }, { {0xe0,0x7d,0},{0xe0, 0xfd,0} }, { {0xe0,0x7e,0},{0xe0, 0xfe,0} }, { {0xe0,0x7f,0},{0xe0, 0xff,0} }, /*17c*/ - - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ - { { 0},{ 0} }, { {0xe0,0xe1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{ 0} }, { { 0},{ 0} }, /*1ec*/ - { { 0},{ 0} }, { {0xe0,0xf1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ - { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ - { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{ 0} }, { {0xe0,0xff,0},{ 0} } /*1fc*/ + { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 100 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 102 */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 104 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 106 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 108 */ + { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10a */ + { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10e */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 110 */ + { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 112 */ + { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 114 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 116 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 118 */ + { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11a */ + { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11c */ + { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11e */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 120 */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 122 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 124 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12c */ + { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12e */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 130 */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 136 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ + { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13a */ + { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13c */ + { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13e */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 140 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 142 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 146 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14a */ + { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14c */ + { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14e */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 150 */ + { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 156 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 158 */ + { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15a */ + { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15c */ + { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 160 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 162 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 164 */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 166 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 168 */ + { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16a */ + { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16c */ + { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 170 */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 172 */ + { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 176 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 178 */ + { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17a */ + { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17c */ + { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0xe0, 0xee, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0xe0, 0xfe, 0 }, { 0 } }, { { 0xe0, 0xff, 0 }, { 0 } } /* 1fe */ // clang-format on }; diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 1d4c3303f..39cb43d70 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -138,262 +138,265 @@ static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No addit static const scancode scancode_tandy[512] = { // clang-format off - { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, - { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, - { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, - { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, - { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, - { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, - { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, - { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, - { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, - { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, - { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, - { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, - { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, - { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, - { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, - { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, - { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, - { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, - { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, - { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, - { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, - { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, - { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, - { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, - { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, - { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, - { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, - { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, - { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, - { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, - { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, - { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, - { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, - { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x56, 0}, {0xd6, 0} }, - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*054*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*058*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*05c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*060*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*064*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*068*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*06c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*070*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*074*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*078*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*07c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*080*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*084*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*088*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*08c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*090*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*094*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*098*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*09c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0fc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*100*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*104*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*108*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*10c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*110*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*114*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*118*/ - { {0x57, 0}, {0xd7, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*11c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*120*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*124*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*128*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*12c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*130*/ - { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, - { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ - { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*138*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*13c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*140*/ - { {0}, {0} }, { {0}, {0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*144*/ - { {0x29, 0}, {0xa9, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0}, {0} }, { {0x2b, 0}, {0xab, 0} }, /*148*/ - { {0}, {0} }, { {0x4e, 0}, {0xce, 0} }, - { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*14c*/ - { {0x4a, 0}, {0xca, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*150*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*154*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*158*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*15c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*160*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*164*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*168*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*16c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*170*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*174*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*148*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*17c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*180*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*184*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*188*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*18c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*190*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*194*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*198*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*19c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x56, 0 }, { 0xd6, 0 } }, /* 052 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ + { { 0x57, 0 }, { 0xd7, 0 } }, { { 0 }, { 0 } }, /* 11c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ + { { 0x29, 0 }, { 0xa9, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 14a */ + { { 0 }, { 0 } }, { { 0x4e, 0 }, { 0xce, 0 } }, /* 14c */ + { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ // clang-format on }; static uint8_t crtcmask[32] = { diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 7806d378b..6cc359892 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -846,262 +846,265 @@ ms_poll(void *priv) */ const scancode scancode_olivetti_m24_deluxe[512] = { // clang-format off - { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, - { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, - { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, - { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, - { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, - { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, - { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, - { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, - { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, - { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, - { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, - { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, - { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, - { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, - { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, - { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, - { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, - { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, - { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, - { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, - { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, - { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, - { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, - { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, - { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, - { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, - { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, - { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, - { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, - { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, - { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, - { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, - { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, - { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, - { {0}, {0} }, { {0}, {0} }, - { {0x5e, 0}, {0xde, 0} }, { {0x60, 0}, {0xe0, 0} }, /*054*/ - { {0x61, 0}, {0xe1, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*058*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*05c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*060*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*064*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*068*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*06c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*070*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*074*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*078*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*07c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*080*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*084*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*088*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*08c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*090*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*094*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*098*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*09c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0fc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*100*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*104*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*108*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*10c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*110*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*114*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*118*/ - { {0x57, 0}, {0xd7, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*11c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*120*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*124*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*128*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*12c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*130*/ - { {0}, {0} }, { {0x5f, 0}, {0xdf, 0} }, - { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ - { {0x66, 0}, {0xe6, 0} }, { {0x55, 0}, {0xd5, 0} }, - { {0}, {0} }, { {0}, {0} }, /*138*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*13c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*140*/ - { {0}, {0} }, { {0}, {0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x63, 0}, {0xe3, 0} }, /*144*/ - { {0x5b, 0}, {0xdb, 0} }, { {0x5c, 0}, {0xdc, 0} }, - { {0}, {0} }, { {0x58, 0}, {0xd8, 0} }, /*148*/ - { {0}, {0} }, { {0x5a, 0}, {0xda, 0} }, - { {0}, {0} }, { {0x65, 0}, {0xe5, 0} }, /*14c*/ - { {0x59, 0}, {0xd9, 0} }, { {0x5d, 0}, {0xdd, 0} }, - { {0x62, 0}, {0xe2, 0} }, { {0x64, 0}, {0xe4, 0} }, /*150*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*154*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0x54, 0}, {0xd4, 0} }, /*158*/ - { {0x67, 0}, {0xe7, 0} }, { {0x56, 0}, {0xd6, 0} }, - { {0}, {0} }, { {0}, {0} }, /*15c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*160*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*164*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*168*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*16c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*170*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*174*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*148*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*17c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*180*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*184*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*188*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*18c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*190*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*194*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*198*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*19c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ + { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x60, 0 }, { 0xe0, 0 } }, /* 056 */ + { { 0x61, 0 }, { 0xe1, 0 } }, { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ + { { 0x57, 0 }, { 0xd7, 0 } }, { { 0 }, { 0 } }, /* 11c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ + { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 138 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 146 */ + { { 0x5b, 0 }, { 0xdb, 0 } }, { { 0x5c, 0 }, { 0xdc, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0x58, 0 }, { 0xd8, 0 } }, /* 14a */ + { { 0 }, { 0 } }, { { 0x5a, 0 }, { 0xda, 0 } }, /* 14c */ + { { 0 }, { 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 14e */ + { { 0x59, 0 }, { 0xd9, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 150 */ + { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x64, 0 }, { 0xe4, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, { { 0x54, 0 }, { 0xd4, 0 } }, /* 15a */ + { { 0x67, 0 }, { 0xe7, 0 } }, { { 0x56, 0 }, { 0xd6, 0 } }, /* 15c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ // clang-format on }; @@ -1113,262 +1116,265 @@ const scancode scancode_olivetti_m24_deluxe[512] = { */ const scancode scancode_olivetti_m240[512] = { // clang-format off - { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, - { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, - { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, - { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, - { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, - { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, - { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, - { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, - { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, - { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, - { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, - { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, - { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, - { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, - { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, - { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, - { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, - { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, - { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, - { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, - { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, - { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, - { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, - { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, - { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, - { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, - { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, - { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, - { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, - { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, - { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, - { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, - { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, - { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*054*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*058*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*05c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*060*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*064*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*068*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*06c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*070*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*074*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*078*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*07c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*080*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*084*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*088*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*08c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*090*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*094*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*098*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*09c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*0fc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*100*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*104*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*108*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*10c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*110*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*114*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*118*/ - { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, - { {0}, {0} }, { {0}, {0} }, /*11c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*120*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*124*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*128*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*12c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*130*/ - { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, - { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ - { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*138*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*13c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*140*/ - { {0}, {0} }, { {0}, {0} }, - { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*144*/ - { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, - { {0}, {0} }, { {0x4b, 0}, {0xcb, 0} }, /*148*/ - { {0}, {0} }, { {0x4d, 0}, {0xcd, 0} }, - { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*14c*/ - { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, - { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*150*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*154*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*158*/ - { {0}, {0} }, { {0x54, 0}, {0xd4, 0} }, - { {0x56, 0}, {0xd6, 0} }, { {0x5c, 0}, {0xdc, 0} }, /*15c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*160*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*164*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*168*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*16c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*170*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*174*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*148*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*17c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*180*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*184*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*188*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*18c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*190*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*194*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*198*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*19c*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1a8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ac*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1b8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1bc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1c8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1cc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1d8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1dc*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1e8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1ec*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f0*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f4*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} }, /*1f8*/ - { {0}, {0} }, { {0}, {0} }, - { {0}, {0} }, { {0}, {0} } /*1fc*/ + { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ + { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ + { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ + { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ + { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ + { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ + { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ + { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ + { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ + { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ + { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ + { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ + { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ + { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ + { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ + { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ + { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ + { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ + { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ + { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ + { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ + { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ + { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ + { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ + { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ + { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ + { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ + { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ + { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ + { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ + { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ + { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ + { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ + { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ + { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ + { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ + { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ + { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ + { { 0 }, { 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14a */ + { { 0 }, { 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14c */ + { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ + { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ + { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, { { 0x54, 0 }, { 0xd4, 0 } }, /* 15c */ + { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x5c, 0 }, { 0xdc, 0 } }, /* 15e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ + + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ // clang-format on }; From 931fc0d24a9767cc0202e29c3feacd41699fd7ef Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 21 Jun 2024 21:24:03 -0400 Subject: [PATCH 652/690] One line per keyboard scancode (Part 2) --- src/device/keyboard_at.c | 2241 +++++++++++++++++++++++------------ src/device/keyboard_xt.c | 771 ++++++++---- src/machine/m_amstrad.c | 747 ++++++++---- src/machine/m_tandy.c | 771 ++++++++---- src/machine/m_xt_olivetti.c | 1542 ++++++++++++++++-------- 5 files changed, 4032 insertions(+), 2040 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index aea35e995..915dbe2b8 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -81,769 +81,1504 @@ static uint16_t bat_counter = 0; static const scancode scancode_set1[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ - { { 0x54, 0 }, { 0xd4, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 054 */ - { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x57, 0 }, { 0xd7, 0 } }, /* 056 */ - { { 0x58, 0 }, { 0xd8, 0 } }, { { 0x59, 0 }, { 0xd9, 0 } }, /* 058 */ - { { 0x5a, 0 }, { 0xda, 0 } }, { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05a */ - { { 0x5c, 0 }, { 0xdc, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05c */ - { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05e */ - { { 0x60, 0 }, { 0xe0, 0 } }, { { 0x61, 0 }, { 0xe1, 0 } }, /* 060 */ - { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 062 */ - { { 0x64, 0 }, { 0xe4, 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 064 */ - { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x67, 0 }, { 0xe7, 0 } }, /* 066 */ - { { 0x68, 0 }, { 0xe8, 0 } }, { { 0x69, 0 }, { 0xe9, 0 } }, /* 068 */ - { { 0x6a, 0 }, { 0xea, 0 } }, { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06a */ - { { 0x6c, 0 }, { 0xec, 0 } }, { { 0x6d, 0 }, { 0xed, 0 } }, /* 06c */ - { { 0x6e, 0 }, { 0xee, 0 } }, { { 0x6f, 0 }, { 0xef, 0 } }, /* 06e */ - { { 0x70, 0 }, { 0xf0, 0 } }, { { 0x71, 0 }, { 0xf1, 0 } }, /* 070 */ - { { 0x72, 0 }, { 0xf2, 0 } }, { { 0x73, 0 }, { 0xf3, 0 } }, /* 072 */ - { { 0x74, 0 }, { 0xf4, 0 } }, { { 0x75, 0 }, { 0xf5, 0 } }, /* 074 */ - { { 0x76, 0 }, { 0xf6, 0 } }, { { 0x77, 0 }, { 0xf7, 0 } }, /* 076 */ - { { 0x78, 0 }, { 0xf8, 0 } }, { { 0x79, 0 }, { 0xf9, 0 } }, /* 078 */ - { { 0x7a, 0 }, { 0xfa, 0 } }, { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07a */ - { { 0x7c, 0 }, { 0xfc, 0 } }, { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07c */ - { { 0x7e, 0 }, { 0xfe, 0 } }, { { 0x7f, 0 }, { 0xff, 0 } }, /* 07e */ - - { { 0x80, 0 }, { 0 } }, { { 0x81, 0 }, { 0 } }, /* 080 */ - { { 0x82, 0 }, { 0 } }, { { 0 } ,{ 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0x85, 0 }, { 0 } }, /* 084 */ - { { 0x86, 0 }, { 0 } }, { { 0x87, 0 }, { 0 } }, /* 086 */ - { { 0x88, 0 }, { 0 } }, { { 0x89, 0 }, { 0 } }, /* 088 */ - { { 0x8a, 0 }, { 0 } }, { { 0x8b, 0 }, { 0 } }, /* 08a */ - { { 0x8c, 0 }, { 0 } }, { { 0x8d, 0 }, { 0 } }, /* 08c */ - { { 0x8e, 0 }, { 0 } }, { { 0x8f, 0 }, { 0 } }, /* 08e */ - { { 0x90, 0 }, { 0 } }, { { 0x91, 0 }, { 0 } }, /* 090 */ - { { 0x92, 0 }, { 0 } }, { { 0x93, 0 }, { 0 } }, /* 092 */ - { { 0x94, 0 }, { 0 } }, { { 0x95, 0 }, { 0 } }, /* 094 */ - { { 0x96, 0 }, { 0 } }, { { 0x97, 0 }, { 0 } }, /* 096 */ - { { 0x98, 0 }, { 0 } }, { { 0x99, 0 }, { 0 } }, /* 098 */ - { { 0x9a, 0 }, { 0 } }, { { 0x9b, 0 }, { 0 } }, /* 09a */ - { { 0x9c, 0 }, { 0 } }, { { 0x9d, 0 }, { 0 } }, /* 09c */ - { { 0x9e, 0 }, { 0 } }, { { 0x9f, 0 }, { 0 } }, /* 09e */ - { { 0xa0, 0 }, { 0 } }, { { 0xa1, 0 }, { 0 } }, /* 0a0 */ - { { 0xa2, 0 }, { 0 } }, { { 0xa3, 0 }, { 0 } }, /* 0a2 */ - { { 0xa4, 0 }, { 0 } }, { { 0xa5, 0 }, { 0 } }, /* 0a4 */ - { { 0xa6, 0 }, { 0 } }, { { 0xa7, 0 }, { 0 } }, /* 0a6 */ - { { 0xa8, 0 }, { 0 } }, { { 0xa9, 0 }, { 0 } }, /* 0a8 */ - { { 0xaa, 0 }, { 0 } }, { { 0xab, 0 }, { 0 } }, /* 0aa */ - { { 0xac, 0 }, { 0 } }, { { 0xad, 0 }, { 0 } }, /* 0ac */ - { { 0xae, 0 }, { 0 } }, { { 0xaf, 0 }, { 0 } }, /* 0ae */ - { { 0xb0, 0 }, { 0 } }, { { 0xb1, 0 }, { 0 } }, /* 0b0 */ - { { 0xb2, 0 }, { 0 } }, { { 0xb3, 0 }, { 0 } }, /* 0b2 */ - { { 0xb4, 0 }, { 0 } }, { { 0xb5, 0 }, { 0 } }, /* 0b4 */ - { { 0xb6, 0 }, { 0 } }, { { 0xb7, 0 }, { 0 } }, /* 0b6 */ - { { 0xb8, 0 }, { 0 } }, { { 0xb9, 0 }, { 0 } }, /* 0b8 */ - { { 0xba, 0 }, { 0 } }, { { 0xbb, 0 }, { 0 } }, /* 0ba */ - { { 0xbc, 0 }, { 0 } }, { { 0xbd, 0 }, { 0 } }, /* 0bc */ - { { 0xbe, 0 }, { 0 } }, { { 0xbf, 0 }, { 0 } }, /* 0be */ - { { 0xc0, 0 }, { 0 } }, { { 0xc1, 0 }, { 0 } }, /* 0c0 */ - { { 0xc2, 0 }, { 0 } }, { { 0xc3, 0 }, { 0 } }, /* 0c2 */ - { { 0xc4, 0 }, { 0 } }, { { 0xc5, 0 }, { 0 } }, /* 0c4 */ - { { 0xc6, 0 }, { 0 } }, { { 0xc7, 0 }, { 0 } }, /* 0c6 */ - { { 0xc8, 0 }, { 0 } }, { { 0xc9, 0 }, { 0 } }, /* 0c8 */ - { { 0xca, 0 }, { 0 } }, { { 0xcb, 0 }, { 0 } }, /* 0ca */ - { { 0xcc, 0 }, { 0 } }, { { 0xcd, 0 }, { 0 } }, /* 0cc */ - { { 0xce, 0 }, { 0 } }, { { 0xcf, 0 }, { 0 } }, /* 0ce */ - { { 0xd0, 0 }, { 0 } }, { { 0xd1, 0 }, { 0 } }, /* 0d0 */ - { { 0xd2, 0 }, { 0 } }, { { 0xd3, 0 }, { 0 } }, /* 0d2 */ - { { 0xd4, 0 }, { 0 } }, { { 0xd5, 0 }, { 0 } }, /* 0d4 */ - { { 0xd6, 0 }, { 0 } }, { { 0xd7, 0 }, { 0 } }, /* 0d6 */ - { { 0xd8, 0 }, { 0 } }, { { 0xd9, 0 }, { 0 } }, /* 0d8 */ - { { 0xda, 0 }, { 0 } }, { { 0xdb, 0 }, { 0 } }, /* 0da */ - { { 0xdc, 0 }, { 0 } }, { { 0xdd, 0 }, { 0 } }, /* 0dc */ - { { 0xde, 0 }, { 0 } }, { { 0xdf, 0 }, { 0 } }, /* 0de */ - { { 0xe0, 0 }, { 0 } }, { { 0xe1, 0 }, { 0 } }, /* 0e0 */ - { { 0xe2, 0 }, { 0 } }, { { 0xe3, 0 }, { 0 } }, /* 0e2 */ - { { 0xe4, 0 }, { 0 } }, { { 0xe5, 0 }, { 0 } }, /* 0e4 */ - { { 0xe6, 0 }, { 0 } }, { { 0xe7, 0 }, { 0 } }, /* 0e6 */ - { { 0xe8, 0 }, { 0 } }, { { 0xe9, 0 }, { 0 } }, /* 0e8 */ - { { 0xea, 0 }, { 0 } }, { { 0xeb, 0 }, { 0 } }, /* 0ea */ - { { 0xec, 0 }, { 0 } }, { { 0xed, 0 }, { 0 } }, /* 0ec */ - { { 0xee, 0 }, { 0 } }, { { 0xef, 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0 } }, /* 0f0 */ - { { 0xf2, 0 }, { 0 } }, { { 0xf3, 0 }, { 0 } }, /* 0f2 */ - { { 0xf4, 0 }, { 0 } }, { { 0xf5, 0 }, { 0 } }, /* 0f4 */ - { { 0xf6, 0 }, { 0 } }, { { 0xf7, 0 }, { 0 } }, /* 0f6 */ - { { 0xf8, 0 }, { 0 } }, { { 0xf9, 0 }, { 0 } }, /* 0f8 */ - { { 0xfa, 0 }, { 0 } }, { { 0xfb, 0 }, { 0 } }, /* 0fa */ - { { 0xfc, 0 }, { 0 } }, { { 0xfd, 0 }, { 0 } }, /* 0fc */ - { { 0xfe, 0 }, { 0 } }, { { 0xff, 0 }, { 0 } }, /* 0fe */ - - { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 100 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 102 */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 104 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 106 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 108 */ - { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10a */ - { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10e */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 110 */ - { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 112 */ - { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 114 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 116 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 118 */ - { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11a */ - { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11c */ - { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11e */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 120 */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 122 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 124 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12c */ - { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12e */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 130 */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 136 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ - { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13a */ - { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13c */ - { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13e */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 140 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 142 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 146 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14a */ - { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14c */ - { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14e */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 150 */ - { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 156 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 158 */ - { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15a */ - { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15c */ - { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 160 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 162 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 164 */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 166 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 168 */ - { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16a */ - { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16c */ - { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 170 */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 172 */ - { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 176 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 178 */ - { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17a */ - { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17c */ - { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0xe0, 0xee, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0xe0, 0xfe, 0 }, { 0 } }, { { 0xe0, 0xff, 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ + { { 0x54, 0 }, { 0xd4, 0 } }, /* 054 */ + { { 0x55, 0 }, { 0xd5, 0 } }, /* 055 */ + { { 0x56, 0 }, { 0xd6, 0 } }, /* 056 */ + { { 0x57, 0 }, { 0xd7, 0 } }, /* 057 */ + { { 0x58, 0 }, { 0xd8, 0 } }, /* 058 */ + { { 0x59, 0 }, { 0xd9, 0 } }, /* 059 */ + { { 0x5a, 0 }, { 0xda, 0 } }, /* 05a */ + { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05b */ + { { 0x5c, 0 }, { 0xdc, 0 } }, /* 05c */ + { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05d */ + { { 0x5e, 0 }, { 0xde, 0 } }, /* 05e */ + { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05f */ + { { 0x60, 0 }, { 0xe0, 0 } }, /* 060 */ + { { 0x61, 0 }, { 0xe1, 0 } }, /* 061 */ + { { 0x62, 0 }, { 0xe2, 0 } }, /* 062 */ + { { 0x63, 0 }, { 0xe3, 0 } }, /* 063 */ + { { 0x64, 0 }, { 0xe4, 0 } }, /* 064 */ + { { 0x65, 0 }, { 0xe5, 0 } }, /* 065 */ + { { 0x66, 0 }, { 0xe6, 0 } }, /* 066 */ + { { 0x67, 0 }, { 0xe7, 0 } }, /* 067 */ + { { 0x68, 0 }, { 0xe8, 0 } }, /* 068 */ + { { 0x69, 0 }, { 0xe9, 0 } }, /* 069 */ + { { 0x6a, 0 }, { 0xea, 0 } }, /* 06a */ + { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06b */ + { { 0x6c, 0 }, { 0xec, 0 } }, /* 06c */ + { { 0x6d, 0 }, { 0xed, 0 } }, /* 06d */ + { { 0x6e, 0 }, { 0xee, 0 } }, /* 06e */ + { { 0x6f, 0 }, { 0xef, 0 } }, /* 06f */ + { { 0x70, 0 }, { 0xf0, 0 } }, /* 070 */ + { { 0x71, 0 }, { 0xf1, 0 } }, /* 071 */ + { { 0x72, 0 }, { 0xf2, 0 } }, /* 072 */ + { { 0x73, 0 }, { 0xf3, 0 } }, /* 073 */ + { { 0x74, 0 }, { 0xf4, 0 } }, /* 074 */ + { { 0x75, 0 }, { 0xf5, 0 } }, /* 075 */ + { { 0x76, 0 }, { 0xf6, 0 } }, /* 076 */ + { { 0x77, 0 }, { 0xf7, 0 } }, /* 077 */ + { { 0x78, 0 }, { 0xf8, 0 } }, /* 078 */ + { { 0x79, 0 }, { 0xf9, 0 } }, /* 079 */ + { { 0x7a, 0 }, { 0xfa, 0 } }, /* 07a */ + { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07b */ + { { 0x7c, 0 }, { 0xfc, 0 } }, /* 07c */ + { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07d */ + { { 0x7e, 0 }, { 0xfe, 0 } }, /* 07e */ + { { 0x7f, 0 }, { 0xff, 0 } }, /* 07f */ + { { 0x80, 0 }, { 0 } }, /* 080 */ + { { 0x81, 0 }, { 0 } }, /* 081 */ + { { 0x82, 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0x85, 0 }, { 0 } }, /* 085 */ + { { 0x86, 0 }, { 0 } }, /* 086 */ + { { 0x87, 0 }, { 0 } }, /* 087 */ + { { 0x88, 0 }, { 0 } }, /* 088 */ + { { 0x89, 0 }, { 0 } }, /* 089 */ + { { 0x8a, 0 }, { 0 } }, /* 08a */ + { { 0x8b, 0 }, { 0 } }, /* 08b */ + { { 0x8c, 0 }, { 0 } }, /* 08c */ + { { 0x8d, 0 }, { 0 } }, /* 08d */ + { { 0x8e, 0 }, { 0 } }, /* 08e */ + { { 0x8f, 0 }, { 0 } }, /* 08f */ + { { 0x90, 0 }, { 0 } }, /* 090 */ + { { 0x91, 0 }, { 0 } }, /* 091 */ + { { 0x92, 0 }, { 0 } }, /* 092 */ + { { 0x93, 0 }, { 0 } }, /* 093 */ + { { 0x94, 0 }, { 0 } }, /* 094 */ + { { 0x95, 0 }, { 0 } }, /* 095 */ + { { 0x96, 0 }, { 0 } }, /* 096 */ + { { 0x97, 0 }, { 0 } }, /* 097 */ + { { 0x98, 0 }, { 0 } }, /* 098 */ + { { 0x99, 0 }, { 0 } }, /* 099 */ + { { 0x9a, 0 }, { 0 } }, /* 09a */ + { { 0x9b, 0 }, { 0 } }, /* 09b */ + { { 0x9c, 0 }, { 0 } }, /* 09c */ + { { 0x9d, 0 }, { 0 } }, /* 09d */ + { { 0x9e, 0 }, { 0 } }, /* 09e */ + { { 0x9f, 0 }, { 0 } }, /* 09f */ + { { 0xa0, 0 }, { 0 } }, /* 0a0 */ + { { 0xa1, 0 }, { 0 } }, /* 0a1 */ + { { 0xa2, 0 }, { 0 } }, /* 0a2 */ + { { 0xa3, 0 }, { 0 } }, /* 0a3 */ + { { 0xa4, 0 }, { 0 } }, /* 0a4 */ + { { 0xa5, 0 }, { 0 } }, /* 0a5 */ + { { 0xa6, 0 }, { 0 } }, /* 0a6 */ + { { 0xa7, 0 }, { 0 } }, /* 0a7 */ + { { 0xa8, 0 }, { 0 } }, /* 0a8 */ + { { 0xa9, 0 }, { 0 } }, /* 0a9 */ + { { 0xaa, 0 }, { 0 } }, /* 0aa */ + { { 0xab, 0 }, { 0 } }, /* 0ab */ + { { 0xac, 0 }, { 0 } }, /* 0ac */ + { { 0xad, 0 }, { 0 } }, /* 0ad */ + { { 0xae, 0 }, { 0 } }, /* 0ae */ + { { 0xaf, 0 }, { 0 } }, /* 0af */ + { { 0xb0, 0 }, { 0 } }, /* 0b0 */ + { { 0xb1, 0 }, { 0 } }, /* 0b1 */ + { { 0xb2, 0 }, { 0 } }, /* 0b2 */ + { { 0xb3, 0 }, { 0 } }, /* 0b3 */ + { { 0xb4, 0 }, { 0 } }, /* 0b4 */ + { { 0xb5, 0 }, { 0 } }, /* 0b5 */ + { { 0xb6, 0 }, { 0 } }, /* 0b6 */ + { { 0xb7, 0 }, { 0 } }, /* 0b7 */ + { { 0xb8, 0 }, { 0 } }, /* 0b8 */ + { { 0xb9, 0 }, { 0 } }, /* 0b9 */ + { { 0xba, 0 }, { 0 } }, /* 0ba */ + { { 0xbb, 0 }, { 0 } }, /* 0bb */ + { { 0xbc, 0 }, { 0 } }, /* 0bc */ + { { 0xbd, 0 }, { 0 } }, /* 0bd */ + { { 0xbe, 0 }, { 0 } }, /* 0be */ + { { 0xbf, 0 }, { 0 } }, /* 0bf */ + { { 0xc0, 0 }, { 0 } }, /* 0c0 */ + { { 0xc1, 0 }, { 0 } }, /* 0c1 */ + { { 0xc2, 0 }, { 0 } }, /* 0c2 */ + { { 0xc3, 0 }, { 0 } }, /* 0c3 */ + { { 0xc4, 0 }, { 0 } }, /* 0c4 */ + { { 0xc5, 0 }, { 0 } }, /* 0c5 */ + { { 0xc6, 0 }, { 0 } }, /* 0c6 */ + { { 0xc7, 0 }, { 0 } }, /* 0c7 */ + { { 0xc8, 0 }, { 0 } }, /* 0c8 */ + { { 0xc9, 0 }, { 0 } }, /* 0c9 */ + { { 0xca, 0 }, { 0 } }, /* 0ca */ + { { 0xcb, 0 }, { 0 } }, /* 0cb */ + { { 0xcc, 0 }, { 0 } }, /* 0cc */ + { { 0xcd, 0 }, { 0 } }, /* 0cd */ + { { 0xce, 0 }, { 0 } }, /* 0ce */ + { { 0xcf, 0 }, { 0 } }, /* 0cf */ + { { 0xd0, 0 }, { 0 } }, /* 0d0 */ + { { 0xd1, 0 }, { 0 } }, /* 0d1 */ + { { 0xd2, 0 }, { 0 } }, /* 0d2 */ + { { 0xd3, 0 }, { 0 } }, /* 0d3 */ + { { 0xd4, 0 }, { 0 } }, /* 0d4 */ + { { 0xd5, 0 }, { 0 } }, /* 0d5 */ + { { 0xd6, 0 }, { 0 } }, /* 0d6 */ + { { 0xd7, 0 }, { 0 } }, /* 0d7 */ + { { 0xd8, 0 }, { 0 } }, /* 0d8 */ + { { 0xd9, 0 }, { 0 } }, /* 0d9 */ + { { 0xda, 0 }, { 0 } }, /* 0da */ + { { 0xdb, 0 }, { 0 } }, /* 0db */ + { { 0xdc, 0 }, { 0 } }, /* 0dc */ + { { 0xdd, 0 }, { 0 } }, /* 0dd */ + { { 0xde, 0 }, { 0 } }, /* 0de */ + { { 0xdf, 0 }, { 0 } }, /* 0df */ + { { 0xe0, 0 }, { 0 } }, /* 0e0 */ + { { 0xe1, 0 }, { 0 } }, /* 0e1 */ + { { 0xe2, 0 }, { 0 } }, /* 0e2 */ + { { 0xe3, 0 }, { 0 } }, /* 0e3 */ + { { 0xe4, 0 }, { 0 } }, /* 0e4 */ + { { 0xe5, 0 }, { 0 } }, /* 0e5 */ + { { 0xe6, 0 }, { 0 } }, /* 0e6 */ + { { 0xe7, 0 }, { 0 } }, /* 0e7 */ + { { 0xe8, 0 }, { 0 } }, /* 0e8 */ + { { 0xe9, 0 }, { 0 } }, /* 0e9 */ + { { 0xea, 0 }, { 0 } }, /* 0ea */ + { { 0xeb, 0 }, { 0 } }, /* 0eb */ + { { 0xec, 0 }, { 0 } }, /* 0ec */ + { { 0xed, 0 }, { 0 } }, /* 0ed */ + { { 0xee, 0 }, { 0 } }, /* 0ee */ + { { 0xef, 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0xf1, 0 }, { 0 } }, /* 0f1 */ + { { 0xf2, 0 }, { 0 } }, /* 0f2 */ + { { 0xf3, 0 }, { 0 } }, /* 0f3 */ + { { 0xf4, 0 }, { 0 } }, /* 0f4 */ + { { 0xf5, 0 }, { 0 } }, /* 0f5 */ + { { 0xf6, 0 }, { 0 } }, /* 0f6 */ + { { 0xf7, 0 }, { 0 } }, /* 0f7 */ + { { 0xf8, 0 }, { 0 } }, /* 0f8 */ + { { 0xf9, 0 }, { 0 } }, /* 0f9 */ + { { 0xfa, 0 }, { 0 } }, /* 0fa */ + { { 0xfb, 0 }, { 0 } }, /* 0fb */ + { { 0xfc, 0 }, { 0 } }, /* 0fc */ + { { 0xfd, 0 }, { 0 } }, /* 0fd */ + { { 0xfe, 0 }, { 0 } }, /* 0fe */ + { { 0xff, 0 }, { 0 } }, /* 0ff */ + { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, /* 100 */ + { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 101 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, /* 102 */ + { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 103 */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, /* 104 */ + { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 105 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, /* 106 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 107 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, /* 108 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 109 */ + { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, /* 10a */ + { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10b */ + { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, /* 10e */ + { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10f */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, /* 110 */ + { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 111 */ + { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, /* 112 */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 113 */ + { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, /* 114 */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 115 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, /* 116 */ + { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 117 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, /* 118 */ + { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 119 */ + { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, /* 11a */ + { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11b */ + { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, /* 11c */ + { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11d */ + { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, /* 11e */ + { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11f */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, /* 120 */ + { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 121 */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, /* 122 */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 123 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, /* 124 */ + { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 125 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, /* 12c */ + { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12d */ + { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, /* 12e */ + { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12f */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, /* 130 */ + { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 131 */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, /* 134 */ + { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 137 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, /* 13a */ + { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13b */ + { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, /* 13c */ + { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13d */ + { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, /* 13e */ + { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13f */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, /* 140 */ + { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 141 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, /* 142 */ + { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 143 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, /* 146 */ + { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 147 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, /* 148 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14b */ + { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, /* 14c */ + { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14d */ + { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, /* 14e */ + { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14f */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, /* 150 */ + { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 151 */ + { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, /* 152 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 157 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, /* 158 */ + { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 159 */ + { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, /* 15a */ + { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15b */ + { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, /* 15c */ + { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15d */ + { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, /* 15e */ + { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 161 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, /* 162 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 163 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, /* 164 */ + { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 165 */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, /* 166 */ + { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 167 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, /* 168 */ + { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 169 */ + { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, /* 16a */ + { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16b */ + { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, /* 16c */ + { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16d */ + { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, /* 170 */ + { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 171 */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, /* 172 */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 173 */ + { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, /* 174 */ + { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 177 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, /* 178 */ + { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 179 */ + { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, /* 17a */ + { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17b */ + { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, /* 17c */ + { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17d */ + { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, /* 17e */ + { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0xe0, 0xee, 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0xe0, 0xfe, 0 }, { 0 } }, /* 1fe */ + { { 0xe0, 0xff, 0 }, { 0 } } /* 1ff */ // clang-format on }; static const scancode scancode_set2[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x76, 0 }, { 0xF0, 0x76, 0 } }, /* 000 */ - { { 0x16, 0 }, { 0xF0, 0x16, 0 } }, { { 0x1E, 0 }, { 0xF0, 0x1E, 0 } }, /* 002 */ - { { 0x26, 0 }, { 0xF0, 0x26, 0 } }, { { 0x25, 0 }, { 0xF0, 0x25, 0 } }, - { { 0x2E, 0 }, { 0xF0, 0x2E, 0 } }, { { 0x36, 0 }, { 0xF0, 0x36, 0 } }, /* 004 */ - { { 0x3D, 0 }, { 0xF0, 0x3D, 0 } }, { { 0x3E, 0 }, { 0xF0, 0x3E, 0 } }, - { { 0x46, 0 }, { 0xF0, 0x46, 0 } }, { { 0x45, 0 }, { 0xF0, 0x45, 0 } }, /* 008 */ - { { 0x4E, 0 }, { 0xF0, 0x4E, 0 } }, { { 0x55, 0 }, { 0xF0, 0x55, 0 } }, - { { 0x66, 0 }, { 0xF0, 0x66, 0 } }, { { 0x0D, 0 }, { 0xF0, 0x0D, 0 } }, /* 00c */ - { { 0x15, 0 }, { 0xF0, 0x15, 0 } }, { { 0x1D, 0 }, { 0xF0, 0x1D, 0 } }, - { { 0x24, 0 }, { 0xF0, 0x24, 0 } }, { { 0x2D, 0 }, { 0xF0, 0x2D, 0 } }, /* 010 */ - { { 0x2C, 0 }, { 0xF0, 0x2C, 0 } }, { { 0x35, 0 }, { 0xF0, 0x35, 0 } }, - { { 0x3C, 0 }, { 0xF0, 0x3C, 0 } }, { { 0x43, 0 }, { 0xF0, 0x43, 0 } }, /* 014 */ - { { 0x44, 0 }, { 0xF0, 0x44, 0 } }, { { 0x4D, 0 }, { 0xF0, 0x4D, 0 } }, - { { 0x54, 0 }, { 0xF0, 0x54, 0 } }, { { 0x5B, 0 }, { 0xF0, 0x5B, 0 } }, /* 018 */ - { { 0x5A, 0 }, { 0xF0, 0x5A, 0 } }, { { 0x14, 0 }, { 0xF0, 0x14, 0 } }, - { { 0x1C, 0 }, { 0xF0, 0x1C, 0 } }, { { 0x1B, 0 }, { 0xF0, 0x1B, 0 } }, /* 01c */ - { { 0x23, 0 }, { 0xF0, 0x23, 0 } }, { { 0x2B, 0 }, { 0xF0, 0x2B, 0 } }, - { { 0x34, 0 }, { 0xF0, 0x34, 0 } }, { { 0x33, 0 }, { 0xF0, 0x33, 0 } }, /* 020 */ - { { 0x3B, 0 }, { 0xF0, 0x3B, 0 } }, { { 0x42, 0 }, { 0xF0, 0x42, 0 } }, - { { 0x4B, 0 }, { 0xF0, 0x4B, 0 } }, { { 0x4C, 0 }, { 0xF0, 0x4C, 0 } }, /* 024 */ - { { 0x52, 0 }, { 0xF0, 0x52, 0 } }, { { 0x0E, 0 }, { 0xF0, 0x0E, 0 } }, - { { 0x12, 0 }, { 0xF0, 0x12, 0 } }, { { 0x5D, 0 }, { 0xF0, 0x5D, 0 } }, /* 028 */ - { { 0x1A, 0 }, { 0xF0, 0x1A, 0 } }, { { 0x22, 0 }, { 0xF0, 0x22, 0 } }, - { { 0x21, 0 }, { 0xF0, 0x21, 0 } }, { { 0x2A, 0 }, { 0xF0, 0x2A, 0 } }, /* 02c */ - { { 0x32, 0 }, { 0xF0, 0x32, 0 } }, { { 0x31, 0 }, { 0xF0, 0x31, 0 } }, - { { 0x3A, 0 }, { 0xF0, 0x3A, 0 } }, { { 0x41, 0 }, { 0xF0, 0x41, 0 } }, /* 030 */ - { { 0x49, 0 }, { 0xF0, 0x49, 0 } }, { { 0x4A, 0 }, { 0xF0, 0x4A, 0 } }, - { { 0x59, 0 }, { 0xF0, 0x59, 0 } }, { { 0x7C, 0 }, { 0xF0, 0x7C, 0 } }, /* 034 */ - { { 0x11, 0 }, { 0xF0, 0x11, 0 } }, { { 0x29, 0 }, { 0xF0, 0x29, 0 } }, - { { 0x58, 0 }, { 0xF0, 0x58, 0 } }, { { 0x05, 0 }, { 0xF0, 0x05, 0 } }, /* 038 */ - { { 0x06, 0 }, { 0xF0, 0x06, 0 } }, { { 0x04, 0 }, { 0xF0, 0x04, 0 } }, - { { 0x0C, 0 }, { 0xF0, 0x0C, 0 } }, { { 0x03, 0 }, { 0xF0, 0x03, 0 } }, /* 03c */ - { { 0x0B, 0 }, { 0xF0, 0x0B, 0 } }, { { 0x83, 0 }, { 0xF0, 0x83, 0 } }, - { { 0x0A, 0 }, { 0xF0, 0x0A, 0 } }, { { 0x01, 0 }, { 0xF0, 0x01, 0 } }, /* 040 */ - { { 0x09, 0 }, { 0xF0, 0x09, 0 } }, { { 0x77, 0 }, { 0xF0, 0x77, 0 } }, - { { 0x7E, 0 }, { 0xF0, 0x7E, 0 } }, { { 0x6C, 0 }, { 0xF0, 0x6C, 0 } }, /* 044 */ - { { 0x75, 0 }, { 0xF0, 0x75, 0 } }, { { 0x7D, 0 }, { 0xF0, 0x7D, 0 } }, - { { 0x7B, 0 }, { 0xF0, 0x7B, 0 } }, { { 0x6B, 0 }, { 0xF0, 0x6B, 0 } }, /* 048 */ - { { 0x73, 0 }, { 0xF0, 0x73, 0 } }, { { 0x74, 0 }, { 0xF0, 0x74, 0 } }, - { { 0x79, 0 }, { 0xF0, 0x79, 0 } }, { { 0x69, 0 }, { 0xF0, 0x69, 0 } }, /* 04c */ - { { 0x72, 0 }, { 0xF0, 0x72, 0 } }, { { 0x7A, 0 }, { 0xF0, 0x7A, 0 } }, - { { 0x70, 0 }, { 0xF0, 0x70, 0 } }, { { 0x71, 0 }, { 0xF0, 0x71, 0 } }, /* 050 */ - { { 0x84, 0 }, { 0xF0, 0x84, 0 } }, { { 0x60, 0 }, { 0xF0, 0x60, 0 } }, - { { 0x61, 0 }, { 0xF0, 0x61, 0 } }, { { 0x78, 0 }, { 0xF0, 0x78, 0 } }, /* 054 */ - { { 0x07, 0 }, { 0xF0, 0x07, 0 } }, { { 0x0F, 0 }, { 0xF0, 0x0F, 0 } }, - { { 0x17, 0 }, { 0xF0, 0x17, 0 } }, { { 0x1F, 0 }, { 0xF0, 0x1F, 0 } }, /* 058 */ - { { 0x27, 0 }, { 0xF0, 0x27, 0 } }, { { 0x2F, 0 }, { 0xF0, 0x2F, 0 } }, - { { 0x37, 0 }, { 0xF0, 0x37, 0 } }, { { 0x3F, 0 }, { 0xF0, 0x3F, 0 } }, /* 05c */ - { { 0x47, 0 }, { 0xF0, 0x47, 0 } }, { { 0x4F, 0 }, { 0xF0, 0x4F, 0 } }, - { { 0x56, 0 }, { 0xF0, 0x56, 0 } }, { { 0x5E, 0 }, { 0xF0, 0x5E, 0 } }, /* 060 */ - { { 0x08, 0 }, { 0xF0, 0x08, 0 } }, { { 0x10, 0 }, { 0xF0, 0x10, 0 } }, - { { 0x18, 0 }, { 0xF0, 0x18, 0 } }, { { 0x20, 0 }, { 0xF0, 0x20, 0 } }, /* 064 */ - { { 0x28, 0 }, { 0xF0, 0x28, 0 } }, { { 0x30, 0 }, { 0xF0, 0x30, 0 } }, - { { 0x38, 0 }, { 0xF0, 0x38, 0 } }, { { 0x40, 0 }, { 0xF0, 0x40, 0 } }, /* 068 */ - { { 0x48, 0 }, { 0xF0, 0x48, 0 } }, { { 0x50, 0 }, { 0xF0, 0x50, 0 } }, - { { 0x57, 0 }, { 0xF0, 0x57, 0 } }, { { 0x6F, 0 }, { 0xF0, 0x6F, 0 } }, /* 06c */ - { { 0x13, 0 }, { 0xF0, 0x13, 0 } }, { { 0x19, 0 }, { 0xF0, 0x19, 0 } }, - { { 0x39, 0 }, { 0xF0, 0x39, 0 } }, { { 0x51, 0 }, { 0xF0, 0x51, 0 } }, /* 070 */ - { { 0x53, 0 }, { 0xF0, 0x53, 0 } }, { { 0x5C, 0 }, { 0xF0, 0x5C, 0 } }, - { { 0x5F, 0 }, { 0xF0, 0x5F, 0 } }, { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 074 */ - { { 0x63, 0 }, { 0xF0, 0x63, 0 } }, { { 0x64, 0 }, { 0xF0, 0x64, 0 } }, - { { 0x65, 0 }, { 0xF0, 0x65, 0 } }, { { 0x67, 0 }, { 0xF0, 0x67, 0 } }, /* 078 */ - { { 0x68, 0 }, { 0xF0, 0x68, 0 } }, { { 0x6A, 0 }, { 0xF0, 0x6A, 0 } }, - { { 0x6D, 0 }, { 0xF0, 0x6D, 0 } }, { { 0x6E, 0 }, { 0xF0, 0x6E, 0 } }, /* 07c */ - - { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 080 */ - { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, - { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 084 */ - { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, - { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 088 */ - { { 0x8c, 0 }, { 0xf0, 0x8c, 0 } }, { { 0x8d, 0 }, { 0xf0, 0x8d, 0 } }, - { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08c */ - { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, - { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 090 */ - { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, - { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 094 */ - { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, - { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 098 */ - { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, - { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09c */ - { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, - { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a0 */ - { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, - { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a4 */ - { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, - { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0a8 */ - { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, - { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0ac */ - { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, - { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b0 */ - { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, - { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b4 */ - { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, - { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0b8 */ - { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, - { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bc */ - { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, - { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c0 */ - { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, - { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c4 */ - { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, - { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0c8 */ - { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, - { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cc */ - { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, - { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d0 */ - { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, - { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d4 */ - { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, - { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0d8 */ - { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, - { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0dc */ - { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, - { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e0 */ - { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, - { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e4 */ - { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, - { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0e8 */ - { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, - { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, - { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f0 */ - { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, - { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f4 */ - { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, - { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0f8 */ - { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, - { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0fc */ - - { { 0xe1, 0x14, 0 }, { 0xe1, 0xf0, 0x14, 0 } }, { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 100 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 102 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, - { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 104 */ - { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, - { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 108 */ - { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10c */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, - { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 110 */ - { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, - { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 114 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, - { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 118 */ - { { 0xe0, 0x5A, 0 }, { 0xe0, 0xF0, 0x5A, 0 } }, { { 0xe0, 0x14, 0 }, { 0xe0, 0xF0, 0x14, 0 } }, - { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11c */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, - { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 120 */ - { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, - { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, - { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12c */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, - { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, { { 0xe0, 0x4A, 0 }, { 0xe0, 0xF0, 0x4A, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x7C, 0 }, { 0xe0, 0xF0, 0x7C, 0 } }, /* 134 */ - { { 0xe0, 0x11, 0 }, { 0xe0, 0xF0, 0x11, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 138 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, - { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13c */ - { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, - { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 140 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, { { 0xe0, 0x6C, 0 }, { 0xe0, 0xF0, 0x6C, 0 } }, /* 144 */ - { { 0xe0, 0x75, 0 }, { 0xe0, 0xF0, 0x75, 0 } }, { { 0xe0, 0x7D, 0 }, { 0xe0, 0xF0, 0x7D, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x6B, 0 }, { 0xe0, 0xF0, 0x6B, 0 } }, /* 148 */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, { { 0xe0, 0x74, 0 }, { 0xe0, 0xF0, 0x74, 0 } }, - { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xF0, 0x69, 0 } }, /* 14c */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xF0, 0x72, 0 } }, { { 0xe0, 0x7A, 0 }, { 0xe0, 0xF0, 0x7A, 0 } }, - { { 0xe0, 0x70, 0 }, { 0xe0, 0xF0, 0x70, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xF0, 0x71, 0 } }, /* 150 */ - { { 0 }, { 0 } }, { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 154 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, - { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, { { 0xe0, 0x1F, 0 }, { 0xe0, 0xF0, 0x1F, 0 } }, /* 158 */ - { { 0xe0, 0x27, 0 }, { 0xe0, 0xF0, 0x27, 0 } }, { { 0xe0, 0x2F, 0 }, { 0xe0, 0xF0, 0x2F, 0 } }, - { { 0xe0, 0x37, 0 }, { 0xe0, 0xF0, 0x37, 0 } }, { { 0xe0, 0x3F, 0 }, { 0xe0, 0xF0, 0x3F, 0 } }, /* 15c */ - { { 0 }, { 0 } }, { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, - { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, { { 0xe0, 0x5E, 0 }, { 0xe0, 0xF0, 0x5E, 0 } }, /* 160 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, - { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 164 */ - { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, - { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 168 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, - { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, - { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 170 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 174 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, - { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 178 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, - { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17c */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1fc */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x76, 0 }, { 0xF0, 0x76, 0 } }, /* 001 */ + { { 0x16, 0 }, { 0xF0, 0x16, 0 } }, /* 002 */ + { { 0x1E, 0 }, { 0xF0, 0x1E, 0 } }, /* 003 */ + { { 0x26, 0 }, { 0xF0, 0x26, 0 } }, /* 004 */ + { { 0x25, 0 }, { 0xF0, 0x25, 0 } }, /* 005 */ + { { 0x2E, 0 }, { 0xF0, 0x2E, 0 } }, /* 006 */ + { { 0x36, 0 }, { 0xF0, 0x36, 0 } }, /* 007 */ + { { 0x3D, 0 }, { 0xF0, 0x3D, 0 } }, /* 008 */ + { { 0x3E, 0 }, { 0xF0, 0x3E, 0 } }, /* 009 */ + { { 0x46, 0 }, { 0xF0, 0x46, 0 } }, /* 00a */ + { { 0x45, 0 }, { 0xF0, 0x45, 0 } }, /* 00b */ + { { 0x4E, 0 }, { 0xF0, 0x4E, 0 } }, /* 00c */ + { { 0x55, 0 }, { 0xF0, 0x55, 0 } }, /* 00d */ + { { 0x66, 0 }, { 0xF0, 0x66, 0 } }, /* 00e */ + { { 0x0D, 0 }, { 0xF0, 0x0D, 0 } }, /* 00f */ + { { 0x15, 0 }, { 0xF0, 0x15, 0 } }, /* 010 */ + { { 0x1D, 0 }, { 0xF0, 0x1D, 0 } }, /* 011 */ + { { 0x24, 0 }, { 0xF0, 0x24, 0 } }, /* 012 */ + { { 0x2D, 0 }, { 0xF0, 0x2D, 0 } }, /* 013 */ + { { 0x2C, 0 }, { 0xF0, 0x2C, 0 } }, /* 014 */ + { { 0x35, 0 }, { 0xF0, 0x35, 0 } }, /* 015 */ + { { 0x3C, 0 }, { 0xF0, 0x3C, 0 } }, /* 016 */ + { { 0x43, 0 }, { 0xF0, 0x43, 0 } }, /* 017 */ + { { 0x44, 0 }, { 0xF0, 0x44, 0 } }, /* 018 */ + { { 0x4D, 0 }, { 0xF0, 0x4D, 0 } }, /* 019 */ + { { 0x54, 0 }, { 0xF0, 0x54, 0 } }, /* 01a */ + { { 0x5B, 0 }, { 0xF0, 0x5B, 0 } }, /* 01b */ + { { 0x5A, 0 }, { 0xF0, 0x5A, 0 } }, /* 01c */ + { { 0x14, 0 }, { 0xF0, 0x14, 0 } }, /* 01d */ + { { 0x1C, 0 }, { 0xF0, 0x1C, 0 } }, /* 01e */ + { { 0x1B, 0 }, { 0xF0, 0x1B, 0 } }, /* 01f */ + { { 0x23, 0 }, { 0xF0, 0x23, 0 } }, /* 020 */ + { { 0x2B, 0 }, { 0xF0, 0x2B, 0 } }, /* 021 */ + { { 0x34, 0 }, { 0xF0, 0x34, 0 } }, /* 022 */ + { { 0x33, 0 }, { 0xF0, 0x33, 0 } }, /* 023 */ + { { 0x3B, 0 }, { 0xF0, 0x3B, 0 } }, /* 024 */ + { { 0x42, 0 }, { 0xF0, 0x42, 0 } }, /* 025 */ + { { 0x4B, 0 }, { 0xF0, 0x4B, 0 } }, /* 026 */ + { { 0x4C, 0 }, { 0xF0, 0x4C, 0 } }, /* 027 */ + { { 0x52, 0 }, { 0xF0, 0x52, 0 } }, /* 028 */ + { { 0x0E, 0 }, { 0xF0, 0x0E, 0 } }, /* 029 */ + { { 0x12, 0 }, { 0xF0, 0x12, 0 } }, /* 02a */ + { { 0x5D, 0 }, { 0xF0, 0x5D, 0 } }, /* 02b */ + { { 0x1A, 0 }, { 0xF0, 0x1A, 0 } }, /* 02c */ + { { 0x22, 0 }, { 0xF0, 0x22, 0 } }, /* 02d */ + { { 0x21, 0 }, { 0xF0, 0x21, 0 } }, /* 02e */ + { { 0x2A, 0 }, { 0xF0, 0x2A, 0 } }, /* 02f */ + { { 0x32, 0 }, { 0xF0, 0x32, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xF0, 0x31, 0 } }, /* 031 */ + { { 0x3A, 0 }, { 0xF0, 0x3A, 0 } }, /* 032 */ + { { 0x41, 0 }, { 0xF0, 0x41, 0 } }, /* 033 */ + { { 0x49, 0 }, { 0xF0, 0x49, 0 } }, /* 034 */ + { { 0x4A, 0 }, { 0xF0, 0x4A, 0 } }, /* 035 */ + { { 0x59, 0 }, { 0xF0, 0x59, 0 } }, /* 036 */ + { { 0x7C, 0 }, { 0xF0, 0x7C, 0 } }, /* 037 */ + { { 0x11, 0 }, { 0xF0, 0x11, 0 } }, /* 038 */ + { { 0x29, 0 }, { 0xF0, 0x29, 0 } }, /* 039 */ + { { 0x58, 0 }, { 0xF0, 0x58, 0 } }, /* 03a */ + { { 0x05, 0 }, { 0xF0, 0x05, 0 } }, /* 03b */ + { { 0x06, 0 }, { 0xF0, 0x06, 0 } }, /* 03c */ + { { 0x04, 0 }, { 0xF0, 0x04, 0 } }, /* 03d */ + { { 0x0C, 0 }, { 0xF0, 0x0C, 0 } }, /* 03e */ + { { 0x03, 0 }, { 0xF0, 0x03, 0 } }, /* 03f */ + { { 0x0B, 0 }, { 0xF0, 0x0B, 0 } }, /* 040 */ + { { 0x83, 0 }, { 0xF0, 0x83, 0 } }, /* 041 */ + { { 0x0A, 0 }, { 0xF0, 0x0A, 0 } }, /* 042 */ + { { 0x01, 0 }, { 0xF0, 0x01, 0 } }, /* 043 */ + { { 0x09, 0 }, { 0xF0, 0x09, 0 } }, /* 044 */ + { { 0x77, 0 }, { 0xF0, 0x77, 0 } }, /* 045 */ + { { 0x7E, 0 }, { 0xF0, 0x7E, 0 } }, /* 046 */ + { { 0x6C, 0 }, { 0xF0, 0x6C, 0 } }, /* 047 */ + { { 0x75, 0 }, { 0xF0, 0x75, 0 } }, /* 048 */ + { { 0x7D, 0 }, { 0xF0, 0x7D, 0 } }, /* 049 */ + { { 0x7B, 0 }, { 0xF0, 0x7B, 0 } }, /* 04a */ + { { 0x6B, 0 }, { 0xF0, 0x6B, 0 } }, /* 04b */ + { { 0x73, 0 }, { 0xF0, 0x73, 0 } }, /* 04c */ + { { 0x74, 0 }, { 0xF0, 0x74, 0 } }, /* 04d */ + { { 0x79, 0 }, { 0xF0, 0x79, 0 } }, /* 04e */ + { { 0x69, 0 }, { 0xF0, 0x69, 0 } }, /* 04f */ + { { 0x72, 0 }, { 0xF0, 0x72, 0 } }, /* 050 */ + { { 0x7A, 0 }, { 0xF0, 0x7A, 0 } }, /* 051 */ + { { 0x70, 0 }, { 0xF0, 0x70, 0 } }, /* 052 */ + { { 0x71, 0 }, { 0xF0, 0x71, 0 } }, /* 053 */ + { { 0x84, 0 }, { 0xF0, 0x84, 0 } }, /* 054 */ + { { 0x60, 0 }, { 0xF0, 0x60, 0 } }, /* 055 */ + { { 0x61, 0 }, { 0xF0, 0x61, 0 } }, /* 056 */ + { { 0x78, 0 }, { 0xF0, 0x78, 0 } }, /* 057 */ + { { 0x07, 0 }, { 0xF0, 0x07, 0 } }, /* 058 */ + { { 0x0F, 0 }, { 0xF0, 0x0F, 0 } }, /* 059 */ + { { 0x17, 0 }, { 0xF0, 0x17, 0 } }, /* 05a */ + { { 0x1F, 0 }, { 0xF0, 0x1F, 0 } }, /* 05b */ + { { 0x27, 0 }, { 0xF0, 0x27, 0 } }, /* 05c */ + { { 0x2F, 0 }, { 0xF0, 0x2F, 0 } }, /* 05d */ + { { 0x37, 0 }, { 0xF0, 0x37, 0 } }, /* 05e */ + { { 0x3F, 0 }, { 0xF0, 0x3F, 0 } }, /* 05f */ + { { 0x47, 0 }, { 0xF0, 0x47, 0 } }, /* 060 */ + { { 0x4F, 0 }, { 0xF0, 0x4F, 0 } }, /* 061 */ + { { 0x56, 0 }, { 0xF0, 0x56, 0 } }, /* 062 */ + { { 0x5E, 0 }, { 0xF0, 0x5E, 0 } }, /* 063 */ + { { 0x08, 0 }, { 0xF0, 0x08, 0 } }, /* 064 */ + { { 0x10, 0 }, { 0xF0, 0x10, 0 } }, /* 065 */ + { { 0x18, 0 }, { 0xF0, 0x18, 0 } }, /* 066 */ + { { 0x20, 0 }, { 0xF0, 0x20, 0 } }, /* 067 */ + { { 0x28, 0 }, { 0xF0, 0x28, 0 } }, /* 068 */ + { { 0x30, 0 }, { 0xF0, 0x30, 0 } }, /* 069 */ + { { 0x38, 0 }, { 0xF0, 0x38, 0 } }, /* 06a */ + { { 0x40, 0 }, { 0xF0, 0x40, 0 } }, /* 06b */ + { { 0x48, 0 }, { 0xF0, 0x48, 0 } }, /* 06c */ + { { 0x50, 0 }, { 0xF0, 0x50, 0 } }, /* 06d */ + { { 0x57, 0 }, { 0xF0, 0x57, 0 } }, /* 06e */ + { { 0x6F, 0 }, { 0xF0, 0x6F, 0 } }, /* 06f */ + { { 0x13, 0 }, { 0xF0, 0x13, 0 } }, /* 070 */ + { { 0x19, 0 }, { 0xF0, 0x19, 0 } }, /* 071 */ + { { 0x39, 0 }, { 0xF0, 0x39, 0 } }, /* 072 */ + { { 0x51, 0 }, { 0xF0, 0x51, 0 } }, /* 073 */ + { { 0x53, 0 }, { 0xF0, 0x53, 0 } }, /* 074 */ + { { 0x5C, 0 }, { 0xF0, 0x5C, 0 } }, /* 075 */ + { { 0x5F, 0 }, { 0xF0, 0x5F, 0 } }, /* 076 */ + { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 077 */ + { { 0x63, 0 }, { 0xF0, 0x63, 0 } }, /* 078 */ + { { 0x64, 0 }, { 0xF0, 0x64, 0 } }, /* 079 */ + { { 0x65, 0 }, { 0xF0, 0x65, 0 } }, /* 07a */ + { { 0x67, 0 }, { 0xF0, 0x67, 0 } }, /* 07b */ + { { 0x68, 0 }, { 0xF0, 0x68, 0 } }, /* 07c */ + { { 0x6A, 0 }, { 0xF0, 0x6A, 0 } }, /* 07d */ + { { 0x6D, 0 }, { 0xF0, 0x6D, 0 } }, /* 07e */ + { { 0x6E, 0 }, { 0xF0, 0x6E, 0 } }, /* 07f */ + { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, /* 080 */ + { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 081 */ + { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, /* 085 */ + { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 086 */ + { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 087 */ + { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, /* 088 */ + { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, /* 089 */ + { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, /* 08a */ + { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 08b */ + { { 0x8c, 0 }, { 0xf0, 0x8c, 0 } }, /* 08c */ + { { 0x8d, 0 }, { 0xf0, 0x8d, 0 } }, /* 08d */ + { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, /* 08e */ + { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08f */ + { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, /* 090 */ + { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, /* 091 */ + { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, /* 092 */ + { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 093 */ + { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, /* 094 */ + { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, /* 095 */ + { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, /* 096 */ + { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 097 */ + { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, /* 098 */ + { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, /* 099 */ + { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, /* 09a */ + { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 09b */ + { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, /* 09c */ + { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, /* 09d */ + { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, /* 09e */ + { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09f */ + { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, /* 0a0 */ + { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, /* 0a1 */ + { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, /* 0a2 */ + { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a3 */ + { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, /* 0a4 */ + { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, /* 0a5 */ + { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, /* 0a6 */ + { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a7 */ + { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, /* 0a8 */ + { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, /* 0a9 */ + { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, /* 0aa */ + { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0ab */ + { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, /* 0ac */ + { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, /* 0ad */ + { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, /* 0ae */ + { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0af */ + { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, /* 0b0 */ + { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, /* 0b1 */ + { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, /* 0b2 */ + { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b3 */ + { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, /* 0b4 */ + { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, /* 0b5 */ + { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, /* 0b6 */ + { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b7 */ + { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, /* 0b8 */ + { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, /* 0b9 */ + { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, /* 0ba */ + { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0bb */ + { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, /* 0bc */ + { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, /* 0bd */ + { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, /* 0be */ + { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bf */ + { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, /* 0c0 */ + { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, /* 0c1 */ + { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, /* 0c2 */ + { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c3 */ + { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, /* 0c4 */ + { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, /* 0c5 */ + { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, /* 0c6 */ + { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c7 */ + { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, /* 0c8 */ + { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, /* 0c9 */ + { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, /* 0ca */ + { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0cb */ + { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, /* 0cc */ + { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, /* 0cd */ + { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, /* 0ce */ + { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cf */ + { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d0 */ + { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d1 */ + { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, /* 0d2 */ + { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d3 */ + { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, /* 0d4 */ + { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, /* 0d5 */ + { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, /* 0d6 */ + { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d7 */ + { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, /* 0d8 */ + { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, /* 0d9 */ + { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, /* 0da */ + { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0db */ + { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, /* 0dc */ + { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, /* 0dd */ + { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, /* 0de */ + { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0df */ + { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, /* 0e0 */ + { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, /* 0e1 */ + { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, /* 0e2 */ + { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e3 */ + { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, /* 0e4 */ + { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, /* 0e5 */ + { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, /* 0e6 */ + { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e7 */ + { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, /* 0e8 */ + { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, /* 0e9 */ + { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, /* 0ea */ + { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0eb */ + { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, /* 0ec */ + { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, /* 0ed */ + { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, /* 0ee */ + { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f3 */ + { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, /* 0f4 */ + { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, /* 0f5 */ + { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, /* 0f6 */ + { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f7 */ + { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, /* 0f8 */ + { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, /* 0f9 */ + { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, /* 0fa */ + { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0fb */ + { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, /* 0fc */ + { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, /* 0fd */ + { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, /* 0fe */ + { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0ff */ + { { 0xe1, 0x14, 0 }, { 0xe1, 0xf0, 0x14, 0 } }, /* 100 */ + { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ + { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ + { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ + { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ + { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ + { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ + { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ + { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ + { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ + { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ + { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, /* 112 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, /* 113 */ + { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ + { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ + { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ + { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ + { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ + { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ + { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ + { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ + { { 0xe0, 0x5A, 0 }, { 0xe0, 0xF0, 0x5A, 0 } }, /* 11c */ + { { 0xe0, 0x14, 0 }, { 0xe0, 0xF0, 0x14, 0 } }, /* 11d */ + { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ + { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ + { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ + { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ + { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ + { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ + { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ + { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ + { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ + { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ + { { 0xe0, 0x4A, 0 }, { 0xe0, 0xF0, 0x4A, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0xe0, 0x7C, 0 }, { 0xe0, 0xF0, 0x7C, 0 } }, /* 137 */ + { { 0xe0, 0x11, 0 }, { 0xe0, 0xF0, 0x11, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ + { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ + { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ + { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ + { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ + { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ + { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ + { { 0xe0, 0x6C, 0 }, { 0xe0, 0xF0, 0x6C, 0 } }, /* 147 */ + { { 0xe0, 0x75, 0 }, { 0xe0, 0xF0, 0x75, 0 } }, /* 148 */ + { { 0xe0, 0x7D, 0 }, { 0xe0, 0xF0, 0x7D, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0xe0, 0x6B, 0 }, { 0xe0, 0xF0, 0x6B, 0 } }, /* 14b */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ + { { 0xe0, 0x74, 0 }, { 0xe0, 0xF0, 0x74, 0 } }, /* 14d */ + { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ + { { 0xe0, 0x69, 0 }, { 0xe0, 0xF0, 0x69, 0 } }, /* 14f */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xF0, 0x72, 0 } }, /* 150 */ + { { 0xe0, 0x7A, 0 }, { 0xe0, 0xF0, 0x7A, 0 } }, /* 151 */ + { { 0xe0, 0x70, 0 }, { 0xe0, 0xF0, 0x70, 0 } }, /* 152 */ + { { 0xe0, 0x71, 0 }, { 0xe0, 0xF0, 0x71, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ + { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ + { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ + { { 0xe0, 0x1F, 0 }, { 0xe0, 0xF0, 0x1F, 0 } }, /* 15b */ + { { 0xe0, 0x27, 0 }, { 0xe0, 0xF0, 0x27, 0 } }, /* 15c */ + { { 0xe0, 0x2F, 0 }, { 0xe0, 0xF0, 0x2F, 0 } }, /* 15d */ + { { 0xe0, 0x37, 0 }, { 0xe0, 0xF0, 0x37, 0 } }, /* 15e */ + { { 0xe0, 0x3F, 0 }, { 0xe0, 0xF0, 0x3F, 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ + { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ + { { 0xe0, 0x5E, 0 }, { 0xe0, 0xF0, 0x5E, 0 } }, /* 163 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ + { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ + { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ + { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ + { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ + { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ + { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ + { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ + { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ + { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ + { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ + { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cv */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ + { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ // clang-format on }; static const scancode scancode_set3[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x08, 0 }, { 0xf0, 0x08, 0 } }, /* 000 */ - { { 0x16, 0 }, { 0xf0, 0x16, 0 } }, { { 0x1E, 0 }, { 0xf0, 0x1E, 0 } }, /* 002 */ - { { 0x26, 0 }, { 0xf0, 0x26, 0 } }, { { 0x25, 0 }, { 0xf0, 0x25, 0 } }, - { { 0x2E, 0 }, { 0xf0, 0x2E, 0 } }, { { 0x36, 0 }, { 0xf0, 0x36, 0 } }, /* 004 */ - { { 0x3D, 0 }, { 0xf0, 0x3D, 0 } }, { { 0x3E, 0 }, { 0xf0, 0x3E, 0 } }, - { { 0x46, 0 }, { 0xf0, 0x46, 0 } }, { { 0x45, 0 }, { 0xf0, 0x45, 0 } }, /* 008 */ - { { 0x4E, 0 }, { 0xf0, 0x4E, 0 } }, { { 0x55, 0 }, { 0xf0, 0x55, 0 } }, - { { 0x66, 0 }, { 0xf0, 0x66, 0 } }, { { 0x0D, 0 }, { 0xf0, 0x0D, 0 } }, /* 00c */ - { { 0x15, 0 }, { 0xf0, 0x15, 0 } }, { { 0x1D, 0 }, { 0xf0, 0x1D, 0 } }, - { { 0x24, 0 }, { 0xf0, 0x24, 0 } }, { { 0x2D, 0 }, { 0xf0, 0x2D, 0 } }, /* 010 */ - { { 0x2C, 0 }, { 0xf0, 0x2C, 0 } }, { { 0x35, 0 }, { 0xf0, 0x35, 0 } }, - { { 0x3C, 0 }, { 0xf0, 0x3C, 0 } }, { { 0x43, 0 }, { 0xf0, 0x43, 0 } }, /* 014 */ - { { 0x44, 0 }, { 0xf0, 0x44, 0 } }, { { 0x4D, 0 }, { 0xf0, 0x4D, 0 } }, - { { 0x54, 0 }, { 0xf0, 0x54, 0 } }, { { 0x5B, 0 }, { 0xf0, 0x5B, 0 } }, /* 018 */ - { { 0x5A, 0 }, { 0xf0, 0x5A, 0 } }, { { 0x11, 0 }, { 0xf0, 0x11, 0 } }, - { { 0x1C, 0 }, { 0xf0, 0x1C, 0 } }, { { 0x1B, 0 }, { 0xf0, 0x1B, 0 } }, /* 01c */ - { { 0x23, 0 }, { 0xf0, 0x23, 0 } }, { { 0x2B, 0 }, { 0xf0, 0x2B, 0 } }, - { { 0x34, 0 }, { 0xf0, 0x34, 0 } }, { { 0x33, 0 }, { 0xf0, 0x33, 0 } }, /* 020 */ - { { 0x3B, 0 }, { 0xf0, 0x3B, 0 } }, { { 0x42, 0 }, { 0xf0, 0x42, 0 } }, - { { 0x4B, 0 }, { 0xf0, 0x4B, 0 } }, { { 0x4C, 0 }, { 0xf0, 0x4C, 0 } }, /* 024 */ - { { 0x52, 0 }, { 0xf0, 0x52, 0 } }, { { 0x0E, 0 }, { 0xf0, 0x0E, 0 } }, - { { 0x12, 0 }, { 0xf0, 0x12, 0 } }, { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 028 */ - { { 0x1A, 0 }, { 0xf0, 0x1A, 0 } }, { { 0x22, 0 }, { 0xf0, 0x22, 0 } }, - { { 0x21, 0 }, { 0xf0, 0x21, 0 } }, { { 0x2A, 0 }, { 0xf0, 0x2A, 0 } }, /* 02c */ - { { 0x32, 0 }, { 0xf0, 0x32, 0 } }, { { 0x31, 0 }, { 0xf0, 0x31, 0 } }, - { { 0x3A, 0 }, { 0xf0, 0x3A, 0 } }, { { 0x41, 0 }, { 0xf0, 0x41, 0 } }, /* 030 */ - { { 0x49, 0 }, { 0xf0, 0x49, 0 } }, { { 0x4A, 0 }, { 0xf0, 0x4A, 0 } }, - { { 0x59, 0 }, { 0xf0, 0x59, 0 } }, { { 0x7E, 0 }, { 0xf0, 0x7E, 0 } }, /* 034 */ - { { 0x19, 0 }, { 0xf0, 0x19, 0 } }, { { 0x29, 0 }, { 0xf0, 0x29, 0 } }, - { { 0x14, 0 }, { 0xf0, 0x14, 0 } }, { { 0x07, 0 }, { 0xf0, 0x07, 0 } }, /* 038 */ - { { 0x0F, 0 }, { 0xf0, 0x0F, 0 } }, { { 0x17, 0 }, { 0xf0, 0x17, 0 } }, - { { 0x1F, 0 }, { 0xf0, 0x1F, 0 } }, { { 0x27, 0 }, { 0xf0, 0x27, 0 } }, /* 03c */ - { { 0x2F, 0 }, { 0xf0, 0x2F, 0 } }, { { 0x37, 0 }, { 0xf0, 0x37, 0 } }, - { { 0x3F, 0 }, { 0xf0, 0x3F, 0 } }, { { 0x47, 0 }, { 0xf0, 0x47, 0 } }, /* 040 */ - { { 0x4F, 0 }, { 0xf0, 0x4F, 0 } }, { { 0x76, 0 }, { 0xf0, 0x76, 0 } }, - { { 0x5F, 0 }, { 0xf0, 0x5F, 0 } }, { { 0x6C, 0 }, { 0xf0, 0x6C, 0 } }, /* 044 */ - { { 0x75, 0 }, { 0xf0, 0x75, 0 } }, { { 0x7D, 0 }, { 0xf0, 0x7D, 0 } }, - { { 0x84, 0 }, { 0xf0, 0x84, 0 } }, { { 0x6B, 0 }, { 0xf0, 0x6B, 0 } }, /* 048 */ - { { 0x73, 0 }, { 0xf0, 0x73, 0 } }, { { 0x74, 0 }, { 0xf0, 0x74, 0 } }, - { { 0x7C, 0 }, { 0xf0, 0x7C, 0 } }, { { 0x69, 0 }, { 0xf0, 0x69, 0 } }, /* 04c */ - { { 0x72, 0 }, { 0xf0, 0x72, 0 } }, { { 0x7A, 0 }, { 0xf0, 0x7A, 0 } }, - { { 0x70, 0 }, { 0xf0, 0x70, 0 } }, { { 0x71, 0 }, { 0xf0, 0x71, 0 } }, /* 050 */ - { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, - { { 0 }, { 0 } }, { { 0x56, 0 }, { 0xf0, 0x56, 0 } }, /* 054 */ - { { 0x5E, 0 }, { 0xf0, 0x5E, 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, { { 0x10, 0 }, { 0xf0, 0x10, 0 } }, - { { 0x18, 0 }, { 0xf0, 0x18, 0 } }, { { 0x20, 0 }, { 0xf0, 0x20, 0 } }, /* 064 */ - { { 0x28, 0 }, { 0xf0, 0x28, 0 } }, { { 0x30, 0 }, { 0xf0, 0x30, 0 } }, - { { 0x38, 0 }, { 0xf0, 0x38, 0 } }, { { 0x40, 0 }, { 0xf0, 0x40, 0 } }, /* 068 */ - { { 0x48, 0 }, { 0xf0, 0x48, 0 } }, { { 0x50, 0 }, { 0xf0, 0x50, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ - { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0x51, 0 }, { 0xf0, 0x51, 0 } }, /* 070 */ - { { 0x53, 0 }, { 0xf0, 0x53, 0 } }, { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, - { { 0 }, { 0 } }, { { 0x62, 0 }, { 0xf0, 0x62, 0 } }, /* 074 */ - { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, - { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x85, 0 } }, /* 078 */ - { { 0x68, 0 }, { 0xf0, 0x68, 0 } }, { { 0x13, 0 }, { 0xf0, 0x13, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - - { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 080 */ - { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, - { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 084 */ - { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, - { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 088 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08c */ - { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, - { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 090 */ - { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, - { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 094 */ - { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, - { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 098 */ - { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, - { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09c */ - { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, - { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a0 */ - { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, - { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a4 */ - { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, - { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0a8 */ - { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, - { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0ac */ - { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, - { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b0 */ - { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, - { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b4 */ - { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, - { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0b8 */ - { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, - { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bc */ - { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, - { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c0 */ - { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, - { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c4 */ - { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, - { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0c8 */ - { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, - { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cc */ - { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, - { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d0 */ - { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, - { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d4 */ - { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, - { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0d8 */ - { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, - { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0dc */ - { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, - { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e0 */ - { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, - { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e4 */ - { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, - { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0e8 */ - { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, - { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, - { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f0 */ - { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, - { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f4 */ - { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, - { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0f8 */ - { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, - { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0fc */ - - { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 100 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 102 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, - { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 104 */ - { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, - { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 108 */ - { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10c */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, - { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 110 */ - { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, - { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 114 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, - { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 118 */ - { { 0x79, 0 }, { 0xf0, 0x79, 0 } }, { { 0x58, 0 }, { 0xf0, 0x58, 0 } }, - { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11c */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, - { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 120 */ - { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, - { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, - { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12c */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, - { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, { { 0x77, 0 }, { 0xf0, 0x77, 0 } }, - { { 0 }, { 0 } }, { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 134 */ - { { 0x39, 0 }, { 0xf0, 0x39, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 138 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, - { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13c */ - { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, - { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 140 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, { { 0x6E, 0 }, { 0xf0, 0x6E, 0 } }, /* 144 */ - { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, { { 0x6F, 0 }, { 0xf0, 0x6F, 0 } }, - { { 0 }, { 0 } }, { { 0x61, 0 }, { 0xf0, 0x61, 0 } }, /* 148 */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, { { 0x6A, 0 }, { 0xf0, 0x6A, 0 } }, - { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, { { 0x65, 0 }, { 0xf0, 0x65, 0 } }, /* 14c */ - { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, { { 0x6D, 0 }, { 0xf0, 0x6D, 0 } }, - { { 0x67, 0 }, { 0xf0, 0x67, 0 } }, { { 0x64, 0 }, { 0xf0, 0x64, 0 } }, /* 150 */ - { { 0xd4, 0 }, { 0xf0, 0xD4, 0 } }, { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 154 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, - { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, { { 0x8B, 0 }, { 0xf0, 0x8B, 0 } }, /* 158 */ - { { 0x8C, 0 }, { 0xf0, 0x8C, 0 } }, { { 0x8D, 0 }, { 0xf0, 0x8D, 0 } }, - { { 0 }, { 0 } }, { { 0x7F, 0 }, { 0xf0, 0x7F, 0 } }, /* 15c */ - { { 0 }, { 0 } }, { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, - { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, { { 0 }, { 0 } }, /* 160 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, - { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 164 */ - { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, - { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 168 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, - { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, - { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 170 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, - { { 0 }, { 0 } }, { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 174 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, - { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 178 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, - { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17c */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, - { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1fc */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x08, 0 }, { 0xf0, 0x08, 0 } }, /* 001 */ + { { 0x16, 0 }, { 0xf0, 0x16, 0 } }, /* 002 */ + { { 0x1E, 0 }, { 0xf0, 0x1E, 0 } }, /* 003 */ + { { 0x26, 0 }, { 0xf0, 0x26, 0 } }, /* 004 */ + { { 0x25, 0 }, { 0xf0, 0x25, 0 } }, /* 005 */ + { { 0x2E, 0 }, { 0xf0, 0x2E, 0 } }, /* 006 */ + { { 0x36, 0 }, { 0xf0, 0x36, 0 } }, /* 007 */ + { { 0x3D, 0 }, { 0xf0, 0x3D, 0 } }, /* 008 */ + { { 0x3E, 0 }, { 0xf0, 0x3E, 0 } }, /* 009 */ + { { 0x46, 0 }, { 0xf0, 0x46, 0 } }, /* 00a */ + { { 0x45, 0 }, { 0xf0, 0x45, 0 } }, /* 00b */ + { { 0x4E, 0 }, { 0xf0, 0x4E, 0 } }, /* 00c */ + { { 0x55, 0 }, { 0xf0, 0x55, 0 } }, /* 00d */ + { { 0x66, 0 }, { 0xf0, 0x66, 0 } }, /* 00e */ + { { 0x0D, 0 }, { 0xf0, 0x0D, 0 } }, /* 00f */ + { { 0x15, 0 }, { 0xf0, 0x15, 0 } }, /* 010 */ + { { 0x1D, 0 }, { 0xf0, 0x1D, 0 } }, /* 011 */ + { { 0x24, 0 }, { 0xf0, 0x24, 0 } }, /* 012 */ + { { 0x2D, 0 }, { 0xf0, 0x2D, 0 } }, /* 013 */ + { { 0x2C, 0 }, { 0xf0, 0x2C, 0 } }, /* 014 */ + { { 0x35, 0 }, { 0xf0, 0x35, 0 } }, /* 015 */ + { { 0x3C, 0 }, { 0xf0, 0x3C, 0 } }, /* 016 */ + { { 0x43, 0 }, { 0xf0, 0x43, 0 } }, /* 017 */ + { { 0x44, 0 }, { 0xf0, 0x44, 0 } }, /* 018 */ + { { 0x4D, 0 }, { 0xf0, 0x4D, 0 } }, /* 019 */ + { { 0x54, 0 }, { 0xf0, 0x54, 0 } }, /* 01a */ + { { 0x5B, 0 }, { 0xf0, 0x5B, 0 } }, /* 01b */ + { { 0x5A, 0 }, { 0xf0, 0x5A, 0 } }, /* 01c */ + { { 0x11, 0 }, { 0xf0, 0x11, 0 } }, /* 01d */ + { { 0x1C, 0 }, { 0xf0, 0x1C, 0 } }, /* 01e */ + { { 0x1B, 0 }, { 0xf0, 0x1B, 0 } }, /* 01f */ + { { 0x23, 0 }, { 0xf0, 0x23, 0 } }, /* 020 */ + { { 0x2B, 0 }, { 0xf0, 0x2B, 0 } }, /* 021 */ + { { 0x34, 0 }, { 0xf0, 0x34, 0 } }, /* 022 */ + { { 0x33, 0 }, { 0xf0, 0x33, 0 } }, /* 023 */ + { { 0x3B, 0 }, { 0xf0, 0x3B, 0 } }, /* 024 */ + { { 0x42, 0 }, { 0xf0, 0x42, 0 } }, /* 025 */ + { { 0x4B, 0 }, { 0xf0, 0x4B, 0 } }, /* 026 */ + { { 0x4C, 0 }, { 0xf0, 0x4C, 0 } }, /* 027 */ + { { 0x52, 0 }, { 0xf0, 0x52, 0 } }, /* 028 */ + { { 0x0E, 0 }, { 0xf0, 0x0E, 0 } }, /* 029 */ + { { 0x12, 0 }, { 0xf0, 0x12, 0 } }, /* 02a */ + { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 02b */ + { { 0x1A, 0 }, { 0xf0, 0x1A, 0 } }, /* 02c */ + { { 0x22, 0 }, { 0xf0, 0x22, 0 } }, /* 02d */ + { { 0x21, 0 }, { 0xf0, 0x21, 0 } }, /* 02e */ + { { 0x2A, 0 }, { 0xf0, 0x2A, 0 } }, /* 02f */ + { { 0x32, 0 }, { 0xf0, 0x32, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xf0, 0x31, 0 } }, /* 031 */ + { { 0x3A, 0 }, { 0xf0, 0x3A, 0 } }, /* 032 */ + { { 0x41, 0 }, { 0xf0, 0x41, 0 } }, /* 033 */ + { { 0x49, 0 }, { 0xf0, 0x49, 0 } }, /* 034 */ + { { 0x4A, 0 }, { 0xf0, 0x4A, 0 } }, /* 035 */ + { { 0x59, 0 }, { 0xf0, 0x59, 0 } }, /* 036 */ + { { 0x7E, 0 }, { 0xf0, 0x7E, 0 } }, /* 037 */ + { { 0x19, 0 }, { 0xf0, 0x19, 0 } }, /* 038 */ + { { 0x29, 0 }, { 0xf0, 0x29, 0 } }, /* 039 */ + { { 0x14, 0 }, { 0xf0, 0x14, 0 } }, /* 03a */ + { { 0x07, 0 }, { 0xf0, 0x07, 0 } }, /* 03b */ + { { 0x0F, 0 }, { 0xf0, 0x0F, 0 } }, /* 03c */ + { { 0x17, 0 }, { 0xf0, 0x17, 0 } }, /* 03d */ + { { 0x1F, 0 }, { 0xf0, 0x1F, 0 } }, /* 03e */ + { { 0x27, 0 }, { 0xf0, 0x27, 0 } }, /* 03f */ + { { 0x2F, 0 }, { 0xf0, 0x2F, 0 } }, /* 040 */ + { { 0x37, 0 }, { 0xf0, 0x37, 0 } }, /* 041 */ + { { 0x3F, 0 }, { 0xf0, 0x3F, 0 } }, /* 042 */ + { { 0x47, 0 }, { 0xf0, 0x47, 0 } }, /* 043 */ + { { 0x4F, 0 }, { 0xf0, 0x4F, 0 } }, /* 044 */ + { { 0x76, 0 }, { 0xf0, 0x76, 0 } }, /* 045 */ + { { 0x5F, 0 }, { 0xf0, 0x5F, 0 } }, /* 046 */ + { { 0x6C, 0 }, { 0xf0, 0x6C, 0 } }, /* 047 */ + { { 0x75, 0 }, { 0xf0, 0x75, 0 } }, /* 048 */ + { { 0x7D, 0 }, { 0xf0, 0x7D, 0 } }, /* 049 */ + { { 0x84, 0 }, { 0xf0, 0x84, 0 } }, /* 04a */ + { { 0x6B, 0 }, { 0xf0, 0x6B, 0 } }, /* 04b */ + { { 0x73, 0 }, { 0xf0, 0x73, 0 } }, /* 04c */ + { { 0x74, 0 }, { 0xf0, 0x74, 0 } }, /* 04d */ + { { 0x7C, 0 }, { 0xf0, 0x7C, 0 } }, /* 04e */ + { { 0x69, 0 }, { 0xf0, 0x69, 0 } }, /* 04f */ + { { 0x72, 0 }, { 0xf0, 0x72, 0 } }, /* 050 */ + { { 0x7A, 0 }, { 0xf0, 0x7A, 0 } }, /* 051 */ + { { 0x70, 0 }, { 0xf0, 0x70, 0 } }, /* 052 */ + { { 0x71, 0 }, { 0xf0, 0x71, 0 } }, /* 053 */ + { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 054 */ + { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, /* 055 */ + { { 0 }, { 0 } }, /* 056 */ + { { 0x56, 0 }, { 0xf0, 0x56, 0 } }, /* 057 */ + { { 0x5E, 0 }, { 0xf0, 0x5E, 0 } }, /* 058 */ + { { 0 }, { 0 } }, /* 059 */ + { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, /* 05b */ + { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, /* 05d */ + { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, /* 05f */ + { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, /* 061 */ + { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, /* 063 */ + { { 0 }, { 0 } }, /* 064 */ + { { 0x10, 0 }, { 0xf0, 0x10, 0 } }, /* 065 */ + { { 0x18, 0 }, { 0xf0, 0x18, 0 } }, /* 066 */ + { { 0x20, 0 }, { 0xf0, 0x20, 0 } }, /* 067 */ + { { 0x28, 0 }, { 0xf0, 0x28, 0 } }, /* 068 */ + { { 0x30, 0 }, { 0xf0, 0x30, 0 } }, /* 069 */ + { { 0x38, 0 }, { 0xf0, 0x38, 0 } }, /* 06a */ + { { 0x40, 0 }, { 0xf0, 0x40, 0 } }, /* 06b */ + { { 0x48, 0 }, { 0xf0, 0x48, 0 } }, /* 06c */ + { { 0x50, 0 }, { 0xf0, 0x50, 0 } }, /* 06d */ + { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, /* 06f */ + { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 070 */ + { { 0 }, { 0 } }, /* 071 */ + { { 0 }, { 0 } }, /* 072 */ + { { 0x51, 0 }, { 0xf0, 0x51, 0 } }, /* 073 */ + { { 0x53, 0 }, { 0xf0, 0x53, 0 } }, /* 074 */ + { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 075 */ + { { 0 }, { 0 } }, /* 076 */ + { { 0x62, 0 }, { 0xf0, 0x62, 0 } }, /* 077 */ + { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, /* 078 */ + { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 079 */ + { { 0 }, { 0 } }, /* 07a */ + { { 0x85, 0 }, { 0xf0, 0x85, 0 } }, /* 07b */ + { { 0x68, 0 }, { 0xf0, 0x68, 0 } }, /* 07c */ + { { 0x13, 0 }, { 0xf0, 0x13, 0 } }, /* 07d */ + { { 0 }, { 0 } }, /* 07e */ + { { 0 }, { 0 } }, /* 07f */ + { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, /* 080 */ + { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 081 */ + { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, /* 085 */ + { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 086 */ + { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 087 */ + { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, /* 087 */ + { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, /* 088 */ + { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, /* 089 */ + { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 08b */ + { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, /* 08d */ + { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, /* 08e */ + { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08f */ + { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, /* 090 */ + { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, /* 091 */ + { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, /* 092 */ + { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 093 */ + { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, /* 094 */ + { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, /* 095 */ + { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, /* 096 */ + { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 097 */ + { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, /* 098 */ + { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, /* 099 */ + { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, /* 09a */ + { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 09b */ + { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, /* 09c */ + { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, /* 09d */ + { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, /* 09e */ + { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09f */ + { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, /* 0a0 */ + { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, /* 0a1 */ + { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, /* 0a2 */ + { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a3 */ + { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, /* 0a4 */ + { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, /* 0a5 */ + { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, /* 0a6 */ + { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a7 */ + { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, /* 0a8 */ + { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, /* 0a9 */ + { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, /* 0aa */ + { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0ab */ + { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, /* 0ac */ + { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, /* 0ad */ + { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, /* 0ae */ + { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0af */ + { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, /* 0b0 */ + { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, /* 0b1 */ + { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, /* 0b2 */ + { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b3 */ + { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, /* 0b4 */ + { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, /* 0b5 */ + { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, /* 0b6 */ + { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b7 */ + { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, /* 0b8 */ + { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, /* 0b9 */ + { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, /* 0ba */ + { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0bb */ + { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, /* 0bc */ + { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, /* 0bd */ + { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, /* 0be */ + { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bf */ + { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, /* 0c0 */ + { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, /* 0c1 */ + { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, /* 0c2 */ + { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c3 */ + { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, /* 0c4 */ + { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, /* 0c5 */ + { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, /* 0c6 */ + { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c7 */ + { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, /* 0c8 */ + { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, /* 0c9 */ + { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, /* 0ca */ + { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0cb */ + { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, /* 0cc */ + { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, /* 0cd */ + { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, /* 0ce */ + { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cf */ + { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d0 */ + { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d1 */ + { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, /* 0d2 */ + { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d3 */ + { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, /* 0d4 */ + { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, /* 0d5 */ + { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, /* 0d6 */ + { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d7 */ + { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, /* 0d8 */ + { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, /* 0d9 */ + { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, /* 0da */ + { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0db */ + { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, /* 0dc */ + { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, /* 0dd */ + { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, /* 0de */ + { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0df */ + { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, /* 0e0 */ + { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, /* 0e1 */ + { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, /* 0e2 */ + { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e3 */ + { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, /* 0e4 */ + { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, /* 0e5 */ + { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, /* 0e6 */ + { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e7 */ + { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, /* 0e7 */ + { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, /* 0e8 */ + { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, /* 0e9 */ + { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0eb */ + { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, /* 0ec */ + { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, /* 0ed */ + { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, /* 0ee */ + { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f3 */ + { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, /* 0f4 */ + { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, /* 0f5 */ + { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, /* 0f6 */ + { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f7 */ + { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, /* 0f8 */ + { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, /* 0f9 */ + { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, /* 0fa */ + { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0fb */ + { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, /* 0fc */ + { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, /* 0fd */ + { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, /* 0fe */ + { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0ff */ + { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 100 */ + { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ + { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ + { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ + { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ + { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ + { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ + { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ + { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ + { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ + { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ + { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, /* 111 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, /* 112 */ + { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ + { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ + { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ + { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ + { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ + { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ + { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ + { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ + { { 0x79, 0 }, { 0xf0, 0x79, 0 } }, /* 11c */ + { { 0x58, 0 }, { 0xf0, 0x58, 0 } }, /* 11d */ + { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ + { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ + { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ + { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ + { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ + { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ + { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ + { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ + { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ + { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ + { { 0x77, 0 }, { 0xf0, 0x77, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 137 */ + { { 0x39, 0 }, { 0xf0, 0x39, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ + { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ + { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ + { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ + { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ + { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ + { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ + { { 0x6E, 0 }, { 0xf0, 0x6E, 0 } }, /* 147 */ + { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, /* 148 */ + { { 0x6F, 0 }, { 0xf0, 0x6F, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0x61, 0 }, { 0xf0, 0x61, 0 } }, /* 14b */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ + { { 0x6A, 0 }, { 0xf0, 0x6A, 0 } }, /* 14d */ + { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ + { { 0x65, 0 }, { 0xf0, 0x65, 0 } }, /* 14f */ + { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, /* 150 */ + { { 0x6D, 0 }, { 0xf0, 0x6D, 0 } }, /* 151 */ + { { 0x67, 0 }, { 0xf0, 0x67, 0 } }, /* 152 */ + { { 0x64, 0 }, { 0xf0, 0x64, 0 } }, /* 153 */ + { { 0xd4, 0 }, { 0xf0, 0xD4, 0 } }, /* 154 */ + { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ + { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ + { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ + { { 0x8B, 0 }, { 0xf0, 0x8B, 0 } }, /* 15b */ + { { 0x8C, 0 }, { 0xf0, 0x8C, 0 } }, /* 15c */ + { { 0x8D, 0 }, { 0xf0, 0x8D, 0 } }, /* 15d */ + { { 0 }, { 0 } }, /* 15e */ + { { 0x7F, 0 }, { 0xf0, 0x7F, 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ + { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ + { { 0 }, { 0 } }, /* 163 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ + { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ + { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ + { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ + { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ + { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ + { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ + { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ + { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ + { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ + { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ + { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ + { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ // clang-format on }; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index c2404231f..ea2564aa9 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -90,265 +90,518 @@ typedef struct xtkbd_t { /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ const scancode scancode_xt[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14a */ - { { 0 }, { 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14c */ - { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ + { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, /* 055 */ + { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, /* 057 */ + { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, /* 059 */ + { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, /* 05b */ + { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, /* 05d */ + { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, /* 05f */ + { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, /* 061 */ + { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, /* 063 */ + { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, /* 065 */ + { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, /* 067 */ + { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, /* 069 */ + { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, /* 06b */ + { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, /* 06d */ + { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, /* 06f */ + { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, /* 071 */ + { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, /* 073 */ + { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, /* 075 */ + { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, /* 077 */ + { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, /* 079 */ + { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, /* 07b */ + { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, /* 07d */ + { { 0 }, { 0 } }, /* 07e */ + { { 0 }, { 0 } }, /* 07f */ + { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, /* 081 */ + { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, /* 085 */ + { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, /* 087 */ + { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, /* 089 */ + { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, /* 08b */ + { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, /* 08d */ + { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, /* 08f */ + { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, /* 091 */ + { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, /* 093 */ + { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, /* 095 */ + { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, /* 097 */ + { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, /* 099 */ + { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, /* 09b */ + { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, /* 09d */ + { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, /* 09f */ + { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, /* 0a1 */ + { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, /* 0a3 */ + { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, /* 0a5 */ + { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, /* 0a7 */ + { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, /* 0a9 */ + { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, /* 0ab */ + { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, /* 0ad */ + { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, /* 0af */ + { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, /* 0b1 */ + { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, /* 0b3 */ + { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, /* 0b5 */ + { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, /* 0b7 */ + { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, /* 0b9 */ + { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, /* 0bb */ + { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, /* 0bd */ + { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, /* 0bf */ + { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, /* 0c1 */ + { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, /* 0c3 */ + { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, /* 0c5 */ + { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, /* 0c7 */ + { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, /* 0c9 */ + { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, /* 0cb */ + { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, /* 0cd */ + { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, /* 0cf */ + { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, /* 0d1 */ + { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, /* 0d3 */ + { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, /* 0d5 */ + { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, /* 0d7 */ + { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, /* 0d9 */ + { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, /* 0db */ + { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, /* 0dd */ + { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, /* 0df */ + { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, /* 0e1 */ + { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, /* 0e3 */ + { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, /* 0e5 */ + { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, /* 0e7 */ + { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, /* 0e9 */ + { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, /* 0eb */ + { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, /* 0ed */ + { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, /* 0f1 */ + { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, /* 0f3 */ + { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, /* 0f5 */ + { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, /* 0f7 */ + { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, /* 0f9 */ + { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, /* 0fb */ + { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, /* 0fd */ + { { 0 }, { 0 } }, /* 0fe */ + { { 0 }, { 0 } }, /* 0ff */ + { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, /* 101 */ + { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, /* 103 */ + { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, /* 105 */ + { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, /* 107 */ + { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, /* 109 */ + { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, /* 10b */ + { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, /* 10f */ + { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, /* 111 */ + { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, /* 113 */ + { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, /* 115 */ + { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, /* 117 */ + { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, /* 119 */ + { { 0 }, { 0 } }, /* 11a */ + { { 0 }, { 0 } }, /* 11b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 11c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11d */ + { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, /* 11f */ + { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, /* 121 */ + { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, /* 123 */ + { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, /* 125 */ + { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, /* 12d */ + { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, /* 12f */ + { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, /* 131 */ + { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0 }, { 0 } }, /* 134 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, /* 13b */ + { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, /* 13d */ + { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, /* 13f */ + { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, /* 141 */ + { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, /* 143 */ + { { 0 }, { 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 148 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14b */ + { { 0 }, { 0 } }, /* 14c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14d */ + { { 0 }, { 0 } }, /* 14e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 150 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, /* 157 */ + { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, /* 159 */ + { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, /* 15b */ + { { 0 }, { 0 } }, /* 15c */ + { { 0 }, { 0 } }, /* 15d */ + { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, /* 161 */ + { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, /* 163 */ + { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, /* 165 */ + { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, /* 167 */ + { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, /* 169 */ + { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, /* 16b */ + { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, /* 16d */ + { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, /* 171 */ + { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, /* 173 */ + { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, /* 177 */ + { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, /* 179 */ + { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, /* 17b */ + { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, /* 17d */ + { { 0 }, { 0 } }, /* 17e */ + { { 0 }, { 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0 }, { 0 } }, /* 1fe */ + { { 0 }, { 0 } } /* 1ff */ // clang-format on }; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 772a3a261..ff99c94da 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2350,257 +2350,502 @@ ams_read(uint16_t port, void *priv) static const scancode scancode_pc200[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ - { { 0x54, 0 }, { 0xd4, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 054 */ - { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x57, 0 }, { 0xd7, 0 } }, /* 056 */ - { { 0x58, 0 }, { 0xd8, 0 } }, { { 0x59, 0 }, { 0xd9, 0 } }, /* 058 */ - { { 0x5a, 0 }, { 0xda, 0 } }, { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05a */ - { { 0x5c, 0 }, { 0xdc, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05c */ - { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05e */ - { { 0x60, 0 }, { 0xe0, 0 } }, { { 0x61, 0 }, { 0xe1, 0 } }, /* 060 */ - { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 062 */ - { { 0x64, 0 }, { 0xe4, 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 064 */ - { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x67, 0 }, { 0xe7, 0 } }, /* 066 */ - { { 0x68, 0 }, { 0xe8, 0 } }, { { 0x69, 0 }, { 0xe9, 0 } }, /* 068 */ - { { 0x6a, 0 }, { 0xea, 0 } }, { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06a */ - { { 0x6c, 0 }, { 0xec, 0 } }, { { 0x6d, 0 }, { 0xed, 0 } }, /* 06c */ - { { 0x6e, 0 }, { 0xee, 0 } }, { { 0x6f, 0 }, { 0xef, 0 } }, /* 06e */ - { { 0x70, 0 }, { 0xf0, 0 } }, { { 0x71, 0 }, { 0xf1, 0 } }, /* 070 */ - { { 0x72, 0 }, { 0xf2, 0 } }, { { 0x73, 0 }, { 0xf3, 0 } }, /* 072 */ - { { 0x74, 0 }, { 0xf4, 0 } }, { { 0x75, 0 }, { 0xf5, 0 } }, /* 074 */ - { { 0x76, 0 }, { 0xf6, 0 } }, { { 0x77, 0 }, { 0xf7, 0 } }, /* 076 */ - { { 0x78, 0 }, { 0xf8, 0 } }, { { 0x79, 0 }, { 0xf9, 0 } }, /* 078 */ - { { 0x7a, 0 }, { 0xfa, 0 } }, { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07a */ - { { 0x7c, 0 }, { 0xfc, 0 } }, { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07c */ - { { 0x7e, 0 }, { 0xfe, 0 } }, { { 0x7f, 0 }, { 0xff, 0 } }, /* 07e */ - - { { 0x80, 0 }, { 0 } }, { { 0x81, 0 }, { 0 } }, /* 080 */ - { { 0x82, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0x85, 0 }, { 0 } }, /* 084 */ - { { 0x86, 0 }, { 0 } }, { { 0x87, 0 }, { 0 } }, /* 086 */ - { { 0x88, 0 }, { 0 } }, { { 0x89, 0 }, { 0 } }, /* 088 */ - { { 0x8a, 0 }, { 0 } }, { { 0x8b, 0 }, { 0 } }, /* 08a */ - { { 0x8c, 0 }, { 0 } }, { { 0x8d, 0 }, { 0 } }, /* 08c */ - { { 0x8e, 0 }, { 0 } }, { { 0x8f, 0 }, { 0 } }, /* 08e */ - { { 0x90, 0 }, { 0 } }, { { 0x91, 0 }, { 0 } }, /* 090 */ - { { 0x92, 0 }, { 0 } }, { { 0x93, 0 }, { 0 } }, /* 092 */ - { { 0x94, 0 }, { 0 } }, { { 0x95, 0 }, { 0 } }, /* 094 */ - { { 0x96, 0 }, { 0 } }, { { 0x97, 0 }, { 0 } }, /* 096 */ - { { 0x98, 0 }, { 0 } }, { { 0x99, 0 }, { 0 } }, /* 098 */ - { { 0x9a, 0 }, { 0 } }, { { 0x9b, 0 }, { 0 } }, /* 09a */ - { { 0x9c, 0 }, { 0 } }, { { 0x9d, 0 }, { 0 } }, /* 09c */ - { { 0x9e, 0 }, { 0 } }, { { 0x9f, 0 }, { 0 } }, /* 09e */ - { { 0xa0, 0 }, { 0 } }, { { 0xa1, 0 }, { 0 } }, /* 0a0 */ - { { 0xa2, 0 }, { 0 } }, { { 0xa3, 0 }, { 0 } }, /* 0a2 */ - { { 0xa4, 0 }, { 0 } }, { { 0xa5, 0 }, { 0 } }, /* 0a4 */ - { { 0xa6, 0 }, { 0 } }, { { 0xa7, 0 }, { 0 } }, /* 0a6 */ - { { 0xa8, 0 }, { 0 } }, { { 0xa9, 0 }, { 0 } }, /* 0a8 */ - { { 0xaa, 0 }, { 0 } }, { { 0xab, 0 }, { 0 } }, /* 0aa */ - { { 0xac, 0 }, { 0 } }, { { 0xad, 0 }, { 0 } }, /* 0ac */ - { { 0xae, 0 }, { 0 } }, { { 0xaf, 0 }, { 0 } }, /* 0ae */ - { { 0xb0, 0 }, { 0 } }, { { 0xb1, 0 }, { 0 } }, /* 0b0 */ - { { 0xb2, 0 }, { 0 } }, { { 0xb3, 0 }, { 0 } }, /* 0b2 */ - { { 0xb4, 0 }, { 0 } }, { { 0xb5, 0 }, { 0 } }, /* 0b4 */ - { { 0xb6, 0 }, { 0 } }, { { 0xb7, 0 }, { 0 } }, /* 0b6 */ - { { 0xb8, 0 }, { 0 } }, { { 0xb9, 0 }, { 0 } }, /* 0b8 */ - { { 0xba, 0 }, { 0 } }, { { 0xbb, 0 }, { 0 } }, /* 0ba */ - { { 0xbc, 0 }, { 0 } }, { { 0xbd, 0 }, { 0 } }, /* 0bc */ - { { 0xbe, 0 }, { 0 } }, { { 0xbf, 0 }, { 0 } }, /* 0be */ - { { 0xc0, 0 }, { 0 } }, { { 0xc1, 0 }, { 0 } }, /* 0c0 */ - { { 0xc2, 0 }, { 0 } }, { { 0xc3, 0 }, { 0 } }, /* 0c2 */ - { { 0xc4, 0 }, { 0 } }, { { 0xc5, 0 }, { 0 } }, /* 0c4 */ - { { 0xc6, 0 }, { 0 } }, { { 0xc7, 0 }, { 0 } }, /* 0c6 */ - { { 0xc8, 0 }, { 0 } }, { { 0xc9, 0 }, { 0 } }, /* 0c8 */ - { { 0xca, 0 }, { 0 } }, { { 0xcb, 0 }, { 0 } }, /* 0ca */ - { { 0xcc, 0 }, { 0 } }, { { 0xcd, 0 }, { 0 } }, /* 0cc */ - { { 0xce, 0 }, { 0 } }, { { 0xcf, 0 }, { 0 } }, /* 0ce */ - { { 0xd0, 0 }, { 0 } }, { { 0xd1, 0 }, { 0 } }, /* 0d0 */ - { { 0xd2, 0 }, { 0 } }, { { 0xd3, 0 }, { 0 } }, /* 0d2 */ - { { 0xd4, 0 }, { 0 } }, { { 0xd5, 0 }, { 0 } }, /* 0d4 */ - { { 0xd6, 0 }, { 0 } }, { { 0xd7, 0 }, { 0 } }, /* 0d6 */ - { { 0xd8, 0 }, { 0 } }, { { 0xd9, 0 }, { 0 } }, /* 0d8 */ - { { 0xda, 0 }, { 0 } }, { { 0xdb, 0 }, { 0 } }, /* 0da */ - { { 0xdc, 0 }, { 0 } }, { { 0xdd, 0 }, { 0 } }, /* 0dc */ - { { 0xde, 0 }, { 0 } }, { { 0xdf, 0 }, { 0 } }, /* 0de */ - { { 0xe0, 0 }, { 0 } }, { { 0xe1, 0 }, { 0 } }, /* 0e0 */ - { { 0xe2, 0 }, { 0 } }, { { 0xe3, 0 }, { 0 } }, /* 0e2 */ - { { 0xe4, 0 }, { 0 } }, { { 0xe5, 0 }, { 0 } }, /* 0e4 */ - { { 0xe6, 0 }, { 0 } }, { { 0xe7, 0 }, { 0 } }, /* 0e6 */ - { { 0xe8, 0 }, { 0 } }, { { 0xe9, 0 }, { 0 } }, /* 0e8 */ - { { 0xea, 0 }, { 0 } }, { { 0xeb, 0 }, { 0 } }, /* 0ea */ - { { 0xec, 0 }, { 0 } }, { { 0xed, 0 }, { 0 } }, /* 0ec */ - { { 0xee, 0 }, { 0 } }, { { 0xef, 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0xf1, 0 }, { 0 } }, /* 0f0 */ - { { 0xf2, 0 }, { 0 } }, { { 0xf3, 0 }, { 0 } }, /* 0f2 */ - { { 0xf4, 0 }, { 0 } }, { { 0xf5, 0 }, { 0 } }, /* 0f4 */ - { { 0xf6, 0 }, { 0 } }, { { 0xf7, 0 }, { 0 } }, /* 0f6 */ - { { 0xf8, 0 }, { 0 } }, { { 0xf9, 0 }, { 0 } }, /* 0f8 */ - { { 0xfa, 0 }, { 0 } }, { { 0xfb, 0 }, { 0 } }, /* 0fa */ - { { 0xfc, 0 }, { 0 } }, { { 0xfd, 0 }, { 0 } }, /* 0fc */ - { { 0xfe, 0 }, { 0 } }, { { 0xff, 0 }, { 0 } }, /* 0fe */ - - { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 100 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 102 */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 104 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 106 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 108 */ - { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10a */ - { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10e */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 110 */ - { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 112 */ - { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 114 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 116 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 118 */ - { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11a */ - { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11c */ - { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11e */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 120 */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 122 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 124 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12c */ - { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12e */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 130 */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 136 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ - { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13a */ - { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13c */ - { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13e */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 140 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 142 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 146 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14a */ - { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14c */ - { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14e */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 150 */ - { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 156 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 158 */ - { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15a */ - { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15c */ - { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 160 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 162 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 164 */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 166 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 168 */ - { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16a */ - { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16c */ - { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 170 */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 172 */ - { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 176 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 178 */ - { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17a */ - { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17c */ - { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0xe0, 0xee, 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0xe0, 0xfe, 0 }, { 0 } }, { { 0xe0, 0xff, 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ + { { 0x54, 0 }, { 0xd4, 0 } }, /* 054 */ + { { 0x55, 0 }, { 0xd5, 0 } }, /* 055 */ + { { 0x56, 0 }, { 0xd6, 0 } }, /* 056 */ + { { 0x57, 0 }, { 0xd7, 0 } }, /* 057 */ + { { 0x58, 0 }, { 0xd8, 0 } }, /* 058 */ + { { 0x59, 0 }, { 0xd9, 0 } }, /* 059 */ + { { 0x5a, 0 }, { 0xda, 0 } }, /* 05a */ + { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05b */ + { { 0x5c, 0 }, { 0xdc, 0 } }, /* 05c */ + { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05d */ + { { 0x5e, 0 }, { 0xde, 0 } }, /* 05e */ + { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05f */ + { { 0x60, 0 }, { 0xe0, 0 } }, /* 060 */ + { { 0x61, 0 }, { 0xe1, 0 } }, /* 061 */ + { { 0x62, 0 }, { 0xe2, 0 } }, /* 062 */ + { { 0x63, 0 }, { 0xe3, 0 } }, /* 063 */ + { { 0x64, 0 }, { 0xe4, 0 } }, /* 064 */ + { { 0x65, 0 }, { 0xe5, 0 } }, /* 065 */ + { { 0x66, 0 }, { 0xe6, 0 } }, /* 066 */ + { { 0x67, 0 }, { 0xe7, 0 } }, /* 067 */ + { { 0x68, 0 }, { 0xe8, 0 } }, /* 068 */ + { { 0x69, 0 }, { 0xe9, 0 } }, /* 069 */ + { { 0x6a, 0 }, { 0xea, 0 } }, /* 06a */ + { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06b */ + { { 0x6c, 0 }, { 0xec, 0 } }, /* 06c */ + { { 0x6d, 0 }, { 0xed, 0 } }, /* 06d */ + { { 0x6e, 0 }, { 0xee, 0 } }, /* 06e */ + { { 0x6f, 0 }, { 0xef, 0 } }, /* 06f */ + { { 0x70, 0 }, { 0xf0, 0 } }, /* 070 */ + { { 0x71, 0 }, { 0xf1, 0 } }, /* 071 */ + { { 0x72, 0 }, { 0xf2, 0 } }, /* 072 */ + { { 0x73, 0 }, { 0xf3, 0 } }, /* 073 */ + { { 0x74, 0 }, { 0xf4, 0 } }, /* 074 */ + { { 0x75, 0 }, { 0xf5, 0 } }, /* 075 */ + { { 0x76, 0 }, { 0xf6, 0 } }, /* 076 */ + { { 0x77, 0 }, { 0xf7, 0 } }, /* 077 */ + { { 0x78, 0 }, { 0xf8, 0 } }, /* 078 */ + { { 0x79, 0 }, { 0xf9, 0 } }, /* 079 */ + { { 0x7a, 0 }, { 0xfa, 0 } }, /* 07a */ + { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07b */ + { { 0x7c, 0 }, { 0xfc, 0 } }, /* 07c */ + { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07d */ + { { 0x7e, 0 }, { 0xfe, 0 } }, /* 07e */ + { { 0x7f, 0 }, { 0xff, 0 } }, /* 07f */ + { { 0x80, 0 }, { 0 } }, /* 080 */ + { { 0x81, 0 }, { 0 } }, /* 081 */ + { { 0x82, 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0x85, 0 }, { 0 } }, /* 085 */ + { { 0x86, 0 }, { 0 } }, /* 086 */ + { { 0x87, 0 }, { 0 } }, /* 087 */ + { { 0x88, 0 }, { 0 } }, /* 088 */ + { { 0x89, 0 }, { 0 } }, /* 089 */ + { { 0x8a, 0 }, { 0 } }, /* 08a */ + { { 0x8b, 0 }, { 0 } }, /* 08b */ + { { 0x8c, 0 }, { 0 } }, /* 08c */ + { { 0x8d, 0 }, { 0 } }, /* 08d */ + { { 0x8e, 0 }, { 0 } }, /* 08e */ + { { 0x8f, 0 }, { 0 } }, /* 08f */ + { { 0x90, 0 }, { 0 } }, /* 090 */ + { { 0x91, 0 }, { 0 } }, /* 091 */ + { { 0x92, 0 }, { 0 } }, /* 092 */ + { { 0x93, 0 }, { 0 } }, /* 093 */ + { { 0x94, 0 }, { 0 } }, /* 094 */ + { { 0x95, 0 }, { 0 } }, /* 095 */ + { { 0x96, 0 }, { 0 } }, /* 096 */ + { { 0x97, 0 }, { 0 } }, /* 097 */ + { { 0x98, 0 }, { 0 } }, /* 098 */ + { { 0x99, 0 }, { 0 } }, /* 099 */ + { { 0x9a, 0 }, { 0 } }, /* 09a */ + { { 0x9b, 0 }, { 0 } }, /* 09b */ + { { 0x9c, 0 }, { 0 } }, /* 09c */ + { { 0x9d, 0 }, { 0 } }, /* 09d */ + { { 0x9e, 0 }, { 0 } }, /* 09e */ + { { 0x9f, 0 }, { 0 } }, /* 09f */ + { { 0xa0, 0 }, { 0 } }, /* 0a0 */ + { { 0xa1, 0 }, { 0 } }, /* 0a1 */ + { { 0xa2, 0 }, { 0 } }, /* 0a2 */ + { { 0xa3, 0 }, { 0 } }, /* 0a3 */ + { { 0xa4, 0 }, { 0 } }, /* 0a4 */ + { { 0xa5, 0 }, { 0 } }, /* 0a5 */ + { { 0xa6, 0 }, { 0 } }, /* 0a6 */ + { { 0xa7, 0 }, { 0 } }, /* 0a7 */ + { { 0xa8, 0 }, { 0 } }, /* 0a8 */ + { { 0xa9, 0 }, { 0 } }, /* 0a9 */ + { { 0xaa, 0 }, { 0 } }, /* 0aa */ + { { 0xab, 0 }, { 0 } }, /* 0ab */ + { { 0xac, 0 }, { 0 } }, /* 0ac */ + { { 0xad, 0 }, { 0 } }, /* 0ad */ + { { 0xae, 0 }, { 0 } }, /* 0ae */ + { { 0xaf, 0 }, { 0 } }, /* 0af */ + { { 0xb0, 0 }, { 0 } }, /* 0b0 */ + { { 0xb1, 0 }, { 0 } }, /* 0b1 */ + { { 0xb2, 0 }, { 0 } }, /* 0b2 */ + { { 0xb3, 0 }, { 0 } }, /* 0b3 */ + { { 0xb4, 0 }, { 0 } }, /* 0b4 */ + { { 0xb5, 0 }, { 0 } }, /* 0b5 */ + { { 0xb6, 0 }, { 0 } }, /* 0b6 */ + { { 0xb7, 0 }, { 0 } }, /* 0b7 */ + { { 0xb8, 0 }, { 0 } }, /* 0b8 */ + { { 0xb9, 0 }, { 0 } }, /* 0b9 */ + { { 0xba, 0 }, { 0 } }, /* 0ba */ + { { 0xbb, 0 }, { 0 } }, /* 0bb */ + { { 0xbc, 0 }, { 0 } }, /* 0bc */ + { { 0xbd, 0 }, { 0 } }, /* 0bd */ + { { 0xbe, 0 }, { 0 } }, /* 0be */ + { { 0xbf, 0 }, { 0 } }, /* 0bf */ + { { 0xc0, 0 }, { 0 } }, /* 0c0 */ + { { 0xc1, 0 }, { 0 } }, /* 0c1 */ + { { 0xc2, 0 }, { 0 } }, /* 0c2 */ + { { 0xc3, 0 }, { 0 } }, /* 0c3 */ + { { 0xc4, 0 }, { 0 } }, /* 0c4 */ + { { 0xc5, 0 }, { 0 } }, /* 0c5 */ + { { 0xc6, 0 }, { 0 } }, /* 0c6 */ + { { 0xc7, 0 }, { 0 } }, /* 0c7 */ + { { 0xc8, 0 }, { 0 } }, /* 0c8 */ + { { 0xc9, 0 }, { 0 } }, /* 0c9 */ + { { 0xca, 0 }, { 0 } }, /* 0ca */ + { { 0xcb, 0 }, { 0 } }, /* 0cb */ + { { 0xcc, 0 }, { 0 } }, /* 0cc */ + { { 0xcd, 0 }, { 0 } }, /* 0cd */ + { { 0xce, 0 }, { 0 } }, /* 0ce */ + { { 0xcf, 0 }, { 0 } }, /* 0cf */ + { { 0xd0, 0 }, { 0 } }, /* 0d0 */ + { { 0xd1, 0 }, { 0 } }, /* 0d1 */ + { { 0xd2, 0 }, { 0 } }, /* 0d2 */ + { { 0xd3, 0 }, { 0 } }, /* 0d3 */ + { { 0xd4, 0 }, { 0 } }, /* 0d4 */ + { { 0xd5, 0 }, { 0 } }, /* 0d5 */ + { { 0xd6, 0 }, { 0 } }, /* 0d6 */ + { { 0xd7, 0 }, { 0 } }, /* 0d7 */ + { { 0xd8, 0 }, { 0 } }, /* 0d8 */ + { { 0xd9, 0 }, { 0 } }, /* 0d9 */ + { { 0xda, 0 }, { 0 } }, /* 0da */ + { { 0xdb, 0 }, { 0 } }, /* 0db */ + { { 0xdc, 0 }, { 0 } }, /* 0dc */ + { { 0xdd, 0 }, { 0 } }, /* 0dd */ + { { 0xde, 0 }, { 0 } }, /* 0de */ + { { 0xdf, 0 }, { 0 } }, /* 0df */ + { { 0xe0, 0 }, { 0 } }, /* 0e0 */ + { { 0xe1, 0 }, { 0 } }, /* 0e1 */ + { { 0xe2, 0 }, { 0 } }, /* 0e2 */ + { { 0xe3, 0 }, { 0 } }, /* 0e3 */ + { { 0xe4, 0 }, { 0 } }, /* 0e4 */ + { { 0xe5, 0 }, { 0 } }, /* 0e5 */ + { { 0xe6, 0 }, { 0 } }, /* 0e6 */ + { { 0xe7, 0 }, { 0 } }, /* 0e7 */ + { { 0xe8, 0 }, { 0 } }, /* 0e8 */ + { { 0xe9, 0 }, { 0 } }, /* 0e9 */ + { { 0xea, 0 }, { 0 } }, /* 0ea */ + { { 0xeb, 0 }, { 0 } }, /* 0eb */ + { { 0xec, 0 }, { 0 } }, /* 0ec */ + { { 0xed, 0 }, { 0 } }, /* 0ed */ + { { 0xee, 0 }, { 0 } }, /* 0ee */ + { { 0xef, 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0xf1, 0 }, { 0 } }, /* 0f1 */ + { { 0xf2, 0 }, { 0 } }, /* 0f2 */ + { { 0xf3, 0 }, { 0 } }, /* 0f3 */ + { { 0xf4, 0 }, { 0 } }, /* 0f4 */ + { { 0xf5, 0 }, { 0 } }, /* 0f5 */ + { { 0xf6, 0 }, { 0 } }, /* 0f6 */ + { { 0xf7, 0 }, { 0 } }, /* 0f7 */ + { { 0xf8, 0 }, { 0 } }, /* 0f8 */ + { { 0xf9, 0 }, { 0 } }, /* 0f9 */ + { { 0xfa, 0 }, { 0 } }, /* 0fa */ + { { 0xfb, 0 }, { 0 } }, /* 0fb */ + { { 0xfc, 0 }, { 0 } }, /* 0fc */ + { { 0xfd, 0 }, { 0 } }, /* 0fd */ + { { 0xfe, 0 }, { 0 } }, /* 0fe */ + { { 0xff, 0 }, { 0 } }, /* 0ff */ + { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, /* 100 */ + { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 101 */ + { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, /* 102 */ + { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 103 */ + { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, /* 104 */ + { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 105 */ + { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, /* 106 */ + { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 107 */ + { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, /* 108 */ + { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 109 */ + { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, /* 10a */ + { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10b */ + { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, /* 10e */ + { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10f */ + { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, /* 110 */ + { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 111 */ + { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, /* 112 */ + { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 113 */ + { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, /* 114 */ + { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 115 */ + { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, /* 116 */ + { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 117 */ + { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, /* 118 */ + { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 119 */ + { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, /* 11a */ + { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11b */ + { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, /* 11c */ + { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11d */ + { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, /* 11e */ + { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11f */ + { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, /* 120 */ + { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 121 */ + { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, /* 122 */ + { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 123 */ + { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, /* 124 */ + { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 125 */ + { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, /* 12c */ + { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12d */ + { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, /* 12e */ + { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12f */ + { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, /* 130 */ + { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 131 */ + { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, /* 134 */ + { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 137 */ + { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, /* 13a */ + { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13b */ + { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, /* 13c */ + { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13d */ + { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, /* 13e */ + { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13f */ + { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, /* 140 */ + { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 141 */ + { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, /* 142 */ + { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 143 */ + { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, /* 146 */ + { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 147 */ + { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, /* 148 */ + { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14b */ + { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, /* 14c */ + { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14d */ + { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, /* 14e */ + { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14f */ + { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, /* 150 */ + { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 151 */ + { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, /* 152 */ + { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 157 */ + { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, /* 158 */ + { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 159 */ + { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, /* 15a */ + { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15b */ + { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, /* 15c */ + { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15d */ + { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, /* 15e */ + { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 161 */ + { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, /* 162 */ + { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 163 */ + { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, /* 164 */ + { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 165 */ + { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, /* 166 */ + { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 167 */ + { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, /* 168 */ + { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 169 */ + { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, /* 16a */ + { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16b */ + { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, /* 16c */ + { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16d */ + { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, /* 170 */ + { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 171 */ + { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, /* 172 */ + { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 173 */ + { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, /* 174 */ + { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 177 */ + { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, /* 178 */ + { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 179 */ + { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, /* 17a */ + { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17b */ + { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, /* 17c */ + { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17d */ + { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, /* 17e */ + { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0xe0, 0xee, 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0xe0, 0xfe, 0 }, { 0 } }, /* 1fe */ + { { 0xe0, 0xff, 0 }, { 0 } } /* 1ff */ // clang-format on }; diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 39cb43d70..593b673e2 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -138,265 +138,518 @@ static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No addit static const scancode scancode_tandy[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x56, 0 }, { 0xd6, 0 } }, /* 052 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ - { { 0x57, 0 }, { 0xd7, 0 } }, { { 0 }, { 0 } }, /* 11c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ - { { 0x29, 0 }, { 0xa9, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 14a */ - { { 0 }, { 0 } }, { { 0x4e, 0 }, { 0xce, 0 } }, /* 14c */ - { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 013 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x56, 0 }, { 0xd6, 0 } }, /* 053 */ + { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, /* 055 */ + { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, /* 057 */ + { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, /* 059 */ + { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, /* 05b */ + { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, /* 05d */ + { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, /* 05f */ + { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, /* 061 */ + { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, /* 063 */ + { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, /* 065 */ + { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, /* 067 */ + { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, /* 069 */ + { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, /* 06b */ + { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, /* 06d */ + { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, /* 06f */ + { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, /* 071 */ + { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, /* 073 */ + { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, /* 075 */ + { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, /* 077 */ + { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, /* 079 */ + { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, /* 07b */ + { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, /* 07d */ + { { 0 }, { 0 } }, /* 07e */ + { { 0 }, { 0 } }, /* 07f */ + { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, /* 081 */ + { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, /* 085 */ + { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, /* 087 */ + { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, /* 089 */ + { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, /* 08b */ + { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, /* 08d */ + { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, /* 08f */ + { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, /* 091 */ + { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, /* 093 */ + { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, /* 095 */ + { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, /* 097 */ + { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, /* 099 */ + { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, /* 09b */ + { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, /* 09d */ + { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, /* 09f */ + { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, /* 0a1 */ + { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, /* 0a3 */ + { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, /* 0a5 */ + { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, /* 0a7 */ + { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, /* 0a9 */ + { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, /* 0ab */ + { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, /* 0ad */ + { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, /* 0af */ + { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, /* 0b1 */ + { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, /* 0b3 */ + { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, /* 0b5 */ + { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, /* 0b7 */ + { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, /* 0b9 */ + { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, /* 0bb */ + { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, /* 0bd */ + { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, /* 0bf */ + { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, /* 0c1 */ + { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, /* 0c3 */ + { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, /* 0c5 */ + { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, /* 0c7 */ + { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, /* 0c9 */ + { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, /* 0cb */ + { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, /* 0cd */ + { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, /* 0cf */ + { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, /* 0d1 */ + { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, /* 0d3 */ + { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, /* 0d5 */ + { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, /* 0d7 */ + { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, /* 0d9 */ + { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, /* 0db */ + { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, /* 0dd */ + { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, /* 0df */ + { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, /* 0e1 */ + { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, /* 0e3 */ + { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, /* 0e5 */ + { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, /* 0e7 */ + { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, /* 0e9 */ + { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, /* 0eb */ + { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, /* 0ed */ + { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, /* 0f1 */ + { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, /* 0f3 */ + { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, /* 0f5 */ + { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, /* 0f7 */ + { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, /* 0f9 */ + { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, /* 0fb */ + { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, /* 0fd */ + { { 0 }, { 0 } }, /* 0fe */ + { { 0 }, { 0 } }, /* 0ff */ + { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, /* 101 */ + { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, /* 103 */ + { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, /* 105 */ + { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, /* 107 */ + { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, /* 109 */ + { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, /* 10b */ + { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, /* 10f */ + { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, /* 111 */ + { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, /* 113 */ + { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, /* 115 */ + { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, /* 117 */ + { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, /* 119 */ + { { 0 }, { 0 } }, /* 11a */ + { { 0 }, { 0 } }, /* 11b */ + { { 0x57, 0 }, { 0xd7, 0 } }, /* 11c */ + { { 0 }, { 0 } }, /* 11d */ + { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, /* 11f */ + { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, /* 121 */ + { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, /* 123 */ + { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, /* 125 */ + { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, /* 12d */ + { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, /* 12f */ + { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, /* 131 */ + { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0 }, { 0 } }, /* 134 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, /* 13b */ + { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, /* 13d */ + { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, /* 13f */ + { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, /* 141 */ + { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, /* 143 */ + { { 0 }, { 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 148 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 14b */ + { { 0 }, { 0 } }, /* 14c */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 14d */ + { { 0 }, { 0 } }, /* 14e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 150 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, /* 157 */ + { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, /* 159 */ + { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, /* 15b */ + { { 0 }, { 0 } }, /* 15c */ + { { 0 }, { 0 } }, /* 15d */ + { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, /* 161 */ + { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, /* 163 */ + { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, /* 165 */ + { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, /* 167 */ + { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, /* 169 */ + { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, /* 16b */ + { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, /* 16d */ + { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, /* 171 */ + { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, /* 173 */ + { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, /* 177 */ + { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, /* 179 */ + { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, /* 17b */ + { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, /* 17d */ + { { 0 }, { 0 } }, /* 17e */ + { { 0 }, { 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0 }, { 0 } }, /* 1fe */ + { { 0 }, { 0 } } /* 1ff */ // clang-format on }; static uint8_t crtcmask[32] = { diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 6cc359892..b6bcbf3ca 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -846,265 +846,518 @@ ms_poll(void *priv) */ const scancode scancode_olivetti_m24_deluxe[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ - { { 0x5e, 0 }, { 0xde, 0 } }, { { 0x60, 0 }, { 0xe0, 0 } }, /* 056 */ - { { 0x61, 0 }, { 0xe1, 0 } }, { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ - { { 0x57, 0 }, { 0xd7, 0 } }, { { 0 }, { 0 } }, /* 11c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, { { 0x5f, 0 }, { 0xdf, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ - { { 0x66, 0 }, { 0xe6, 0 } }, { { 0x55, 0 }, { 0xd5, 0 } }, /* 138 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x63, 0 }, { 0xe3, 0 } }, /* 146 */ - { { 0x5b, 0 }, { 0xdb, 0 } }, { { 0x5c, 0 }, { 0xdc, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0x58, 0 }, { 0xd8, 0 } }, /* 14a */ - { { 0 }, { 0 } }, { { 0x5a, 0 }, { 0xda, 0 } }, /* 14c */ - { { 0 }, { 0 } }, { { 0x65, 0 }, { 0xe5, 0 } }, /* 14e */ - { { 0x59, 0 }, { 0xd9, 0 } }, { { 0x5d, 0 }, { 0xdd, 0 } }, /* 150 */ - { { 0x62, 0 }, { 0xe2, 0 } }, { { 0x64, 0 }, { 0xe4, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, { { 0x54, 0 }, { 0xd4, 0 } }, /* 15a */ - { { 0x67, 0 }, { 0xe7, 0 } }, { { 0x56, 0 }, { 0xd6, 0 } }, /* 15c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 013 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ + { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, /* 055 */ + { { 0x5e, 0 }, { 0xde, 0 } }, /* 056 */ + { { 0x60, 0 }, { 0xe0, 0 } }, /* 057 */ + { { 0x61, 0 }, { 0xe1, 0 } }, /* 058 */ + { { 0 }, { 0 } }, /* 059 */ + { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, /* 05b */ + { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, /* 05d */ + { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, /* 05f */ + { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, /* 061 */ + { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, /* 063 */ + { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, /* 065 */ + { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, /* 067 */ + { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, /* 069 */ + { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, /* 06b */ + { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, /* 06d */ + { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, /* 06f */ + { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, /* 071 */ + { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, /* 073 */ + { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, /* 075 */ + { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, /* 077 */ + { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, /* 079 */ + { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, /* 07b */ + { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, /* 07d */ + { { 0 }, { 0 } }, /* 07e */ + { { 0 }, { 0 } }, /* 07f */ + { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, /* 081 */ + { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, /* 085 */ + { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, /* 087 */ + { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, /* 089 */ + { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, /* 08b */ + { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, /* 08d */ + { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, /* 08f */ + { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, /* 091 */ + { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, /* 093 */ + { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, /* 095 */ + { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, /* 097 */ + { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, /* 099 */ + { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, /* 09b */ + { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, /* 09d */ + { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, /* 09f */ + { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, /* 0a1 */ + { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, /* 0a3 */ + { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, /* 0a5 */ + { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, /* 0a7 */ + { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, /* 0a9 */ + { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, /* 0ab */ + { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, /* 0ad */ + { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, /* 0af */ + { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, /* 0b1 */ + { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, /* 0b3 */ + { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, /* 0b5 */ + { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, /* 0b7 */ + { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, /* 0b9 */ + { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, /* 0bb */ + { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, /* 0bd */ + { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, /* 0bf */ + { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, /* 0c1 */ + { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, /* 0c3 */ + { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, /* 0c5 */ + { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, /* 0c7 */ + { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, /* 0c9 */ + { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, /* 0cb */ + { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, /* 0cd */ + { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, /* 0cf */ + { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, /* 0d1 */ + { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, /* 0d3 */ + { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, /* 0d5 */ + { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, /* 0d7 */ + { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, /* 0d9 */ + { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, /* 0db */ + { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, /* 0dd */ + { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, /* 0df */ + { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, /* 0e1 */ + { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, /* 0e3 */ + { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, /* 0e5 */ + { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, /* 0e7 */ + { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, /* 0e9 */ + { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, /* 0eb */ + { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, /* 0ed */ + { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, /* 0f1 */ + { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, /* 0f3 */ + { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, /* 0f5 */ + { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, /* 0f7 */ + { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, /* 0f9 */ + { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, /* 0fb */ + { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, /* 0fd */ + { { 0 }, { 0 } }, /* 0fe */ + { { 0 }, { 0 } }, /* 0ff */ + { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, /* 101 */ + { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, /* 103 */ + { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, /* 105 */ + { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, /* 107 */ + { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, /* 109 */ + { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, /* 10b */ + { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, /* 10f */ + { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, /* 111 */ + { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, /* 113 */ + { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, /* 115 */ + { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, /* 117 */ + { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, /* 119 */ + { { 0 }, { 0 } }, /* 11a */ + { { 0 }, { 0 } }, /* 11b */ + { { 0x57, 0 }, { 0xd7, 0 } }, /* 11c */ + { { 0 }, { 0 } }, /* 11d */ + { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, /* 11f */ + { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, /* 121 */ + { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, /* 123 */ + { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, /* 125 */ + { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, /* 12d */ + { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, /* 12f */ + { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, /* 131 */ + { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0 }, { 0 } }, /* 134 */ + { { 0x5f, 0 }, { 0xdf, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ + { { 0x66, 0 }, { 0xe6, 0 } }, /* 138 */ + { { 0x55, 0 }, { 0xd5, 0 } }, /* 139 */ + { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, /* 13b */ + { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, /* 13d */ + { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, /* 13f */ + { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, /* 141 */ + { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, /* 143 */ + { { 0 }, { 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ + { { 0x63, 0 }, { 0xe3, 0 } }, /* 147 */ + { { 0x5b, 0 }, { 0xdb, 0 } }, /* 148 */ + { { 0x5c, 0 }, { 0xdc, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0x58, 0 }, { 0xd8, 0 } }, /* 14b */ + { { 0 }, { 0 } }, /* 14c */ + { { 0x5a, 0 }, { 0xda, 0 } }, /* 14d */ + { { 0 }, { 0 } }, /* 14e */ + { { 0x65, 0 }, { 0xe5, 0 } }, /* 14f */ + { { 0x59, 0 }, { 0xd9, 0 } }, /* 150 */ + { { 0x5d, 0 }, { 0xdd, 0 } }, /* 151 */ + { { 0x62, 0 }, { 0xe2, 0 } }, /* 152 */ + { { 0x64, 0 }, { 0xe4, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, /* 157 */ + { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, /* 159 */ + { { 0 }, { 0 } }, /* 15a */ + { { 0x54, 0 }, { 0xd4, 0 } }, /* 15b */ + { { 0x67, 0 }, { 0xe7, 0 } }, /* 15c */ + { { 0x56, 0 }, { 0xd6, 0 } }, /* 15d */ + { { 0 }, { 0 } }, /* 15e */ + { { 0 }, { 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, /* 161 */ + { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, /* 163 */ + { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, /* 165 */ + { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, /* 167 */ + { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, /* 169 */ + { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, /* 16b */ + { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, /* 16d */ + { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, /* 171 */ + { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, /* 173 */ + { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, /* 177 */ + { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, /* 179 */ + { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, /* 17b */ + { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, /* 17d */ + { { 0 }, { 0 } }, /* 17e */ + { { 0 }, { 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0 }, { 0 } }, /* 1fe */ + { { 0 }, { 0 } } /* 1ff */ // clang-format on }; @@ -1116,265 +1369,518 @@ const scancode scancode_olivetti_m24_deluxe[512] = { */ const scancode scancode_olivetti_m240[512] = { // clang-format off - { { 0 }, { 0 } }, { { 0x01, 0 }, { 0x81, 0 } }, /* 000 */ - { { 0x02, 0 }, { 0x82, 0 } }, { { 0x03, 0 }, { 0x83, 0 } }, /* 002 */ - { { 0x04, 0 }, { 0x84, 0 } }, { { 0x05, 0 }, { 0x85, 0 } }, /* 004 */ - { { 0x06, 0 }, { 0x86, 0 } }, { { 0x07, 0 }, { 0x87, 0 } }, /* 006 */ - { { 0x08, 0 }, { 0x88, 0 } }, { { 0x09, 0 }, { 0x89, 0 } }, /* 008 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00a */ - { { 0x0c, 0 }, { 0x8c, 0 } }, { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00c */ - { { 0x0e, 0 }, { 0x8e, 0 } }, { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00e */ - { { 0x10, 0 }, { 0x90, 0 } }, { { 0x11, 0 }, { 0x91, 0 } }, /* 010 */ - { { 0x12, 0 }, { 0x92, 0 } }, { { 0x13, 0 }, { 0x93, 0 } }, /* 012 */ - { { 0x14, 0 }, { 0x94, 0 } }, { { 0x15, 0 }, { 0x95, 0 } }, /* 014 */ - { { 0x16, 0 }, { 0x96, 0 } }, { { 0x17, 0 }, { 0x97, 0 } }, /* 016 */ - { { 0x18, 0 }, { 0x98, 0 } }, { { 0x19, 0 }, { 0x99, 0 } }, /* 018 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01c */ - { { 0x1e, 0 }, { 0x9e, 0 } }, { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01e */ - { { 0x20, 0 }, { 0xa0, 0 } }, { { 0x21, 0 }, { 0xa1, 0 } }, /* 020 */ - { { 0x22, 0 }, { 0xa2, 0 } }, { { 0x23, 0 }, { 0xa3, 0 } }, /* 022 */ - { { 0x24, 0 }, { 0xa4, 0 } }, { { 0x25, 0 }, { 0xa5, 0 } }, /* 024 */ - { { 0x26, 0 }, { 0xa6, 0 } }, { { 0x27, 0 }, { 0xa7, 0 } }, /* 026 */ - { { 0x28, 0 }, { 0xa8, 0 } }, { { 0x29, 0 }, { 0xa9, 0 } }, /* 028 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, { { 0x2b, 0 }, { 0xab, 0 } }, /* 02a */ - { { 0x2c, 0 }, { 0xac, 0 } }, { { 0x2d, 0 }, { 0xad, 0 } }, /* 02c */ - { { 0x2e, 0 }, { 0xae, 0 } }, { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02e */ - { { 0x30, 0 }, { 0xb0, 0 } }, { { 0x31, 0 }, { 0xb1, 0 } }, /* 030 */ - { { 0x32, 0 }, { 0xb2, 0 } }, { { 0x33, 0 }, { 0xb3, 0 } }, /* 032 */ - { { 0x34, 0 }, { 0xb4, 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 034 */ - { { 0x36, 0 }, { 0xb6, 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 036 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0x39, 0 }, { 0xb9, 0 } }, /* 038 */ - { { 0x3a, 0 }, { 0xba, 0 } }, { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03a */ - { { 0x3c, 0 }, { 0xbc, 0 } }, { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03c */ - { { 0x3e, 0 }, { 0xbe, 0 } }, { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03e */ - { { 0x40, 0 }, { 0xc0, 0 } }, { { 0x41, 0 }, { 0xc1, 0 } }, /* 040 */ - { { 0x42, 0 }, { 0xc2, 0 } }, { { 0x43, 0 }, { 0xc3, 0 } }, /* 042 */ - { { 0x44, 0 }, { 0xc4, 0 } }, { { 0x45, 0 }, { 0xc5, 0 } }, /* 044 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 046 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 048 */ - { { 0x4a, 0 }, { 0xca, 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04a */ - { { 0x4c, 0 }, { 0xcc, 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04c */ - { { 0x4e, 0 }, { 0xce, 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 050 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 052 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 07e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 0fe */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11a */ - { { 0x1c, 0 }, { 0x9c, 0 } }, { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, { { 0x35, 0 }, { 0xb5, 0 } }, /* 134 */ - { { 0 }, { 0 } }, { { 0x37, 0 }, { 0xb7, 0 } }, /* 136 */ - { { 0x38, 0 }, { 0xb8, 0 } }, { { 0 }, { 0 } }, /* 138 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 144 */ - { { 0x46, 0 }, { 0xc6, 0 } }, { { 0x47, 0 }, { 0xc7, 0 } }, /* 146 */ - { { 0x48, 0 }, { 0xc8, 0 } }, { { 0x49, 0 }, { 0xc9, 0 } }, /* 148 */ - { { 0 }, { 0 } }, { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14a */ - { { 0 }, { 0 } }, { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14c */ - { { 0 }, { 0 } }, { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14e */ - { { 0x50, 0 }, { 0xd0, 0 } }, { { 0x51, 0 }, { 0xd1, 0 } }, /* 150 */ - { { 0x52, 0 }, { 0xd2, 0 } }, { { 0x53, 0 }, { 0xd3, 0 } }, /* 152 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, { { 0x54, 0 }, { 0xd4, 0 } }, /* 15c */ - { { 0x56, 0 }, { 0xd6, 0 } }, { { 0x5c, 0 }, { 0xdc, 0 } }, /* 15e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 17e */ - - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, { { 0 }, { 0 } } /* 1fe */ + { { 0 }, { 0 } }, /* 000 */ + { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ + { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ + { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ + { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ + { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ + { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ + { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ + { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ + { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ + { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ + { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ + { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ + { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ + { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ + { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ + { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ + { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ + { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ + { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ + { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ + { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ + { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ + { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ + { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ + { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ + { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ + { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ + { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ + { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ + { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ + { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ + { { 0x22, 0 }, { 0xa2, 0 } }, /* 023 */ + { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ + { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ + { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ + { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ + { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ + { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ + { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ + { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ + { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ + { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ + { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ + { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ + { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ + { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ + { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ + { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ + { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ + { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ + { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ + { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ + { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ + { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ + { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ + { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ + { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ + { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ + { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ + { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ + { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ + { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ + { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ + { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ + { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ + { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ + { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ + { { 0 }, { 0 } }, /* 054 */ + { { 0 }, { 0 } }, /* 055 */ + { { 0 }, { 0 } }, /* 056 */ + { { 0 }, { 0 } }, /* 057 */ + { { 0 }, { 0 } }, /* 058 */ + { { 0 }, { 0 } }, /* 059 */ + { { 0 }, { 0 } }, /* 05a */ + { { 0 }, { 0 } }, /* 05b */ + { { 0 }, { 0 } }, /* 05c */ + { { 0 }, { 0 } }, /* 05d */ + { { 0 }, { 0 } }, /* 05e */ + { { 0 }, { 0 } }, /* 05f */ + { { 0 }, { 0 } }, /* 060 */ + { { 0 }, { 0 } }, /* 061 */ + { { 0 }, { 0 } }, /* 062 */ + { { 0 }, { 0 } }, /* 063 */ + { { 0 }, { 0 } }, /* 064 */ + { { 0 }, { 0 } }, /* 065 */ + { { 0 }, { 0 } }, /* 066 */ + { { 0 }, { 0 } }, /* 067 */ + { { 0 }, { 0 } }, /* 068 */ + { { 0 }, { 0 } }, /* 069 */ + { { 0 }, { 0 } }, /* 06a */ + { { 0 }, { 0 } }, /* 06b */ + { { 0 }, { 0 } }, /* 06c */ + { { 0 }, { 0 } }, /* 06d */ + { { 0 }, { 0 } }, /* 06e */ + { { 0 }, { 0 } }, /* 06f */ + { { 0 }, { 0 } }, /* 070 */ + { { 0 }, { 0 } }, /* 071 */ + { { 0 }, { 0 } }, /* 072 */ + { { 0 }, { 0 } }, /* 073 */ + { { 0 }, { 0 } }, /* 074 */ + { { 0 }, { 0 } }, /* 075 */ + { { 0 }, { 0 } }, /* 076 */ + { { 0 }, { 0 } }, /* 077 */ + { { 0 }, { 0 } }, /* 078 */ + { { 0 }, { 0 } }, /* 079 */ + { { 0 }, { 0 } }, /* 07a */ + { { 0 }, { 0 } }, /* 07b */ + { { 0 }, { 0 } }, /* 07c */ + { { 0 }, { 0 } }, /* 07d */ + { { 0 }, { 0 } }, /* 07e */ + { { 0 }, { 0 } }, /* 07f */ + { { 0 }, { 0 } }, /* 080 */ + { { 0 }, { 0 } }, /* 081 */ + { { 0 }, { 0 } }, /* 082 */ + { { 0 }, { 0 } }, /* 083 */ + { { 0 }, { 0 } }, /* 084 */ + { { 0 }, { 0 } }, /* 085 */ + { { 0 }, { 0 } }, /* 086 */ + { { 0 }, { 0 } }, /* 087 */ + { { 0 }, { 0 } }, /* 088 */ + { { 0 }, { 0 } }, /* 089 */ + { { 0 }, { 0 } }, /* 08a */ + { { 0 }, { 0 } }, /* 08b */ + { { 0 }, { 0 } }, /* 08c */ + { { 0 }, { 0 } }, /* 08d */ + { { 0 }, { 0 } }, /* 08e */ + { { 0 }, { 0 } }, /* 08f */ + { { 0 }, { 0 } }, /* 090 */ + { { 0 }, { 0 } }, /* 091 */ + { { 0 }, { 0 } }, /* 092 */ + { { 0 }, { 0 } }, /* 093 */ + { { 0 }, { 0 } }, /* 094 */ + { { 0 }, { 0 } }, /* 095 */ + { { 0 }, { 0 } }, /* 096 */ + { { 0 }, { 0 } }, /* 097 */ + { { 0 }, { 0 } }, /* 098 */ + { { 0 }, { 0 } }, /* 099 */ + { { 0 }, { 0 } }, /* 09a */ + { { 0 }, { 0 } }, /* 09b */ + { { 0 }, { 0 } }, /* 09c */ + { { 0 }, { 0 } }, /* 09d */ + { { 0 }, { 0 } }, /* 09e */ + { { 0 }, { 0 } }, /* 09f */ + { { 0 }, { 0 } }, /* 0a0 */ + { { 0 }, { 0 } }, /* 0a1 */ + { { 0 }, { 0 } }, /* 0a2 */ + { { 0 }, { 0 } }, /* 0a3 */ + { { 0 }, { 0 } }, /* 0a4 */ + { { 0 }, { 0 } }, /* 0a5 */ + { { 0 }, { 0 } }, /* 0a6 */ + { { 0 }, { 0 } }, /* 0a7 */ + { { 0 }, { 0 } }, /* 0a8 */ + { { 0 }, { 0 } }, /* 0a9 */ + { { 0 }, { 0 } }, /* 0aa */ + { { 0 }, { 0 } }, /* 0ab */ + { { 0 }, { 0 } }, /* 0ac */ + { { 0 }, { 0 } }, /* 0ad */ + { { 0 }, { 0 } }, /* 0ae */ + { { 0 }, { 0 } }, /* 0af */ + { { 0 }, { 0 } }, /* 0b0 */ + { { 0 }, { 0 } }, /* 0b1 */ + { { 0 }, { 0 } }, /* 0b2 */ + { { 0 }, { 0 } }, /* 0b3 */ + { { 0 }, { 0 } }, /* 0b4 */ + { { 0 }, { 0 } }, /* 0b5 */ + { { 0 }, { 0 } }, /* 0b6 */ + { { 0 }, { 0 } }, /* 0b7 */ + { { 0 }, { 0 } }, /* 0b8 */ + { { 0 }, { 0 } }, /* 0b9 */ + { { 0 }, { 0 } }, /* 0ba */ + { { 0 }, { 0 } }, /* 0bb */ + { { 0 }, { 0 } }, /* 0bc */ + { { 0 }, { 0 } }, /* 0bd */ + { { 0 }, { 0 } }, /* 0be */ + { { 0 }, { 0 } }, /* 0bf */ + { { 0 }, { 0 } }, /* 0c0 */ + { { 0 }, { 0 } }, /* 0c1 */ + { { 0 }, { 0 } }, /* 0c2 */ + { { 0 }, { 0 } }, /* 0c3 */ + { { 0 }, { 0 } }, /* 0c4 */ + { { 0 }, { 0 } }, /* 0c5 */ + { { 0 }, { 0 } }, /* 0c6 */ + { { 0 }, { 0 } }, /* 0c7 */ + { { 0 }, { 0 } }, /* 0c8 */ + { { 0 }, { 0 } }, /* 0c9 */ + { { 0 }, { 0 } }, /* 0ca */ + { { 0 }, { 0 } }, /* 0cb */ + { { 0 }, { 0 } }, /* 0cc */ + { { 0 }, { 0 } }, /* 0cd */ + { { 0 }, { 0 } }, /* 0ce */ + { { 0 }, { 0 } }, /* 0cf */ + { { 0 }, { 0 } }, /* 0d0 */ + { { 0 }, { 0 } }, /* 0d1 */ + { { 0 }, { 0 } }, /* 0d2 */ + { { 0 }, { 0 } }, /* 0d3 */ + { { 0 }, { 0 } }, /* 0d4 */ + { { 0 }, { 0 } }, /* 0d5 */ + { { 0 }, { 0 } }, /* 0d6 */ + { { 0 }, { 0 } }, /* 0d7 */ + { { 0 }, { 0 } }, /* 0d8 */ + { { 0 }, { 0 } }, /* 0d9 */ + { { 0 }, { 0 } }, /* 0da */ + { { 0 }, { 0 } }, /* 0db */ + { { 0 }, { 0 } }, /* 0dc */ + { { 0 }, { 0 } }, /* 0dd */ + { { 0 }, { 0 } }, /* 0de */ + { { 0 }, { 0 } }, /* 0df */ + { { 0 }, { 0 } }, /* 0e0 */ + { { 0 }, { 0 } }, /* 0e1 */ + { { 0 }, { 0 } }, /* 0e2 */ + { { 0 }, { 0 } }, /* 0e3 */ + { { 0 }, { 0 } }, /* 0e4 */ + { { 0 }, { 0 } }, /* 0e5 */ + { { 0 }, { 0 } }, /* 0e6 */ + { { 0 }, { 0 } }, /* 0e7 */ + { { 0 }, { 0 } }, /* 0e8 */ + { { 0 }, { 0 } }, /* 0e9 */ + { { 0 }, { 0 } }, /* 0ea */ + { { 0 }, { 0 } }, /* 0eb */ + { { 0 }, { 0 } }, /* 0ec */ + { { 0 }, { 0 } }, /* 0ed */ + { { 0 }, { 0 } }, /* 0ee */ + { { 0 }, { 0 } }, /* 0ef */ + { { 0 }, { 0 } }, /* 0f0 */ + { { 0 }, { 0 } }, /* 0f1 */ + { { 0 }, { 0 } }, /* 0f2 */ + { { 0 }, { 0 } }, /* 0f3 */ + { { 0 }, { 0 } }, /* 0f4 */ + { { 0 }, { 0 } }, /* 0f5 */ + { { 0 }, { 0 } }, /* 0f6 */ + { { 0 }, { 0 } }, /* 0f7 */ + { { 0 }, { 0 } }, /* 0f8 */ + { { 0 }, { 0 } }, /* 0f9 */ + { { 0 }, { 0 } }, /* 0fa */ + { { 0 }, { 0 } }, /* 0fb */ + { { 0 }, { 0 } }, /* 0fc */ + { { 0 }, { 0 } }, /* 0fd */ + { { 0 }, { 0 } }, /* 0fe */ + { { 0 }, { 0 } }, /* 0ff */ + { { 0 }, { 0 } }, /* 100 */ + { { 0 }, { 0 } }, /* 101 */ + { { 0 }, { 0 } }, /* 102 */ + { { 0 }, { 0 } }, /* 103 */ + { { 0 }, { 0 } }, /* 104 */ + { { 0 }, { 0 } }, /* 105 */ + { { 0 }, { 0 } }, /* 106 */ + { { 0 }, { 0 } }, /* 107 */ + { { 0 }, { 0 } }, /* 108 */ + { { 0 }, { 0 } }, /* 109 */ + { { 0 }, { 0 } }, /* 10a */ + { { 0 }, { 0 } }, /* 10b */ + { { 0 }, { 0 } }, /* 10c */ + { { 0 }, { 0 } }, /* 10d */ + { { 0 }, { 0 } }, /* 10e */ + { { 0 }, { 0 } }, /* 10f */ + { { 0 }, { 0 } }, /* 110 */ + { { 0 }, { 0 } }, /* 111 */ + { { 0 }, { 0 } }, /* 112 */ + { { 0 }, { 0 } }, /* 113 */ + { { 0 }, { 0 } }, /* 114 */ + { { 0 }, { 0 } }, /* 115 */ + { { 0 }, { 0 } }, /* 116 */ + { { 0 }, { 0 } }, /* 117 */ + { { 0 }, { 0 } }, /* 118 */ + { { 0 }, { 0 } }, /* 119 */ + { { 0 }, { 0 } }, /* 11a */ + { { 0 }, { 0 } }, /* 11b */ + { { 0x1c, 0 }, { 0x9c, 0 } }, /* 11c */ + { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11d */ + { { 0 }, { 0 } }, /* 11e */ + { { 0 }, { 0 } }, /* 11f */ + { { 0 }, { 0 } }, /* 120 */ + { { 0 }, { 0 } }, /* 121 */ + { { 0 }, { 0 } }, /* 122 */ + { { 0 }, { 0 } }, /* 123 */ + { { 0 }, { 0 } }, /* 124 */ + { { 0 }, { 0 } }, /* 125 */ + { { 0 }, { 0 } }, /* 126 */ + { { 0 }, { 0 } }, /* 127 */ + { { 0 }, { 0 } }, /* 128 */ + { { 0 }, { 0 } }, /* 129 */ + { { 0 }, { 0 } }, /* 12a */ + { { 0 }, { 0 } }, /* 12b */ + { { 0 }, { 0 } }, /* 12c */ + { { 0 }, { 0 } }, /* 12d */ + { { 0 }, { 0 } }, /* 12e */ + { { 0 }, { 0 } }, /* 12f */ + { { 0 }, { 0 } }, /* 130 */ + { { 0 }, { 0 } }, /* 131 */ + { { 0 }, { 0 } }, /* 132 */ + { { 0 }, { 0 } }, /* 133 */ + { { 0 }, { 0 } }, /* 134 */ + { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ + { { 0 }, { 0 } }, /* 136 */ + { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ + { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ + { { 0 }, { 0 } }, /* 139 */ + { { 0 }, { 0 } }, /* 13a */ + { { 0 }, { 0 } }, /* 13b */ + { { 0 }, { 0 } }, /* 13c */ + { { 0 }, { 0 } }, /* 13d */ + { { 0 }, { 0 } }, /* 13e */ + { { 0 }, { 0 } }, /* 13f */ + { { 0 }, { 0 } }, /* 140 */ + { { 0 }, { 0 } }, /* 141 */ + { { 0 }, { 0 } }, /* 142 */ + { { 0 }, { 0 } }, /* 143 */ + { { 0 }, { 0 } }, /* 144 */ + { { 0 }, { 0 } }, /* 145 */ + { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ + { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ + { { 0x48, 0 }, { 0xc8, 0 } }, /* 148 */ + { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ + { { 0 }, { 0 } }, /* 14a */ + { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14b */ + { { 0 }, { 0 } }, /* 14c */ + { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14d */ + { { 0 }, { 0 } }, /* 14e */ + { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ + { { 0x50, 0 }, { 0xd0, 0 } }, /* 150 */ + { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ + { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ + { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ + { { 0 }, { 0 } }, /* 154 */ + { { 0 }, { 0 } }, /* 155 */ + { { 0 }, { 0 } }, /* 156 */ + { { 0 }, { 0 } }, /* 157 */ + { { 0 }, { 0 } }, /* 158 */ + { { 0 }, { 0 } }, /* 159 */ + { { 0 }, { 0 } }, /* 15a */ + { { 0 }, { 0 } }, /* 15b */ + { { 0 }, { 0 } }, /* 15c */ + { { 0x54, 0 }, { 0xd4, 0 } }, /* 15d */ + { { 0x56, 0 }, { 0xd6, 0 } }, /* 15e */ + { { 0x5c, 0 }, { 0xdc, 0 } }, /* 15f */ + { { 0 }, { 0 } }, /* 160 */ + { { 0 }, { 0 } }, /* 161 */ + { { 0 }, { 0 } }, /* 162 */ + { { 0 }, { 0 } }, /* 163 */ + { { 0 }, { 0 } }, /* 164 */ + { { 0 }, { 0 } }, /* 165 */ + { { 0 }, { 0 } }, /* 166 */ + { { 0 }, { 0 } }, /* 167 */ + { { 0 }, { 0 } }, /* 168 */ + { { 0 }, { 0 } }, /* 169 */ + { { 0 }, { 0 } }, /* 16a */ + { { 0 }, { 0 } }, /* 16b */ + { { 0 }, { 0 } }, /* 16c */ + { { 0 }, { 0 } }, /* 16d */ + { { 0 }, { 0 } }, /* 16e */ + { { 0 }, { 0 } }, /* 16f */ + { { 0 }, { 0 } }, /* 170 */ + { { 0 }, { 0 } }, /* 171 */ + { { 0 }, { 0 } }, /* 172 */ + { { 0 }, { 0 } }, /* 173 */ + { { 0 }, { 0 } }, /* 174 */ + { { 0 }, { 0 } }, /* 175 */ + { { 0 }, { 0 } }, /* 176 */ + { { 0 }, { 0 } }, /* 177 */ + { { 0 }, { 0 } }, /* 178 */ + { { 0 }, { 0 } }, /* 179 */ + { { 0 }, { 0 } }, /* 17a */ + { { 0 }, { 0 } }, /* 17b */ + { { 0 }, { 0 } }, /* 17c */ + { { 0 }, { 0 } }, /* 17d */ + { { 0 }, { 0 } }, /* 17e */ + { { 0 }, { 0 } }, /* 17f */ + { { 0 }, { 0 } }, /* 180 */ + { { 0 }, { 0 } }, /* 181 */ + { { 0 }, { 0 } }, /* 182 */ + { { 0 }, { 0 } }, /* 183 */ + { { 0 }, { 0 } }, /* 184 */ + { { 0 }, { 0 } }, /* 185 */ + { { 0 }, { 0 } }, /* 186 */ + { { 0 }, { 0 } }, /* 187 */ + { { 0 }, { 0 } }, /* 188 */ + { { 0 }, { 0 } }, /* 189 */ + { { 0 }, { 0 } }, /* 18a */ + { { 0 }, { 0 } }, /* 18b */ + { { 0 }, { 0 } }, /* 18c */ + { { 0 }, { 0 } }, /* 18d */ + { { 0 }, { 0 } }, /* 18e */ + { { 0 }, { 0 } }, /* 18f */ + { { 0 }, { 0 } }, /* 190 */ + { { 0 }, { 0 } }, /* 191 */ + { { 0 }, { 0 } }, /* 192 */ + { { 0 }, { 0 } }, /* 193 */ + { { 0 }, { 0 } }, /* 194 */ + { { 0 }, { 0 } }, /* 195 */ + { { 0 }, { 0 } }, /* 196 */ + { { 0 }, { 0 } }, /* 197 */ + { { 0 }, { 0 } }, /* 198 */ + { { 0 }, { 0 } }, /* 199 */ + { { 0 }, { 0 } }, /* 19a */ + { { 0 }, { 0 } }, /* 19b */ + { { 0 }, { 0 } }, /* 19c */ + { { 0 }, { 0 } }, /* 19d */ + { { 0 }, { 0 } }, /* 19e */ + { { 0 }, { 0 } }, /* 19f */ + { { 0 }, { 0 } }, /* 1a0 */ + { { 0 }, { 0 } }, /* 1a1 */ + { { 0 }, { 0 } }, /* 1a2 */ + { { 0 }, { 0 } }, /* 1a3 */ + { { 0 }, { 0 } }, /* 1a4 */ + { { 0 }, { 0 } }, /* 1a5 */ + { { 0 }, { 0 } }, /* 1a6 */ + { { 0 }, { 0 } }, /* 1a7 */ + { { 0 }, { 0 } }, /* 1a8 */ + { { 0 }, { 0 } }, /* 1a9 */ + { { 0 }, { 0 } }, /* 1aa */ + { { 0 }, { 0 } }, /* 1ab */ + { { 0 }, { 0 } }, /* 1ac */ + { { 0 }, { 0 } }, /* 1ad */ + { { 0 }, { 0 } }, /* 1ae */ + { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ + { { 0 }, { 0 } }, /* 1c0 */ + { { 0 }, { 0 } }, /* 1c1 */ + { { 0 }, { 0 } }, /* 1c2 */ + { { 0 }, { 0 } }, /* 1c3 */ + { { 0 }, { 0 } }, /* 1c4 */ + { { 0 }, { 0 } }, /* 1c5 */ + { { 0 }, { 0 } }, /* 1c6 */ + { { 0 }, { 0 } }, /* 1c7 */ + { { 0 }, { 0 } }, /* 1c8 */ + { { 0 }, { 0 } }, /* 1c9 */ + { { 0 }, { 0 } }, /* 1ca */ + { { 0 }, { 0 } }, /* 1cb */ + { { 0 }, { 0 } }, /* 1cc */ + { { 0 }, { 0 } }, /* 1cd */ + { { 0 }, { 0 } }, /* 1ce */ + { { 0 }, { 0 } }, /* 1cf */ + { { 0 }, { 0 } }, /* 1d0 */ + { { 0 }, { 0 } }, /* 1d1 */ + { { 0 }, { 0 } }, /* 1d2 */ + { { 0 }, { 0 } }, /* 1d3 */ + { { 0 }, { 0 } }, /* 1d4 */ + { { 0 }, { 0 } }, /* 1d5 */ + { { 0 }, { 0 } }, /* 1d6 */ + { { 0 }, { 0 } }, /* 1d7 */ + { { 0 }, { 0 } }, /* 1d8 */ + { { 0 }, { 0 } }, /* 1d9 */ + { { 0 }, { 0 } }, /* 1da */ + { { 0 }, { 0 } }, /* 1db */ + { { 0 }, { 0 } }, /* 1dc */ + { { 0 }, { 0 } }, /* 1dd */ + { { 0 }, { 0 } }, /* 1de */ + { { 0 }, { 0 } }, /* 1df */ + { { 0 }, { 0 } }, /* 1e0 */ + { { 0 }, { 0 } }, /* 1e1 */ + { { 0 }, { 0 } }, /* 1e2 */ + { { 0 }, { 0 } }, /* 1e3 */ + { { 0 }, { 0 } }, /* 1e4 */ + { { 0 }, { 0 } }, /* 1e5 */ + { { 0 }, { 0 } }, /* 1e6 */ + { { 0 }, { 0 } }, /* 1e7 */ + { { 0 }, { 0 } }, /* 1e8 */ + { { 0 }, { 0 } }, /* 1e9 */ + { { 0 }, { 0 } }, /* 1ea */ + { { 0 }, { 0 } }, /* 1eb */ + { { 0 }, { 0 } }, /* 1ec */ + { { 0 }, { 0 } }, /* 1ed */ + { { 0 }, { 0 } }, /* 1ee */ + { { 0 }, { 0 } }, /* 1ef */ + { { 0 }, { 0 } }, /* 1f0 */ + { { 0 }, { 0 } }, /* 1f1 */ + { { 0 }, { 0 } }, /* 1f2 */ + { { 0 }, { 0 } }, /* 1f3 */ + { { 0 }, { 0 } }, /* 1f4 */ + { { 0 }, { 0 } }, /* 1f5 */ + { { 0 }, { 0 } }, /* 1f6 */ + { { 0 }, { 0 } }, /* 1f7 */ + { { 0 }, { 0 } }, /* 1f8 */ + { { 0 }, { 0 } }, /* 1f9 */ + { { 0 }, { 0 } }, /* 1fa */ + { { 0 }, { 0 } }, /* 1fb */ + { { 0 }, { 0 } }, /* 1fc */ + { { 0 }, { 0 } }, /* 1fd */ + { { 0 }, { 0 } }, /* 1fe */ + { { 0 }, { 0 } } /* 1ff */ // clang-format on }; From 734e40b6d75d430516d74974c78b0b538cd6e80e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 22 Jun 2024 00:40:41 -0400 Subject: [PATCH 653/690] Fix missing entries in amstrad kbd scancode table --- src/machine/m_amstrad.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index ff99c94da..a00e7d8e8 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2782,6 +2782,22 @@ static const scancode scancode_pc200[512] = { { { 0 }, { 0 } }, /* 1ad */ { { 0 }, { 0 } }, /* 1ae */ { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ { { 0 }, { 0 } }, /* 1c0 */ { { 0 }, { 0 } }, /* 1c1 */ { { 0 }, { 0 } }, /* 1c2 */ From 88a4ca68eae716965a7aface035cb209a40c26cb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 22 Jun 2024 01:18:41 -0400 Subject: [PATCH 654/690] Fix missing entries in at kbd scancode tables --- src/device/keyboard_at.c | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 915dbe2b8..c0e9fdb33 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -513,6 +513,22 @@ static const scancode scancode_set1[512] = { { { 0 }, { 0 } }, /* 1ad */ { { 0 }, { 0 } }, /* 1ae */ { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ { { 0 }, { 0 } }, /* 1c0 */ { { 0 }, { 0 } }, /* 1c1 */ { { 0 }, { 0 } }, /* 1c2 */ @@ -1014,6 +1030,22 @@ static const scancode scancode_set2[512] = { { { 0 }, { 0 } }, /* 1ad */ { { 0 }, { 0 } }, /* 1ae */ { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ { { 0 }, { 0 } }, /* 1c0 */ { { 0 }, { 0 } }, /* 1c1 */ { { 0 }, { 0 } }, /* 1c2 */ @@ -1515,6 +1547,22 @@ static const scancode scancode_set3[512] = { { { 0 }, { 0 } }, /* 1ad */ { { 0 }, { 0 } }, /* 1ae */ { { 0 }, { 0 } }, /* 1af */ + { { 0 }, { 0 } }, /* 1b0 */ + { { 0 }, { 0 } }, /* 1b1 */ + { { 0 }, { 0 } }, /* 1b2 */ + { { 0 }, { 0 } }, /* 1b3 */ + { { 0 }, { 0 } }, /* 1b4 */ + { { 0 }, { 0 } }, /* 1b5 */ + { { 0 }, { 0 } }, /* 1b6 */ + { { 0 }, { 0 } }, /* 1b7 */ + { { 0 }, { 0 } }, /* 1b8 */ + { { 0 }, { 0 } }, /* 1b9 */ + { { 0 }, { 0 } }, /* 1ba */ + { { 0 }, { 0 } }, /* 1bb */ + { { 0 }, { 0 } }, /* 1bc */ + { { 0 }, { 0 } }, /* 1bd */ + { { 0 }, { 0 } }, /* 1be */ + { { 0 }, { 0 } }, /* 1bf */ { { 0 }, { 0 } }, /* 1c0 */ { { 0 }, { 0 } }, /* 1c1 */ { { 0 }, { 0 } }, /* 1c2 */ From 4efd072a65f560541ec849b037ca74e8a30339a6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 22 Jun 2024 04:27:51 -0400 Subject: [PATCH 655/690] Default keyboard should be 101/102 key This change doesn't matter yet, but it will later when this gets used. --- src/device/keyboard_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index c0e9fdb33..ce26a499e 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2184,7 +2184,7 @@ static const device_config_t keyboard_at_config[] = { .description = "Type", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 2, + .default_int = 1, .file_filter = "", .spinner = { 0 }, .selection = { From 8a90de40bc65a7036afd40743f116199c9cc0410 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Jun 2024 17:44:45 +0200 Subject: [PATCH 656/690] Matrox: Fix MSITUTOR, fixes #4554. --- src/video/vid_mga.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index fdbb2e411..2d71d36f3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5328,6 +5328,15 @@ blit_texture_trap(mystique_t *mystique) } break; + case (TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY): + if (!ctransp) + goto skip_pixel; + + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + break; + default: fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); } From 3f4df1132934565cbcc448d52b3f6dc84b572455 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Jun 2024 18:30:20 +0200 Subject: [PATCH 657/690] Fixes to the GhostPCL library names on Linux and Mac. --- src/printer/prt_ps.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 3e6612ce1..998343c4d 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -54,13 +54,14 @@ # endif #elif defined __APPLE__ # define PATH_GHOSTSCRIPT_DLL "libgs.dylib" -# define PATH_GHOSTPCL_DLL "libgpcl6.dylib" +# define PATH_GHOSTPCL_DLL "libgpcl6.9.54.dylib" #else # define PATH_GHOSTSCRIPT_DLL "libgs.so.9" # define PATH_GHOSTSCRIPT_DLL_ALT1 "libgs.so.10" # define PATH_GHOSTSCRIPT_DLL_ALT2 "libgs.so" -# define PATH_GHOSTPCL_DLL "libgpcl6.so.10" -# define PATH_GHOSTPCL_DLL_ALT "libgpcl6.so" +# define PATH_GHOSTPCL_DLL "libgpcl6.so.9" +# define PATH_GHOSTPCL_DLL_ALT1 "libgpcl6.so.10" +# define PATH_GHOSTPCL_DLL_ALT2 "libgpcl6.so" #endif #define POSTSCRIPT_BUFFER_LENGTH 65536 @@ -424,9 +425,13 @@ pcl_init(void *lpt) /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); -#ifdef PATH_GHOSTPCL_DLL_ALT +#ifdef PATH_GHOSTPCL_DLL_ALT1 if (ghostscript_handle == NULL) { - ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT, ghostscript_imports); + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT1, ghostscript_imports); +# ifdef PATH_GHOSTPCL_DLL_ALT2 + if (ghostscript_handle == NULL) + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT2, ghostscript_imports); +# endif } #endif if (ghostscript_handle == NULL) { From 499a4e1d770323bdfe76460897fee2b2fa3fb7f0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Jun 2024 23:54:14 +0200 Subject: [PATCH 658/690] MGA: Implement linestyles. --- src/video/vid_mga.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2d71d36f3..ada8b89cf 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -491,7 +491,7 @@ typedef struct mystique_t { struct { - uint8_t funcnt, stylelen, + uint8_t funcnt : 7, stylelen, dmamod; int16_t fxleft, fxright, @@ -505,7 +505,7 @@ typedef struct mystique_t { ta_key, ta_mask, lastpix_r, lastpix_g, lastpix_b, highv_line, beta, dither, err, k1, k2; - int pattern[8][16]; + bool pattern[8][16]; uint32_t dwgctrl, dwgctrl_running, bcol, fcol, pitch, plnwt, ybot, ydstorg, @@ -3885,7 +3885,6 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); while (size >= 32) { int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; - pclog("maccess = 0x%X\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { @@ -4377,15 +4376,20 @@ blit_line(mystique_t *mystique, int closed, int autoline) uint32_t old_dst; int x = mystique->dwgreg.xdst; int z_write; + int pattern_x, pattern_y; + bool transc = !!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC); switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: while (mystique->dwgreg.length >= 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + pattern_y = ((mystique->dwgreg.funcnt % (mystique->dwgreg.stylelen + 1)) >> 4) & 0x7; + pattern_x = (mystique->dwgreg.funcnt % (mystique->dwgreg.stylelen + 1)) & 0xf; + if (!transc || (transc && (mystique->dwgreg.pattern[pattern_y][pattern_x]))) switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: - src = mystique->dwgreg.fcol; + src = mystique->dwgreg.pattern[pattern_y][pattern_x] ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -4402,7 +4406,7 @@ blit_line(mystique_t *mystique, int closed, int autoline) break; case MACCESS_PWIDTH_16: - src = mystique->dwgreg.fcol; + src = mystique->dwgreg.pattern[pattern_y][pattern_x] ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -4419,7 +4423,7 @@ blit_line(mystique_t *mystique, int closed, int autoline) break; case MACCESS_PWIDTH_24: - src = mystique->dwgreg.fcol; + src = mystique->dwgreg.pattern[pattern_y][pattern_x] ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); @@ -4436,7 +4440,7 @@ blit_line(mystique_t *mystique, int closed, int autoline) break; case MACCESS_PWIDTH_32: - src = mystique->dwgreg.fcol; + src = mystique->dwgreg.pattern[pattern_y][pattern_x] ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -4479,6 +4483,7 @@ blit_line(mystique_t *mystique, int closed, int autoline) mystique->dwgreg.err += mystique->dwgreg.k1; mystique->dwgreg.length--; + mystique->dwgreg.funcnt--; } break; From bbe035b62a291b05267ee6f0f9197feac4b0e512 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 23 Jun 2024 02:28:22 +0200 Subject: [PATCH 659/690] Implement special selector pushing behavior and improve the opcode length heuristic for CS limit checks, fixes #4552. --- src/cpu/386.c | 14 ++++++++++---- src/cpu/386_common.c | 22 ++++++++++++++++++++++ src/cpu/386_common.h | 1 + src/cpu/x86seg.c | 37 +++++++++++++++++++++++++++++-------- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 3e96911ba..657bd0894 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -212,11 +212,11 @@ fetch_ea_16_long(uint32_t rmdat) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #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); \ + else 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 CS)", 0); #include "386_ops.h" @@ -261,7 +261,13 @@ exec386_2386(int32_t cycs) fetchdat = fastreadl_fetch(cs + cpu_state.pc); ol = opcode_length[fetchdat & 0xff]; - CHECK_READ_CS(MIN(ol, 4)); + if ((ol == 3) && opcode_has_modrm[fetchdat & 0xff] && (((fetchdat >> 14) & 0x03) == 0x03)) + ol = 2; + if (cpu_16bitbus) { + CHECK_READ_CS(MIN(ol, 2)); + } else { + CHECK_READ_CS(MIN(ol, 4)); + } ins_fetch_fault = cpu_386_check_instruction_fault(); /* Breakpoint fault has priority over other faults. */ diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index d1d38006b..1d130cd8a 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -106,6 +106,28 @@ uint32_t backupregs[16]; x86seg _oldds; +int opcode_has_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; + int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */ diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 6ef65771d..8ca89181c 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -449,6 +449,7 @@ get_ram_ptr(uint32_t a) } } +extern int opcode_has_modrm[256]; extern int opcode_length[256]; #ifdef OPS_286_386 diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index d912a755b..96ec726b0 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -798,6 +798,27 @@ PUSHL(uint32_t v) } } +static void +PUSHL_SEL(uint32_t v) +{ + if (cpu_16bitbus) { + PUSHW(v >> 16); + PUSHW(v & 0xffff); + } else { + if (stack32) { + writememw(ss, ESP - 4, v); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememw(ss, ((SP - 4) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 4; + } + } +} + static uint16_t POPW(void) { @@ -1092,7 +1113,7 @@ loadcscall(uint16_t seg) x86seg_log("Type %04X\n", type); if (type == 0x0c00) { - PUSHL(oldss); + PUSHL_SEL(oldss); PUSHL(oldsp2); if (cpu_state.abrt) { SS = oldss; @@ -1622,10 +1643,10 @@ pmodeint(int num, int soft) cpl_override = 1; if (type >= 0x0800) { if (cpu_state.eflags & VM_FLAG) { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); + PUSHL_SEL(GS); + PUSHL_SEL(FS); + PUSHL_SEL(DS); + PUSHL_SEL(ES); if (cpu_state.abrt) return; op_loadseg(0, &cpu_state.seg_ds); @@ -1633,10 +1654,10 @@ pmodeint(int num, int soft) op_loadseg(0, &cpu_state.seg_fs); op_loadseg(0, &cpu_state.seg_gs); } - PUSHL(oldss); + PUSHL_SEL(oldss); PUSHL(oldsp); PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); + PUSHL_SEL(CS); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; @@ -1672,7 +1693,7 @@ pmodeint(int num, int soft) } if (type > 0x0800) { PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); + PUSHL_SEL(CS); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; From 049579919eccb28b50d5b5826573fe72a263b3f9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 24 Jun 2024 15:13:12 +0200 Subject: [PATCH 660/690] MGA: Fix textures in certain cases. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ada8b89cf..79d669bdc 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5121,7 +5121,7 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) >> s_shift; t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) >> t_shift; s_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); - t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); } if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { From bfb4602e85b82751e2cda0da21d35e001cd1208b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 26 Jun 2024 22:51:34 +0200 Subject: [PATCH 661/690] S3 fixes of the day. 1. Ported the S3 ViRGE reset fix to the Pre-ViRGE cards. 2. Slight cleanup on the acceleration and logs. 3. Unused sequencer register data now return 0xff instead of 0. This fixes Scorched Earth 1.x on DOS using S3 Trio32/64/V+/V2/868/968 cards (on other S3 it works fine as is). --- src/video/vid_s3.c | 229 +++++++++++++-------------------------------- 1 file changed, 66 insertions(+), 163 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8ecd3711e..16dd83f45 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -387,6 +387,8 @@ typedef struct s3_t { void (*accel_start)(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); } s3_t; +static s3_t *reset_state = NULL; + #define INT_VSY (1 << 0) #define INT_GE_BSY (1 << 1) #define INT_FIFO_OVR (1 << 2) @@ -3091,7 +3093,10 @@ s3_in(uint16_t addr, void *priv) (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; - } + } else if ((svga->seqaddr >= 5) && (svga->seqaddr < 8)) + return 0xff; + else + return svga->seqregs[svga->seqaddr]; break; case 0x3c6: @@ -3145,7 +3150,6 @@ s3_in(uint16_t addr, void *priv) } break; case 0x30: - s3_log("[%04X:%08X]: Read CRTC30=%02x.\n", CS, cpu_state.pc, s3->id); return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); @@ -3187,7 +3191,7 @@ s3_in(uint16_t addr, void *priv) return svga->crtc[0x6b]; break; case 0x6c: - s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); + s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6c]); if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return 0x00; @@ -3200,7 +3204,6 @@ s3_in(uint16_t addr, void *priv) default: break; } - s3_log("[%04X:%08X]: Read CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); return svga->crtc[svga->crtcreg]; default: @@ -4348,6 +4351,7 @@ s3_updatemapping(s3_t *s3) /*Banked framebuffer*/ if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ { + s3_log("Enhanced Mode Mapping.\n"); /* Enhanced mode forces 64kb at 0xa0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; @@ -4734,6 +4738,7 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } + s3_log("FIFO Status Temp=%02x.\n", temp); return temp; case 0x9d48: @@ -5235,7 +5240,7 @@ s3_accel_in(uint16_t port, void *priv) case 0xe2e8: if (!s3_cpu_dest(s3)) break; - READ_PIXTRANS_BYTE_IO(0) + READ_PIXTRANS_BYTE_IO(0); if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -5317,7 +5322,7 @@ s3_accel_in(uint16_t port, void *priv) case 0xe2eb: if (!s3_cpu_dest(s3)) break; - READ_PIXTRANS_BYTE_IO(3) + READ_PIXTRANS_BYTE_IO(3); if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -5331,12 +5336,23 @@ s3_accel_in(uint16_t port, void *priv) break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3->accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); + else + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); else s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } else - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } break; default: @@ -7757,9 +7773,8 @@ s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, } } - if ((s3->accel.cmd & 0x100) && !cpu_input) { + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - } frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -9409,157 +9424,41 @@ static int vram_sizes[] = { }; static void -s3_reset(void *priv) +s3_disable_handlers(s3_t *s3) { - s3_t *s3 = (s3_t *) priv; - svga_t *svga = &s3->svga; - - memset(svga->crtc, 0x00, sizeof(svga->crtc)); - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ULL << 32; - svga->dispofftime = 1000ULL << 32; - svga->bpp = 8; - - if (s3->pci) - svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); - else if (s3->vlb) - svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); - else - svga->crtc[0x36] = 3 | (1 << 4); - - if (s3->chip >= S3_86C928) - svga->crtc[0x36] |= (vram_sizes[s3->vram] << 5); - else - svga->crtc[0x36] |= ((s3->vram == 1) ? 0x00 : 0x20) | 0x80; - - svga->crtc[0x37] = 1 | (7 << 5); - - if (s3->chip >= S3_86C928) - svga->crtc[0x37] |= 0x04; - - s3_io_set(s3); - - memset(s3->pci_regs, 0x00, 256); - - s3->pci_regs[PCI_REG_COMMAND] = 7; - - s3->pci_regs[0x30] = 0x00; - s3->pci_regs[0x32] = 0x0c; - s3->pci_regs[0x33] = 0x00; - - if (s3->chip <= S3_86C924) - s3->accel_start = s3_911_accel_start; - else - s3->accel_start = s3_accel_start; - - switch (s3->card_type) { - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - svga->crtc[0x5a] = 0x0a; - svga->getclock = sdac_getclock; - break; - - case S3_SPEA_MIRAGE_86C801: - case S3_SPEA_MIRAGE_86C805: - svga->crtc[0x5a] = 0x0a; - break; - - case S3_PHOENIX_86C801: - case S3_PHOENIX_86C805: - svga->crtc[0x5a] = 0x0a; - break; - - case S3_METHEUS_86C928: - case S3_SPEA_MERCURY_LITE_PCI: - svga->crtc[0x5a] = 0x0a; - break; - - case S3_PARADISE_BAHAMAS64: - case S3_PHOENIX_VISION864: - case S3_MIROCRYSTAL20SD_864: - svga->crtc[0x5a] = 0x0a; - break; - - case S3_DIAMOND_STEALTH64_964: - case S3_ELSAWIN2KPROX_964: - case S3_MIROCRYSTAL20SV_964: - svga->crtc[0x5a] = 0x0a; - break; - - case S3_DIAMOND_STEALTH64_968: - case S3_ELSAWIN2KPROX: - case S3_SPEA_MERCURY_P64V: - case S3_MIROVIDEO40SV_ERGO_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } - break; - - case S3_NUMBER9_9FX_531: - case S3_PHOENIX_VISION868: - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } - break; - - case S3_PHOENIX_TRIO64: - case S3_PHOENIX_TRIO64_ONBOARD: - case S3_STB_POWERGRAPH_64_VIDEO: - case S3_CARDEX_TRIO64VPLUS: - case S3_PHOENIX_TRIO64VPLUS: - case S3_PHOENIX_TRIO64VPLUS_ONBOARD: - case S3_DIAMOND_STEALTH64_764: - case S3_SPEA_MIRAGE_P64: - case S3_NUMBER9_9FX: - if (s3->chip == S3_TRIO64V) - svga->crtc[0x53] = 0x08; - break; - - case S3_TRIO64V2_DX: - svga->crtc[0x53] = 0x08; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - s3->pci_regs[0x05] = 0; - s3->pci_regs[0x06] = 0; - s3->pci_regs[0x07] = 2; - s3->pci_regs[0x3d] = 1; - s3->pci_regs[0x3e] = 4; - s3->pci_regs[0x3f] = 0xff; - break; - - default: - break; - } - - if (s3->has_bios) { - if (s3->pci) - mem_mapping_disable(&s3->bios_rom.mapping); - } - - s3_updatemapping(s3); + s3_io_remove(s3); + mem_mapping_disable(&s3->linear_mapping); mem_mapping_disable(&s3->mmio_mapping); mem_mapping_disable(&s3->new_mmio_mapping); + mem_mapping_disable(&s3->svga.mapping); + if (s3->pci) + mem_mapping_disable(&s3->bios_rom.mapping); + + /* Save all the mappings and the timers because they are part of linked lists. */ + reset_state->linear_mapping = s3->linear_mapping; + reset_state->mmio_mapping = s3->mmio_mapping; + reset_state->new_mmio_mapping = s3->new_mmio_mapping; + reset_state->svga.mapping = s3->svga.mapping; + reset_state->bios_rom.mapping = s3->bios_rom.mapping; + + reset_state->svga.timer = s3->svga.timer; + reset_state->svga.timer8514 = s3->svga.timer8514; +} + +static void +s3_reset(void *priv) +{ + s3_t *s3 = (s3_t *) priv; + + if (reset_state != NULL) { + s3->accel.multifunc[0xe] &= ~(0x200 | 0x10); + s3_disable_handlers(s3); + if (s3->pci) + reset_state->pci_slot = s3->pci_slot; + + *s3 = *reset_state; + } } static void * @@ -9568,8 +9467,9 @@ s3_init(const device_t *info) const char *bios_fn; int chip; int stepping; - s3_t *s3 = malloc(sizeof(s3_t)); - svga_t *svga = &s3->svga; + s3_t *s3 = calloc(1, sizeof(s3_t)); + reset_state = calloc(1, sizeof(s3_t)); + svga_t *svga = &s3->svga; int vram; uint32_t vram_size; @@ -9829,8 +9729,6 @@ s3_init(const device_t *info) return NULL; } - memset(s3, 0, sizeof(s3_t)); - vram = device_get_config_int("memory"); if (vram) @@ -10301,6 +10199,8 @@ s3_init(const device_t *info) s3->fifo_thread_run = 1; s3->fifo_thread = thread_create(fifo_thread, s3); + *reset_state = *s3; + return s3; } @@ -10530,6 +10430,9 @@ s3_close(void *priv) ddc_close(s3->ddc); i2c_gpio_close(s3->i2c); + free(reset_state); + reset_state = NULL; + free(s3); } From 1df242d9bb7a456a33e9b81393986cdab5a60465 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 26 Jun 2024 23:07:59 +0200 Subject: [PATCH 662/690] MGA: Fix texture filtering completely on G100. --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 79d669bdc..f6f38b4de 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5111,8 +5111,8 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; - s_frac = (((int32_t) mystique->dwgreg.tmr[6] >> s_shift) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); - t_frac = (((int32_t) mystique->dwgreg.tmr[7] >> t_shift) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + s_frac = (((int32_t) mystique->dwgreg.tmr[6]) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int32_t) mystique->dwgreg.tmr[7]) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); } else { const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); From d2ce14f9679dfd99fef52e451c3c24a4a7b2e876 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 26 Jun 2024 23:09:55 +0200 Subject: [PATCH 663/690] Fatals now work again. --- src/86box.c | 12 ++++++++---- src/chipset/intel_piix.c | 2 ++ src/qt/qt_mainwindow.cpp | 16 +++++++++++++--- src/qt/qt_mainwindow.hpp | 5 +++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/86box.c b/src/86box.c index 61b81bbf3..60423b2a1 100644 --- a/src/86box.c +++ b/src/86box.c @@ -354,12 +354,14 @@ fatal(const char *fmt, ...) if ((sp = strchr(temp, '\n')) != NULL) *sp = '\0'; + do_pause(2); + + ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp); + /* Cleanly terminate all of the emulator's components so as to avoid things like threads getting stuck. */ do_stop(); - ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp); - fflush(stdlog); exit(-1); @@ -396,12 +398,14 @@ fatal_ex(const char *fmt, va_list ap) if ((sp = strchr(temp, '\n')) != NULL) *sp = '\0'; + do_pause(2); + + ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp); + /* Cleanly terminate all of the emulator's components so as to avoid things like threads getting stuck. */ do_stop(); - ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp); - fflush(stdlog); } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 1f95c28b3..e76486917 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -243,6 +243,8 @@ smbus_update_io_mapping(piix_t *dev) static void nvr_update_io_mapping(piix_t *dev) { + return; + if (dev->nvr_io_base != 0x0000) { piix_log("Removing NVR at %04X...\n", dev->nvr_io_base); nvr_at_handler(0, dev->nvr_io_base, dev->nvr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 112d1cf23..0b7ebb33d 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -214,7 +214,7 @@ MainWindow::MainWindow(QWidget *parent) #endif }); - connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); + connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::QueuedConnection); connect(this, &MainWindow::setTitle, this, [this, toolbar_label](const QString &title) { if (dopause && !hide_tool_bar) { @@ -1267,13 +1267,20 @@ MainWindow::showMessage(int flags, const QString &header, const QString &message if (QThread::currentThread() == this->thread()) { showMessage_(flags, header, message); } else { - emit showMessageForNonQtThread(flags, header, message); + std::atomic_bool done = false; + emit showMessageForNonQtThread(flags, header, message, &done); + while (!done) { + QThread::msleep(1); + } } } void -MainWindow::showMessage_(int flags, const QString &header, const QString &message) +MainWindow::showMessage_(int flags, const QString &header, const QString &message, std::atomic_bool *done) { + if (done) { + *done = false; + } QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this); if (flags & (MBX_FATAL)) { box.setIcon(QMessageBox::Critical); @@ -1282,6 +1289,9 @@ MainWindow::showMessage_(int flags, const QString &header, const QString &messag } box.setTextFormat(Qt::TextFormat::RichText); box.exec(); + if (done) { + *done = true; + } if (cpu_thread_run == 0) QApplication::exit(-1); } diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 1fca09231..175ef5b7e 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -8,6 +8,7 @@ #include #include +#include class MediaMenu; class RendererStack; @@ -54,7 +55,7 @@ signals: void setFullscreen(bool state); void setMouseCapture(bool state); - void showMessageForNonQtThread(int flags, const QString &header, const QString &message); + void showMessageForNonQtThread(int flags, const QString &header, const QString &message, std::atomic_bool* done); void getTitleForNonQtThread(wchar_t *title); public slots: void showSettings(); @@ -120,7 +121,7 @@ private slots: void on_actionRenderer_options_triggered(); void refreshMediaMenu(); - void showMessage_(int flags, const QString &header, const QString &message); + void showMessage_(int flags, const QString &header, const QString &message, std::atomic_bool* done = nullptr); void getTitle_(wchar_t *title); void on_actionMCA_devices_triggered(); From 7d18b0ca0771069ac5eb97b3eff15eeebf52ece0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 27 Jun 2024 00:07:43 +0200 Subject: [PATCH 664/690] PIIX4: Revert test changes that should never have been committed. --- src/chipset/intel_piix.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index e76486917..1f95c28b3 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -243,8 +243,6 @@ smbus_update_io_mapping(piix_t *dev) static void nvr_update_io_mapping(piix_t *dev) { - return; - if (dev->nvr_io_base != 0x0000) { piix_log("Removing NVR at %04X...\n", dev->nvr_io_base); nvr_at_handler(0, dev->nvr_io_base, dev->nvr); From 4b9b6e08156989013a225ad504743d414ec70fa1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 24 Jun 2024 20:02:06 -0400 Subject: [PATCH 665/690] Named Initializers in keyboard scancode tables --- src/device/keyboard_at.c | 3072 +++++++++++++++++------------------ src/device/keyboard_xt.c | 1024 ++++++------ src/machine/m_amstrad.c | 1024 ++++++------ src/machine/m_tandy.c | 1024 ++++++------ src/machine/m_xt_olivetti.c | 2048 +++++++++++------------ 5 files changed, 4096 insertions(+), 4096 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index ce26a499e..bcb4d646b 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -81,1552 +81,1552 @@ static uint16_t bat_counter = 0; static const scancode scancode_set1[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ - { { 0x54, 0 }, { 0xd4, 0 } }, /* 054 */ - { { 0x55, 0 }, { 0xd5, 0 } }, /* 055 */ - { { 0x56, 0 }, { 0xd6, 0 } }, /* 056 */ - { { 0x57, 0 }, { 0xd7, 0 } }, /* 057 */ - { { 0x58, 0 }, { 0xd8, 0 } }, /* 058 */ - { { 0x59, 0 }, { 0xd9, 0 } }, /* 059 */ - { { 0x5a, 0 }, { 0xda, 0 } }, /* 05a */ - { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05b */ - { { 0x5c, 0 }, { 0xdc, 0 } }, /* 05c */ - { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05d */ - { { 0x5e, 0 }, { 0xde, 0 } }, /* 05e */ - { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05f */ - { { 0x60, 0 }, { 0xe0, 0 } }, /* 060 */ - { { 0x61, 0 }, { 0xe1, 0 } }, /* 061 */ - { { 0x62, 0 }, { 0xe2, 0 } }, /* 062 */ - { { 0x63, 0 }, { 0xe3, 0 } }, /* 063 */ - { { 0x64, 0 }, { 0xe4, 0 } }, /* 064 */ - { { 0x65, 0 }, { 0xe5, 0 } }, /* 065 */ - { { 0x66, 0 }, { 0xe6, 0 } }, /* 066 */ - { { 0x67, 0 }, { 0xe7, 0 } }, /* 067 */ - { { 0x68, 0 }, { 0xe8, 0 } }, /* 068 */ - { { 0x69, 0 }, { 0xe9, 0 } }, /* 069 */ - { { 0x6a, 0 }, { 0xea, 0 } }, /* 06a */ - { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06b */ - { { 0x6c, 0 }, { 0xec, 0 } }, /* 06c */ - { { 0x6d, 0 }, { 0xed, 0 } }, /* 06d */ - { { 0x6e, 0 }, { 0xee, 0 } }, /* 06e */ - { { 0x6f, 0 }, { 0xef, 0 } }, /* 06f */ - { { 0x70, 0 }, { 0xf0, 0 } }, /* 070 */ - { { 0x71, 0 }, { 0xf1, 0 } }, /* 071 */ - { { 0x72, 0 }, { 0xf2, 0 } }, /* 072 */ - { { 0x73, 0 }, { 0xf3, 0 } }, /* 073 */ - { { 0x74, 0 }, { 0xf4, 0 } }, /* 074 */ - { { 0x75, 0 }, { 0xf5, 0 } }, /* 075 */ - { { 0x76, 0 }, { 0xf6, 0 } }, /* 076 */ - { { 0x77, 0 }, { 0xf7, 0 } }, /* 077 */ - { { 0x78, 0 }, { 0xf8, 0 } }, /* 078 */ - { { 0x79, 0 }, { 0xf9, 0 } }, /* 079 */ - { { 0x7a, 0 }, { 0xfa, 0 } }, /* 07a */ - { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07b */ - { { 0x7c, 0 }, { 0xfc, 0 } }, /* 07c */ - { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07d */ - { { 0x7e, 0 }, { 0xfe, 0 } }, /* 07e */ - { { 0x7f, 0 }, { 0xff, 0 } }, /* 07f */ - { { 0x80, 0 }, { 0 } }, /* 080 */ - { { 0x81, 0 }, { 0 } }, /* 081 */ - { { 0x82, 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0x85, 0 }, { 0 } }, /* 085 */ - { { 0x86, 0 }, { 0 } }, /* 086 */ - { { 0x87, 0 }, { 0 } }, /* 087 */ - { { 0x88, 0 }, { 0 } }, /* 088 */ - { { 0x89, 0 }, { 0 } }, /* 089 */ - { { 0x8a, 0 }, { 0 } }, /* 08a */ - { { 0x8b, 0 }, { 0 } }, /* 08b */ - { { 0x8c, 0 }, { 0 } }, /* 08c */ - { { 0x8d, 0 }, { 0 } }, /* 08d */ - { { 0x8e, 0 }, { 0 } }, /* 08e */ - { { 0x8f, 0 }, { 0 } }, /* 08f */ - { { 0x90, 0 }, { 0 } }, /* 090 */ - { { 0x91, 0 }, { 0 } }, /* 091 */ - { { 0x92, 0 }, { 0 } }, /* 092 */ - { { 0x93, 0 }, { 0 } }, /* 093 */ - { { 0x94, 0 }, { 0 } }, /* 094 */ - { { 0x95, 0 }, { 0 } }, /* 095 */ - { { 0x96, 0 }, { 0 } }, /* 096 */ - { { 0x97, 0 }, { 0 } }, /* 097 */ - { { 0x98, 0 }, { 0 } }, /* 098 */ - { { 0x99, 0 }, { 0 } }, /* 099 */ - { { 0x9a, 0 }, { 0 } }, /* 09a */ - { { 0x9b, 0 }, { 0 } }, /* 09b */ - { { 0x9c, 0 }, { 0 } }, /* 09c */ - { { 0x9d, 0 }, { 0 } }, /* 09d */ - { { 0x9e, 0 }, { 0 } }, /* 09e */ - { { 0x9f, 0 }, { 0 } }, /* 09f */ - { { 0xa0, 0 }, { 0 } }, /* 0a0 */ - { { 0xa1, 0 }, { 0 } }, /* 0a1 */ - { { 0xa2, 0 }, { 0 } }, /* 0a2 */ - { { 0xa3, 0 }, { 0 } }, /* 0a3 */ - { { 0xa4, 0 }, { 0 } }, /* 0a4 */ - { { 0xa5, 0 }, { 0 } }, /* 0a5 */ - { { 0xa6, 0 }, { 0 } }, /* 0a6 */ - { { 0xa7, 0 }, { 0 } }, /* 0a7 */ - { { 0xa8, 0 }, { 0 } }, /* 0a8 */ - { { 0xa9, 0 }, { 0 } }, /* 0a9 */ - { { 0xaa, 0 }, { 0 } }, /* 0aa */ - { { 0xab, 0 }, { 0 } }, /* 0ab */ - { { 0xac, 0 }, { 0 } }, /* 0ac */ - { { 0xad, 0 }, { 0 } }, /* 0ad */ - { { 0xae, 0 }, { 0 } }, /* 0ae */ - { { 0xaf, 0 }, { 0 } }, /* 0af */ - { { 0xb0, 0 }, { 0 } }, /* 0b0 */ - { { 0xb1, 0 }, { 0 } }, /* 0b1 */ - { { 0xb2, 0 }, { 0 } }, /* 0b2 */ - { { 0xb3, 0 }, { 0 } }, /* 0b3 */ - { { 0xb4, 0 }, { 0 } }, /* 0b4 */ - { { 0xb5, 0 }, { 0 } }, /* 0b5 */ - { { 0xb6, 0 }, { 0 } }, /* 0b6 */ - { { 0xb7, 0 }, { 0 } }, /* 0b7 */ - { { 0xb8, 0 }, { 0 } }, /* 0b8 */ - { { 0xb9, 0 }, { 0 } }, /* 0b9 */ - { { 0xba, 0 }, { 0 } }, /* 0ba */ - { { 0xbb, 0 }, { 0 } }, /* 0bb */ - { { 0xbc, 0 }, { 0 } }, /* 0bc */ - { { 0xbd, 0 }, { 0 } }, /* 0bd */ - { { 0xbe, 0 }, { 0 } }, /* 0be */ - { { 0xbf, 0 }, { 0 } }, /* 0bf */ - { { 0xc0, 0 }, { 0 } }, /* 0c0 */ - { { 0xc1, 0 }, { 0 } }, /* 0c1 */ - { { 0xc2, 0 }, { 0 } }, /* 0c2 */ - { { 0xc3, 0 }, { 0 } }, /* 0c3 */ - { { 0xc4, 0 }, { 0 } }, /* 0c4 */ - { { 0xc5, 0 }, { 0 } }, /* 0c5 */ - { { 0xc6, 0 }, { 0 } }, /* 0c6 */ - { { 0xc7, 0 }, { 0 } }, /* 0c7 */ - { { 0xc8, 0 }, { 0 } }, /* 0c8 */ - { { 0xc9, 0 }, { 0 } }, /* 0c9 */ - { { 0xca, 0 }, { 0 } }, /* 0ca */ - { { 0xcb, 0 }, { 0 } }, /* 0cb */ - { { 0xcc, 0 }, { 0 } }, /* 0cc */ - { { 0xcd, 0 }, { 0 } }, /* 0cd */ - { { 0xce, 0 }, { 0 } }, /* 0ce */ - { { 0xcf, 0 }, { 0 } }, /* 0cf */ - { { 0xd0, 0 }, { 0 } }, /* 0d0 */ - { { 0xd1, 0 }, { 0 } }, /* 0d1 */ - { { 0xd2, 0 }, { 0 } }, /* 0d2 */ - { { 0xd3, 0 }, { 0 } }, /* 0d3 */ - { { 0xd4, 0 }, { 0 } }, /* 0d4 */ - { { 0xd5, 0 }, { 0 } }, /* 0d5 */ - { { 0xd6, 0 }, { 0 } }, /* 0d6 */ - { { 0xd7, 0 }, { 0 } }, /* 0d7 */ - { { 0xd8, 0 }, { 0 } }, /* 0d8 */ - { { 0xd9, 0 }, { 0 } }, /* 0d9 */ - { { 0xda, 0 }, { 0 } }, /* 0da */ - { { 0xdb, 0 }, { 0 } }, /* 0db */ - { { 0xdc, 0 }, { 0 } }, /* 0dc */ - { { 0xdd, 0 }, { 0 } }, /* 0dd */ - { { 0xde, 0 }, { 0 } }, /* 0de */ - { { 0xdf, 0 }, { 0 } }, /* 0df */ - { { 0xe0, 0 }, { 0 } }, /* 0e0 */ - { { 0xe1, 0 }, { 0 } }, /* 0e1 */ - { { 0xe2, 0 }, { 0 } }, /* 0e2 */ - { { 0xe3, 0 }, { 0 } }, /* 0e3 */ - { { 0xe4, 0 }, { 0 } }, /* 0e4 */ - { { 0xe5, 0 }, { 0 } }, /* 0e5 */ - { { 0xe6, 0 }, { 0 } }, /* 0e6 */ - { { 0xe7, 0 }, { 0 } }, /* 0e7 */ - { { 0xe8, 0 }, { 0 } }, /* 0e8 */ - { { 0xe9, 0 }, { 0 } }, /* 0e9 */ - { { 0xea, 0 }, { 0 } }, /* 0ea */ - { { 0xeb, 0 }, { 0 } }, /* 0eb */ - { { 0xec, 0 }, { 0 } }, /* 0ec */ - { { 0xed, 0 }, { 0 } }, /* 0ed */ - { { 0xee, 0 }, { 0 } }, /* 0ee */ - { { 0xef, 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0xf1, 0 }, { 0 } }, /* 0f1 */ - { { 0xf2, 0 }, { 0 } }, /* 0f2 */ - { { 0xf3, 0 }, { 0 } }, /* 0f3 */ - { { 0xf4, 0 }, { 0 } }, /* 0f4 */ - { { 0xf5, 0 }, { 0 } }, /* 0f5 */ - { { 0xf6, 0 }, { 0 } }, /* 0f6 */ - { { 0xf7, 0 }, { 0 } }, /* 0f7 */ - { { 0xf8, 0 }, { 0 } }, /* 0f8 */ - { { 0xf9, 0 }, { 0 } }, /* 0f9 */ - { { 0xfa, 0 }, { 0 } }, /* 0fa */ - { { 0xfb, 0 }, { 0 } }, /* 0fb */ - { { 0xfc, 0 }, { 0 } }, /* 0fc */ - { { 0xfd, 0 }, { 0 } }, /* 0fd */ - { { 0xfe, 0 }, { 0 } }, /* 0fe */ - { { 0xff, 0 }, { 0 } }, /* 0ff */ - { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, /* 100 */ - { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 101 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, /* 102 */ - { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 103 */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, /* 104 */ - { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 105 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, /* 106 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 107 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, /* 108 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 109 */ - { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, /* 10a */ - { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10b */ - { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, /* 10e */ - { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10f */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, /* 110 */ - { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 111 */ - { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, /* 112 */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 113 */ - { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, /* 114 */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 115 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, /* 116 */ - { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 117 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, /* 118 */ - { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 119 */ - { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, /* 11a */ - { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11b */ - { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, /* 11c */ - { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11d */ - { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, /* 11e */ - { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11f */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, /* 120 */ - { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 121 */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, /* 122 */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 123 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, /* 124 */ - { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 125 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, /* 12c */ - { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12d */ - { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, /* 12e */ - { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12f */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, /* 130 */ - { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 131 */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, /* 134 */ - { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 137 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, /* 13a */ - { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13b */ - { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, /* 13c */ - { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13d */ - { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, /* 13e */ - { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13f */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, /* 140 */ - { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 141 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, /* 142 */ - { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 143 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, /* 146 */ - { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 147 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, /* 148 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14b */ - { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, /* 14c */ - { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14d */ - { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, /* 14e */ - { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14f */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, /* 150 */ - { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 151 */ - { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, /* 152 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 157 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, /* 158 */ - { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 159 */ - { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, /* 15a */ - { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15b */ - { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, /* 15c */ - { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15d */ - { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, /* 15e */ - { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 161 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, /* 162 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 163 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, /* 164 */ - { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 165 */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, /* 166 */ - { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 167 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, /* 168 */ - { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 169 */ - { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, /* 16a */ - { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16b */ - { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, /* 16c */ - { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16d */ - { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, /* 170 */ - { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 171 */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, /* 172 */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 173 */ - { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, /* 174 */ - { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 177 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, /* 178 */ - { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 179 */ - { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, /* 17a */ - { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17b */ - { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, /* 17c */ - { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17d */ - { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, /* 17e */ - { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0xe0, 0xee, 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0xe0, 0xfe, 0 }, { 0 } }, /* 1fe */ - { { 0xe0, 0xff, 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 054 */ + { .mk = { 0x55, 0 }, .brk = { 0xd5, 0 } }, /* 055 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 056 */ + { .mk = { 0x57, 0 }, .brk = { 0xd7, 0 } }, /* 057 */ + { .mk = { 0x58, 0 }, .brk = { 0xd8, 0 } }, /* 058 */ + { .mk = { 0x59, 0 }, .brk = { 0xd9, 0 } }, /* 059 */ + { .mk = { 0x5a, 0 }, .brk = { 0xda, 0 } }, /* 05a */ + { .mk = { 0x5b, 0 }, .brk = { 0xdb, 0 } }, /* 05b */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 05c */ + { .mk = { 0x5d, 0 }, .brk = { 0xdd, 0 } }, /* 05d */ + { .mk = { 0x5e, 0 }, .brk = { 0xde, 0 } }, /* 05e */ + { .mk = { 0x5f, 0 }, .brk = { 0xdf, 0 } }, /* 05f */ + { .mk = { 0x60, 0 }, .brk = { 0xe0, 0 } }, /* 060 */ + { .mk = { 0x61, 0 }, .brk = { 0xe1, 0 } }, /* 061 */ + { .mk = { 0x62, 0 }, .brk = { 0xe2, 0 } }, /* 062 */ + { .mk = { 0x63, 0 }, .brk = { 0xe3, 0 } }, /* 063 */ + { .mk = { 0x64, 0 }, .brk = { 0xe4, 0 } }, /* 064 */ + { .mk = { 0x65, 0 }, .brk = { 0xe5, 0 } }, /* 065 */ + { .mk = { 0x66, 0 }, .brk = { 0xe6, 0 } }, /* 066 */ + { .mk = { 0x67, 0 }, .brk = { 0xe7, 0 } }, /* 067 */ + { .mk = { 0x68, 0 }, .brk = { 0xe8, 0 } }, /* 068 */ + { .mk = { 0x69, 0 }, .brk = { 0xe9, 0 } }, /* 069 */ + { .mk = { 0x6a, 0 }, .brk = { 0xea, 0 } }, /* 06a */ + { .mk = { 0x6b, 0 }, .brk = { 0xeb, 0 } }, /* 06b */ + { .mk = { 0x6c, 0 }, .brk = { 0xec, 0 } }, /* 06c */ + { .mk = { 0x6d, 0 }, .brk = { 0xed, 0 } }, /* 06d */ + { .mk = { 0x6e, 0 }, .brk = { 0xee, 0 } }, /* 06e */ + { .mk = { 0x6f, 0 }, .brk = { 0xef, 0 } }, /* 06f */ + { .mk = { 0x70, 0 }, .brk = { 0xf0, 0 } }, /* 070 */ + { .mk = { 0x71, 0 }, .brk = { 0xf1, 0 } }, /* 071 */ + { .mk = { 0x72, 0 }, .brk = { 0xf2, 0 } }, /* 072 */ + { .mk = { 0x73, 0 }, .brk = { 0xf3, 0 } }, /* 073 */ + { .mk = { 0x74, 0 }, .brk = { 0xf4, 0 } }, /* 074 */ + { .mk = { 0x75, 0 }, .brk = { 0xf5, 0 } }, /* 075 */ + { .mk = { 0x76, 0 }, .brk = { 0xf6, 0 } }, /* 076 */ + { .mk = { 0x77, 0 }, .brk = { 0xf7, 0 } }, /* 077 */ + { .mk = { 0x78, 0 }, .brk = { 0xf8, 0 } }, /* 078 */ + { .mk = { 0x79, 0 }, .brk = { 0xf9, 0 } }, /* 079 */ + { .mk = { 0x7a, 0 }, .brk = { 0xfa, 0 } }, /* 07a */ + { .mk = { 0x7b, 0 }, .brk = { 0xfb, 0 } }, /* 07b */ + { .mk = { 0x7c, 0 }, .brk = { 0xfc, 0 } }, /* 07c */ + { .mk = { 0x7d, 0 }, .brk = { 0xfd, 0 } }, /* 07d */ + { .mk = { 0x7e, 0 }, .brk = { 0xfe, 0 } }, /* 07e */ + { .mk = { 0x7f, 0 }, .brk = { 0xff, 0 } }, /* 07f */ + { .mk = { 0x80, 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0x81, 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0x82, 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0x85, 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0x86, 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0x87, 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0x88, 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0x89, 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0x8a, 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0x8b, 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0x8c, 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0x8d, 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0x8e, 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0x8f, 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0x90, 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0x91, 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0x92, 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0x93, 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0x94, 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0x95, 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0x96, 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0x97, 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0x98, 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0x99, 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0x9a, 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0x9b, 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0x9c, 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0x9d, 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0x9e, 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0x9f, 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0xa0, 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0xa1, 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0xa2, 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0xa3, 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0xa4, 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0xa5, 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0xa6, 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0xa7, 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0xa8, 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0xa9, 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0xaa, 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0xab, 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0xac, 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0xad, 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0xae, 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0xaf, 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0xb0, 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0xb1, 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0xb2, 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0xb3, 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0xb4, 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0xb5, 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0xb6, 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0xb7, 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0xb8, 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0xb9, 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0xba, 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0xbb, 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0xbc, 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0xbd, 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0xbe, 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0xbf, 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0xc0, 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0xc1, 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0xc2, 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0xc3, 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0xc4, 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0xc5, 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0xc6, 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0xc7, 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0xc8, 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0xc9, 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0xca, 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0xcb, 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0xcc, 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0xcd, 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0xce, 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0xcf, 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0xd0, 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0xd1, 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0xd2, 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0xd3, 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0xd4, 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0xd5, 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0xd6, 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0xd7, 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0xd8, 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0xd9, 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0xda, 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0xdb, 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0xdc, 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0xdd, 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0xde, 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0xdf, 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0xe0, 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0xe1, 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0xe2, 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0xe3, 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0xe4, 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0xe5, 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0xe6, 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0xe7, 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0xe8, 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0xe9, 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0xea, 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0xeb, 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0xec, 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0xed, 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0xee, 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0xef, 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0xf3, 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0xf4, 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0xf5, 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0xf6, 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0xf7, 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0xf8, 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0xf9, 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0xfa, 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0xfb, 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0xfc, 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0xfd, 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0xfe, 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0xff, 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = {0xe1, 0x1d, 0 }, .brk = { 0xe1, 0x9d, 0 } }, /* 100 */ + { .mk = {0xe0, 0x01, 0 }, .brk = { 0xe0, 0x81, 0 } }, /* 101 */ + { .mk = {0xe0, 0x02, 0 }, .brk = { 0xe0, 0x82, 0 } }, /* 102 */ + { .mk = {0xe0, 0x03, 0 }, .brk = { 0xe0, 0x83, 0 } }, /* 103 */ + { .mk = {0xe0, 0x04, 0 }, .brk = { 0xe0, 0x84, 0 } }, /* 104 */ + { .mk = {0xe0, 0x05, 0 }, .brk = { 0xe0, 0x85, 0 } }, /* 105 */ + { .mk = {0xe0, 0x06, 0 }, .brk = { 0xe0, 0x86, 0 } }, /* 106 */ + { .mk = {0xe0, 0x07, 0 }, .brk = { 0xe0, 0x87, 0 } }, /* 107 */ + { .mk = {0xe0, 0x08, 0 }, .brk = { 0xe0, 0x88, 0 } }, /* 108 */ + { .mk = {0xe0, 0x09, 0 }, .brk = { 0xe0, 0x89, 0 } }, /* 109 */ + { .mk = {0xe0, 0x0a, 0 }, .brk = { 0xe0, 0x8a, 0 } }, /* 10a */ + { .mk = {0xe0, 0x0b, 0 }, .brk = { 0xe0, 0x8b, 0 } }, /* 10b */ + { .mk = {0xe0, 0x0c, 0 }, .brk = { 0xe0, 0x8c, 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = {0xe0, 0x0e, 0 }, .brk = { 0xe0, 0x8e, 0 } }, /* 10e */ + { .mk = {0xe0, 0x0f, 0 }, .brk = { 0xe0, 0x8f, 0 } }, /* 10f */ + { .mk = {0xe0, 0x10, 0 }, .brk = { 0xe0, 0x90, 0 } }, /* 110 */ + { .mk = {0xe0, 0x11, 0 }, .brk = { 0xe0, 0x91, 0 } }, /* 111 */ + { .mk = {0xe0, 0x12, 0 }, .brk = { 0xe0, 0x92, 0 } }, /* 112 */ + { .mk = {0xe0, 0x13, 0 }, .brk = { 0xe0, 0x93, 0 } }, /* 113 */ + { .mk = {0xe0, 0x14, 0 }, .brk = { 0xe0, 0x94, 0 } }, /* 114 */ + { .mk = {0xe0, 0x15, 0 }, .brk = { 0xe0, 0x95, 0 } }, /* 115 */ + { .mk = {0xe0, 0x16, 0 }, .brk = { 0xe0, 0x96, 0 } }, /* 116 */ + { .mk = {0xe0, 0x17, 0 }, .brk = { 0xe0, 0x97, 0 } }, /* 117 */ + { .mk = {0xe0, 0x18, 0 }, .brk = { 0xe0, 0x98, 0 } }, /* 118 */ + { .mk = {0xe0, 0x19, 0 }, .brk = { 0xe0, 0x99, 0 } }, /* 119 */ + { .mk = {0xe0, 0x1a, 0 }, .brk = { 0xe0, 0x9a, 0 } }, /* 11a */ + { .mk = {0xe0, 0x1b, 0 }, .brk = { 0xe0, 0x9b, 0 } }, /* 11b */ + { .mk = {0xe0, 0x1c, 0 }, .brk = { 0xe0, 0x9c, 0 } }, /* 11c */ + { .mk = {0xe0, 0x1d, 0 }, .brk = { 0xe0, 0x9d, 0 } }, /* 11d */ + { .mk = {0xe0, 0x1e, 0 }, .brk = { 0xe0, 0x9e, 0 } }, /* 11e */ + { .mk = {0xe0, 0x1f, 0 }, .brk = { 0xe0, 0x9f, 0 } }, /* 11f */ + { .mk = {0xe0, 0x20, 0 }, .brk = { 0xe0, 0xa0, 0 } }, /* 120 */ + { .mk = {0xe0, 0x21, 0 }, .brk = { 0xe0, 0xa1, 0 } }, /* 121 */ + { .mk = {0xe0, 0x22, 0 }, .brk = { 0xe0, 0xa2, 0 } }, /* 122 */ + { .mk = {0xe0, 0x23, 0 }, .brk = { 0xe0, 0xa3, 0 } }, /* 123 */ + { .mk = {0xe0, 0x24, 0 }, .brk = { 0xe0, 0xa4, 0 } }, /* 124 */ + { .mk = {0xe0, 0x25, 0 }, .brk = { 0xe0, 0xa5, 0 } }, /* 125 */ + { .mk = {0xe0, 0x26, 0 }, .brk = { 0xe0, 0xa6, 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = {0xe0, 0x2c, 0 }, .brk = { 0xe0, 0xac, 0 } }, /* 12c */ + { .mk = {0xe0, 0x2d, 0 }, .brk = { 0xe0, 0xad, 0 } }, /* 12d */ + { .mk = {0xe0, 0x2e, 0 }, .brk = { 0xe0, 0xae, 0 } }, /* 12e */ + { .mk = {0xe0, 0x2f, 0 }, .brk = { 0xe0, 0xaf, 0 } }, /* 12f */ + { .mk = {0xe0, 0x30, 0 }, .brk = { 0xe0, 0xb0, 0 } }, /* 130 */ + { .mk = {0xe0, 0x31, 0 }, .brk = { 0xe0, 0xb1, 0 } }, /* 131 */ + { .mk = {0xe0, 0x32, 0 }, .brk = { 0xe0, 0xb2, 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = {0xe0, 0x34, 0 }, .brk = { 0xe0, 0xb4, 0 } }, /* 134 */ + { .mk = {0xe0, 0x35, 0 }, .brk = { 0xe0, 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = {0xe0, 0x37, 0 }, .brk = { 0xe0, 0xb7, 0 } }, /* 137 */ + { .mk = {0xe0, 0x38, 0 }, .brk = { 0xe0, 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = {0xe0, 0x3a, 0 }, .brk = { 0xe0, 0xba, 0 } }, /* 13a */ + { .mk = {0xe0, 0x3b, 0 }, .brk = { 0xe0, 0xbb, 0 } }, /* 13b */ + { .mk = {0xe0, 0x3c, 0 }, .brk = { 0xe0, 0xbc, 0 } }, /* 13c */ + { .mk = {0xe0, 0x3d, 0 }, .brk = { 0xe0, 0xbd, 0 } }, /* 13d */ + { .mk = {0xe0, 0x3e, 0 }, .brk = { 0xe0, 0xbe, 0 } }, /* 13e */ + { .mk = {0xe0, 0x3f, 0 }, .brk = { 0xe0, 0xbf, 0 } }, /* 13f */ + { .mk = {0xe0, 0x40, 0 }, .brk = { 0xe0, 0xc0, 0 } }, /* 140 */ + { .mk = {0xe0, 0x41, 0 }, .brk = { 0xe0, 0xc1, 0 } }, /* 141 */ + { .mk = {0xe0, 0x42, 0 }, .brk = { 0xe0, 0xc2, 0 } }, /* 142 */ + { .mk = {0xe0, 0x43, 0 }, .brk = { 0xe0, 0xc3, 0 } }, /* 143 */ + { .mk = {0xe0, 0x44, 0 }, .brk = { 0xe0, 0xc4, 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = {0xe0, 0x46, 0 }, .brk = { 0xe0, 0xc6, 0 } }, /* 146 */ + { .mk = {0xe0, 0x47, 0 }, .brk = { 0xe0, 0xc7, 0 } }, /* 147 */ + { .mk = {0xe0, 0x48, 0 }, .brk = { 0xe0, 0xc8, 0 } }, /* 148 */ + { .mk = {0xe0, 0x49, 0 }, .brk = { 0xe0, 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = {0xe0, 0x4b, 0 }, .brk = { 0xe0, 0xcb, 0 } }, /* 14b */ + { .mk = {0xe0, 0x4c, 0 }, .brk = { 0xe0, 0xcc, 0 } }, /* 14c */ + { .mk = {0xe0, 0x4d, 0 }, .brk = { 0xe0, 0xcd, 0 } }, /* 14d */ + { .mk = {0xe0, 0x4e, 0 }, .brk = { 0xe0, 0xce, 0 } }, /* 14e */ + { .mk = {0xe0, 0x4f, 0 }, .brk = { 0xe0, 0xcf, 0 } }, /* 14f */ + { .mk = {0xe0, 0x50, 0 }, .brk = { 0xe0, 0xd0, 0 } }, /* 150 */ + { .mk = {0xe0, 0x51, 0 }, .brk = { 0xe0, 0xd1, 0 } }, /* 151 */ + { .mk = {0xe0, 0x52, 0 }, .brk = { 0xe0, 0xd2, 0 } }, /* 152 */ + { .mk = {0xe0, 0x53, 0 }, .brk = { 0xe0, 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = {0xe0, 0x55, 0 }, .brk = { 0xe0, 0xd5, 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xd7, 0 } }, /* 157 */ + { .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xd8, 0 } }, /* 158 */ + { .mk = {0xe0, 0x59, 0 }, .brk = { 0xe0, 0xd9, 0 } }, /* 159 */ + { .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xaa, 0 } }, /* 15a */ + { .mk = {0xe0, 0x5b, 0 }, .brk = { 0xe0, 0xdb, 0 } }, /* 15b */ + { .mk = {0xe0, 0x5c, 0 }, .brk = { 0xe0, 0xdc, 0 } }, /* 15c */ + { .mk = {0xe0, 0x5d, 0 }, .brk = { 0xe0, 0xdd, 0 } }, /* 15d */ + { .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 15e */ + { .mk = {0xe0, 0x5f, 0 }, .brk = { 0xe0, 0xdf, 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = {0xe0, 0x61, 0 }, .brk = { 0xe0, 0xe1, 0 } }, /* 161 */ + { .mk = {0xe0, 0x62, 0 }, .brk = { 0xe0, 0xe2, 0 } }, /* 162 */ + { .mk = {0xe0, 0x63, 0 }, .brk = { 0xe0, 0xe3, 0 } }, /* 163 */ + { .mk = {0xe0, 0x64, 0 }, .brk = { 0xe0, 0xe4, 0 } }, /* 164 */ + { .mk = {0xe0, 0x65, 0 }, .brk = { 0xe0, 0xe5, 0 } }, /* 165 */ + { .mk = {0xe0, 0x66, 0 }, .brk = { 0xe0, 0xe6, 0 } }, /* 166 */ + { .mk = {0xe0, 0x67, 0 }, .brk = { 0xe0, 0xe7, 0 } }, /* 167 */ + { .mk = {0xe0, 0x68, 0 }, .brk = { 0xe0, 0xe8, 0 } }, /* 168 */ + { .mk = {0xe0, 0x69, 0 }, .brk = { 0xe0, 0xe9, 0 } }, /* 169 */ + { .mk = {0xe0, 0x6a, 0 }, .brk = { 0xe0, 0xea, 0 } }, /* 16a */ + { .mk = {0xe0, 0x6b, 0 }, .brk = { 0xe0, 0xeb, 0 } }, /* 16b */ + { .mk = {0xe0, 0x6c, 0 }, .brk = { 0xe0, 0xec, 0 } }, /* 16c */ + { .mk = {0xe0, 0x6d, 0 }, .brk = { 0xe0, 0xed, 0 } }, /* 16d */ + { .mk = {0xe0, 0x6e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = {0xe0, 0x70, 0 }, .brk = { 0xe0, 0xf0, 0 } }, /* 170 */ + { .mk = {0xe0, 0x71, 0 }, .brk = { 0xe0, 0xf1, 0 } }, /* 171 */ + { .mk = {0xe0, 0x72, 0 }, .brk = { 0xe0, 0xf2, 0 } }, /* 172 */ + { .mk = {0xe0, 0x73, 0 }, .brk = { 0xe0, 0xf3, 0 } }, /* 173 */ + { .mk = {0xe0, 0x74, 0 }, .brk = { 0xe0, 0xf4, 0 } }, /* 174 */ + { .mk = {0xe0, 0x75, 0 }, .brk = { 0xe0, 0xf5, 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = {0xe0, 0x77, 0 }, .brk = { 0xe0, 0xf7, 0 } }, /* 177 */ + { .mk = {0xe0, 0x78, 0 }, .brk = { 0xe0, 0xf8, 0 } }, /* 178 */ + { .mk = {0xe0, 0x79, 0 }, .brk = { 0xe0, 0xf9, 0 } }, /* 179 */ + { .mk = {0xe0, 0x7a, 0 }, .brk = { 0xe0, 0xfa, 0 } }, /* 17a */ + { .mk = {0xe0, 0x7b, 0 }, .brk = { 0xe0, 0xfb, 0 } }, /* 17b */ + { .mk = {0xe0, 0x7c, 0 }, .brk = { 0xe0, 0xfc, 0 } }, /* 17c */ + { .mk = {0xe0, 0x7d, 0 }, .brk = { 0xe0, 0xfd, 0 } }, /* 17d */ + { .mk = {0xe0, 0x7e, 0 }, .brk = { 0xe0, 0xfe, 0 } }, /* 17e */ + { .mk = {0xe0, 0x7f, 0 }, .brk = { 0xe0, 0xff, 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = {0xe0, 0xe1, 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = {0xe0, 0xee, 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = {0xe0, 0xf1, 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = {0xe0, 0xfe, 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = {0xe0, 0xff, 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; static const scancode scancode_set2[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x76, 0 }, { 0xF0, 0x76, 0 } }, /* 001 */ - { { 0x16, 0 }, { 0xF0, 0x16, 0 } }, /* 002 */ - { { 0x1E, 0 }, { 0xF0, 0x1E, 0 } }, /* 003 */ - { { 0x26, 0 }, { 0xF0, 0x26, 0 } }, /* 004 */ - { { 0x25, 0 }, { 0xF0, 0x25, 0 } }, /* 005 */ - { { 0x2E, 0 }, { 0xF0, 0x2E, 0 } }, /* 006 */ - { { 0x36, 0 }, { 0xF0, 0x36, 0 } }, /* 007 */ - { { 0x3D, 0 }, { 0xF0, 0x3D, 0 } }, /* 008 */ - { { 0x3E, 0 }, { 0xF0, 0x3E, 0 } }, /* 009 */ - { { 0x46, 0 }, { 0xF0, 0x46, 0 } }, /* 00a */ - { { 0x45, 0 }, { 0xF0, 0x45, 0 } }, /* 00b */ - { { 0x4E, 0 }, { 0xF0, 0x4E, 0 } }, /* 00c */ - { { 0x55, 0 }, { 0xF0, 0x55, 0 } }, /* 00d */ - { { 0x66, 0 }, { 0xF0, 0x66, 0 } }, /* 00e */ - { { 0x0D, 0 }, { 0xF0, 0x0D, 0 } }, /* 00f */ - { { 0x15, 0 }, { 0xF0, 0x15, 0 } }, /* 010 */ - { { 0x1D, 0 }, { 0xF0, 0x1D, 0 } }, /* 011 */ - { { 0x24, 0 }, { 0xF0, 0x24, 0 } }, /* 012 */ - { { 0x2D, 0 }, { 0xF0, 0x2D, 0 } }, /* 013 */ - { { 0x2C, 0 }, { 0xF0, 0x2C, 0 } }, /* 014 */ - { { 0x35, 0 }, { 0xF0, 0x35, 0 } }, /* 015 */ - { { 0x3C, 0 }, { 0xF0, 0x3C, 0 } }, /* 016 */ - { { 0x43, 0 }, { 0xF0, 0x43, 0 } }, /* 017 */ - { { 0x44, 0 }, { 0xF0, 0x44, 0 } }, /* 018 */ - { { 0x4D, 0 }, { 0xF0, 0x4D, 0 } }, /* 019 */ - { { 0x54, 0 }, { 0xF0, 0x54, 0 } }, /* 01a */ - { { 0x5B, 0 }, { 0xF0, 0x5B, 0 } }, /* 01b */ - { { 0x5A, 0 }, { 0xF0, 0x5A, 0 } }, /* 01c */ - { { 0x14, 0 }, { 0xF0, 0x14, 0 } }, /* 01d */ - { { 0x1C, 0 }, { 0xF0, 0x1C, 0 } }, /* 01e */ - { { 0x1B, 0 }, { 0xF0, 0x1B, 0 } }, /* 01f */ - { { 0x23, 0 }, { 0xF0, 0x23, 0 } }, /* 020 */ - { { 0x2B, 0 }, { 0xF0, 0x2B, 0 } }, /* 021 */ - { { 0x34, 0 }, { 0xF0, 0x34, 0 } }, /* 022 */ - { { 0x33, 0 }, { 0xF0, 0x33, 0 } }, /* 023 */ - { { 0x3B, 0 }, { 0xF0, 0x3B, 0 } }, /* 024 */ - { { 0x42, 0 }, { 0xF0, 0x42, 0 } }, /* 025 */ - { { 0x4B, 0 }, { 0xF0, 0x4B, 0 } }, /* 026 */ - { { 0x4C, 0 }, { 0xF0, 0x4C, 0 } }, /* 027 */ - { { 0x52, 0 }, { 0xF0, 0x52, 0 } }, /* 028 */ - { { 0x0E, 0 }, { 0xF0, 0x0E, 0 } }, /* 029 */ - { { 0x12, 0 }, { 0xF0, 0x12, 0 } }, /* 02a */ - { { 0x5D, 0 }, { 0xF0, 0x5D, 0 } }, /* 02b */ - { { 0x1A, 0 }, { 0xF0, 0x1A, 0 } }, /* 02c */ - { { 0x22, 0 }, { 0xF0, 0x22, 0 } }, /* 02d */ - { { 0x21, 0 }, { 0xF0, 0x21, 0 } }, /* 02e */ - { { 0x2A, 0 }, { 0xF0, 0x2A, 0 } }, /* 02f */ - { { 0x32, 0 }, { 0xF0, 0x32, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xF0, 0x31, 0 } }, /* 031 */ - { { 0x3A, 0 }, { 0xF0, 0x3A, 0 } }, /* 032 */ - { { 0x41, 0 }, { 0xF0, 0x41, 0 } }, /* 033 */ - { { 0x49, 0 }, { 0xF0, 0x49, 0 } }, /* 034 */ - { { 0x4A, 0 }, { 0xF0, 0x4A, 0 } }, /* 035 */ - { { 0x59, 0 }, { 0xF0, 0x59, 0 } }, /* 036 */ - { { 0x7C, 0 }, { 0xF0, 0x7C, 0 } }, /* 037 */ - { { 0x11, 0 }, { 0xF0, 0x11, 0 } }, /* 038 */ - { { 0x29, 0 }, { 0xF0, 0x29, 0 } }, /* 039 */ - { { 0x58, 0 }, { 0xF0, 0x58, 0 } }, /* 03a */ - { { 0x05, 0 }, { 0xF0, 0x05, 0 } }, /* 03b */ - { { 0x06, 0 }, { 0xF0, 0x06, 0 } }, /* 03c */ - { { 0x04, 0 }, { 0xF0, 0x04, 0 } }, /* 03d */ - { { 0x0C, 0 }, { 0xF0, 0x0C, 0 } }, /* 03e */ - { { 0x03, 0 }, { 0xF0, 0x03, 0 } }, /* 03f */ - { { 0x0B, 0 }, { 0xF0, 0x0B, 0 } }, /* 040 */ - { { 0x83, 0 }, { 0xF0, 0x83, 0 } }, /* 041 */ - { { 0x0A, 0 }, { 0xF0, 0x0A, 0 } }, /* 042 */ - { { 0x01, 0 }, { 0xF0, 0x01, 0 } }, /* 043 */ - { { 0x09, 0 }, { 0xF0, 0x09, 0 } }, /* 044 */ - { { 0x77, 0 }, { 0xF0, 0x77, 0 } }, /* 045 */ - { { 0x7E, 0 }, { 0xF0, 0x7E, 0 } }, /* 046 */ - { { 0x6C, 0 }, { 0xF0, 0x6C, 0 } }, /* 047 */ - { { 0x75, 0 }, { 0xF0, 0x75, 0 } }, /* 048 */ - { { 0x7D, 0 }, { 0xF0, 0x7D, 0 } }, /* 049 */ - { { 0x7B, 0 }, { 0xF0, 0x7B, 0 } }, /* 04a */ - { { 0x6B, 0 }, { 0xF0, 0x6B, 0 } }, /* 04b */ - { { 0x73, 0 }, { 0xF0, 0x73, 0 } }, /* 04c */ - { { 0x74, 0 }, { 0xF0, 0x74, 0 } }, /* 04d */ - { { 0x79, 0 }, { 0xF0, 0x79, 0 } }, /* 04e */ - { { 0x69, 0 }, { 0xF0, 0x69, 0 } }, /* 04f */ - { { 0x72, 0 }, { 0xF0, 0x72, 0 } }, /* 050 */ - { { 0x7A, 0 }, { 0xF0, 0x7A, 0 } }, /* 051 */ - { { 0x70, 0 }, { 0xF0, 0x70, 0 } }, /* 052 */ - { { 0x71, 0 }, { 0xF0, 0x71, 0 } }, /* 053 */ - { { 0x84, 0 }, { 0xF0, 0x84, 0 } }, /* 054 */ - { { 0x60, 0 }, { 0xF0, 0x60, 0 } }, /* 055 */ - { { 0x61, 0 }, { 0xF0, 0x61, 0 } }, /* 056 */ - { { 0x78, 0 }, { 0xF0, 0x78, 0 } }, /* 057 */ - { { 0x07, 0 }, { 0xF0, 0x07, 0 } }, /* 058 */ - { { 0x0F, 0 }, { 0xF0, 0x0F, 0 } }, /* 059 */ - { { 0x17, 0 }, { 0xF0, 0x17, 0 } }, /* 05a */ - { { 0x1F, 0 }, { 0xF0, 0x1F, 0 } }, /* 05b */ - { { 0x27, 0 }, { 0xF0, 0x27, 0 } }, /* 05c */ - { { 0x2F, 0 }, { 0xF0, 0x2F, 0 } }, /* 05d */ - { { 0x37, 0 }, { 0xF0, 0x37, 0 } }, /* 05e */ - { { 0x3F, 0 }, { 0xF0, 0x3F, 0 } }, /* 05f */ - { { 0x47, 0 }, { 0xF0, 0x47, 0 } }, /* 060 */ - { { 0x4F, 0 }, { 0xF0, 0x4F, 0 } }, /* 061 */ - { { 0x56, 0 }, { 0xF0, 0x56, 0 } }, /* 062 */ - { { 0x5E, 0 }, { 0xF0, 0x5E, 0 } }, /* 063 */ - { { 0x08, 0 }, { 0xF0, 0x08, 0 } }, /* 064 */ - { { 0x10, 0 }, { 0xF0, 0x10, 0 } }, /* 065 */ - { { 0x18, 0 }, { 0xF0, 0x18, 0 } }, /* 066 */ - { { 0x20, 0 }, { 0xF0, 0x20, 0 } }, /* 067 */ - { { 0x28, 0 }, { 0xF0, 0x28, 0 } }, /* 068 */ - { { 0x30, 0 }, { 0xF0, 0x30, 0 } }, /* 069 */ - { { 0x38, 0 }, { 0xF0, 0x38, 0 } }, /* 06a */ - { { 0x40, 0 }, { 0xF0, 0x40, 0 } }, /* 06b */ - { { 0x48, 0 }, { 0xF0, 0x48, 0 } }, /* 06c */ - { { 0x50, 0 }, { 0xF0, 0x50, 0 } }, /* 06d */ - { { 0x57, 0 }, { 0xF0, 0x57, 0 } }, /* 06e */ - { { 0x6F, 0 }, { 0xF0, 0x6F, 0 } }, /* 06f */ - { { 0x13, 0 }, { 0xF0, 0x13, 0 } }, /* 070 */ - { { 0x19, 0 }, { 0xF0, 0x19, 0 } }, /* 071 */ - { { 0x39, 0 }, { 0xF0, 0x39, 0 } }, /* 072 */ - { { 0x51, 0 }, { 0xF0, 0x51, 0 } }, /* 073 */ - { { 0x53, 0 }, { 0xF0, 0x53, 0 } }, /* 074 */ - { { 0x5C, 0 }, { 0xF0, 0x5C, 0 } }, /* 075 */ - { { 0x5F, 0 }, { 0xF0, 0x5F, 0 } }, /* 076 */ - { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 077 */ - { { 0x63, 0 }, { 0xF0, 0x63, 0 } }, /* 078 */ - { { 0x64, 0 }, { 0xF0, 0x64, 0 } }, /* 079 */ - { { 0x65, 0 }, { 0xF0, 0x65, 0 } }, /* 07a */ - { { 0x67, 0 }, { 0xF0, 0x67, 0 } }, /* 07b */ - { { 0x68, 0 }, { 0xF0, 0x68, 0 } }, /* 07c */ - { { 0x6A, 0 }, { 0xF0, 0x6A, 0 } }, /* 07d */ - { { 0x6D, 0 }, { 0xF0, 0x6D, 0 } }, /* 07e */ - { { 0x6E, 0 }, { 0xF0, 0x6E, 0 } }, /* 07f */ - { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, /* 080 */ - { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 081 */ - { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, /* 085 */ - { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 086 */ - { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 087 */ - { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, /* 088 */ - { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, /* 089 */ - { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, /* 08a */ - { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 08b */ - { { 0x8c, 0 }, { 0xf0, 0x8c, 0 } }, /* 08c */ - { { 0x8d, 0 }, { 0xf0, 0x8d, 0 } }, /* 08d */ - { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, /* 08e */ - { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08f */ - { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, /* 090 */ - { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, /* 091 */ - { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, /* 092 */ - { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 093 */ - { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, /* 094 */ - { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, /* 095 */ - { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, /* 096 */ - { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 097 */ - { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, /* 098 */ - { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, /* 099 */ - { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, /* 09a */ - { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 09b */ - { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, /* 09c */ - { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, /* 09d */ - { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, /* 09e */ - { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09f */ - { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, /* 0a0 */ - { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, /* 0a1 */ - { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, /* 0a2 */ - { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a3 */ - { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, /* 0a4 */ - { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, /* 0a5 */ - { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, /* 0a6 */ - { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a7 */ - { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, /* 0a8 */ - { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, /* 0a9 */ - { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, /* 0aa */ - { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0ab */ - { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, /* 0ac */ - { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, /* 0ad */ - { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, /* 0ae */ - { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0af */ - { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, /* 0b0 */ - { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, /* 0b1 */ - { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, /* 0b2 */ - { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b3 */ - { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, /* 0b4 */ - { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, /* 0b5 */ - { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, /* 0b6 */ - { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b7 */ - { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, /* 0b8 */ - { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, /* 0b9 */ - { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, /* 0ba */ - { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0bb */ - { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, /* 0bc */ - { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, /* 0bd */ - { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, /* 0be */ - { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bf */ - { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, /* 0c0 */ - { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, /* 0c1 */ - { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, /* 0c2 */ - { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c3 */ - { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, /* 0c4 */ - { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, /* 0c5 */ - { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, /* 0c6 */ - { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c7 */ - { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, /* 0c8 */ - { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, /* 0c9 */ - { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, /* 0ca */ - { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0cb */ - { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, /* 0cc */ - { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, /* 0cd */ - { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, /* 0ce */ - { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cf */ - { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d0 */ - { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d1 */ - { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, /* 0d2 */ - { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d3 */ - { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, /* 0d4 */ - { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, /* 0d5 */ - { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, /* 0d6 */ - { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d7 */ - { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, /* 0d8 */ - { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, /* 0d9 */ - { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, /* 0da */ - { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0db */ - { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, /* 0dc */ - { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, /* 0dd */ - { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, /* 0de */ - { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0df */ - { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, /* 0e0 */ - { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, /* 0e1 */ - { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, /* 0e2 */ - { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e3 */ - { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, /* 0e4 */ - { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, /* 0e5 */ - { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, /* 0e6 */ - { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e7 */ - { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, /* 0e8 */ - { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, /* 0e9 */ - { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, /* 0ea */ - { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0eb */ - { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, /* 0ec */ - { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, /* 0ed */ - { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, /* 0ee */ - { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, /* 0f1 */ - { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, /* 0f2 */ - { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f3 */ - { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, /* 0f4 */ - { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, /* 0f5 */ - { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, /* 0f6 */ - { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f7 */ - { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, /* 0f8 */ - { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, /* 0f9 */ - { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, /* 0fa */ - { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0fb */ - { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, /* 0fc */ - { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, /* 0fd */ - { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, /* 0fe */ - { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0ff */ - { { 0xe1, 0x14, 0 }, { 0xe1, 0xf0, 0x14, 0 } }, /* 100 */ - { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ - { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ - { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ - { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ - { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ - { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ - { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ - { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ - { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ - { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ - { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, /* 112 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, /* 113 */ - { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ - { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ - { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ - { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ - { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ - { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ - { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ - { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ - { { 0xe0, 0x5A, 0 }, { 0xe0, 0xF0, 0x5A, 0 } }, /* 11c */ - { { 0xe0, 0x14, 0 }, { 0xe0, 0xF0, 0x14, 0 } }, /* 11d */ - { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ - { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ - { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ - { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ - { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ - { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ - { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ - { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ - { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ - { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ - { { 0xe0, 0x4A, 0 }, { 0xe0, 0xF0, 0x4A, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0xe0, 0x7C, 0 }, { 0xe0, 0xF0, 0x7C, 0 } }, /* 137 */ - { { 0xe0, 0x11, 0 }, { 0xe0, 0xF0, 0x11, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ - { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ - { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ - { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ - { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ - { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ - { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ - { { 0xe0, 0x6C, 0 }, { 0xe0, 0xF0, 0x6C, 0 } }, /* 147 */ - { { 0xe0, 0x75, 0 }, { 0xe0, 0xF0, 0x75, 0 } }, /* 148 */ - { { 0xe0, 0x7D, 0 }, { 0xe0, 0xF0, 0x7D, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0xe0, 0x6B, 0 }, { 0xe0, 0xF0, 0x6B, 0 } }, /* 14b */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ - { { 0xe0, 0x74, 0 }, { 0xe0, 0xF0, 0x74, 0 } }, /* 14d */ - { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ - { { 0xe0, 0x69, 0 }, { 0xe0, 0xF0, 0x69, 0 } }, /* 14f */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xF0, 0x72, 0 } }, /* 150 */ - { { 0xe0, 0x7A, 0 }, { 0xe0, 0xF0, 0x7A, 0 } }, /* 151 */ - { { 0xe0, 0x70, 0 }, { 0xe0, 0xF0, 0x70, 0 } }, /* 152 */ - { { 0xe0, 0x71, 0 }, { 0xe0, 0xF0, 0x71, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ - { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ - { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ - { { 0xe0, 0x1F, 0 }, { 0xe0, 0xF0, 0x1F, 0 } }, /* 15b */ - { { 0xe0, 0x27, 0 }, { 0xe0, 0xF0, 0x27, 0 } }, /* 15c */ - { { 0xe0, 0x2F, 0 }, { 0xe0, 0xF0, 0x2F, 0 } }, /* 15d */ - { { 0xe0, 0x37, 0 }, { 0xe0, 0xF0, 0x37, 0 } }, /* 15e */ - { { 0xe0, 0x3F, 0 }, { 0xe0, 0xF0, 0x3F, 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ - { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ - { { 0xe0, 0x5E, 0 }, { 0xe0, 0xF0, 0x5E, 0 } }, /* 163 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ - { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ - { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ - { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ - { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ - { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ - { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ - { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ - { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ - { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ - { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ - { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cv */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ - { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x76, 0 }, .brk = { 0xF0, 0x76, 0 } }, /* 001 */ + { .mk = { 0x16, 0 }, .brk = { 0xF0, 0x16, 0 } }, /* 002 */ + { .mk = { 0x1E, 0 }, .brk = { 0xF0, 0x1E, 0 } }, /* 003 */ + { .mk = { 0x26, 0 }, .brk = { 0xF0, 0x26, 0 } }, /* 004 */ + { .mk = { 0x25, 0 }, .brk = { 0xF0, 0x25, 0 } }, /* 005 */ + { .mk = { 0x2E, 0 }, .brk = { 0xF0, 0x2E, 0 } }, /* 006 */ + { .mk = { 0x36, 0 }, .brk = { 0xF0, 0x36, 0 } }, /* 007 */ + { .mk = { 0x3D, 0 }, .brk = { 0xF0, 0x3D, 0 } }, /* 008 */ + { .mk = { 0x3E, 0 }, .brk = { 0xF0, 0x3E, 0 } }, /* 009 */ + { .mk = { 0x46, 0 }, .brk = { 0xF0, 0x46, 0 } }, /* 00a */ + { .mk = { 0x45, 0 }, .brk = { 0xF0, 0x45, 0 } }, /* 00b */ + { .mk = { 0x4E, 0 }, .brk = { 0xF0, 0x4E, 0 } }, /* 00c */ + { .mk = { 0x55, 0 }, .brk = { 0xF0, 0x55, 0 } }, /* 00d */ + { .mk = { 0x66, 0 }, .brk = { 0xF0, 0x66, 0 } }, /* 00e */ + { .mk = { 0x0D, 0 }, .brk = { 0xF0, 0x0D, 0 } }, /* 00f */ + { .mk = { 0x15, 0 }, .brk = { 0xF0, 0x15, 0 } }, /* 010 */ + { .mk = { 0x1D, 0 }, .brk = { 0xF0, 0x1D, 0 } }, /* 011 */ + { .mk = { 0x24, 0 }, .brk = { 0xF0, 0x24, 0 } }, /* 012 */ + { .mk = { 0x2D, 0 }, .brk = { 0xF0, 0x2D, 0 } }, /* 013 */ + { .mk = { 0x2C, 0 }, .brk = { 0xF0, 0x2C, 0 } }, /* 014 */ + { .mk = { 0x35, 0 }, .brk = { 0xF0, 0x35, 0 } }, /* 015 */ + { .mk = { 0x3C, 0 }, .brk = { 0xF0, 0x3C, 0 } }, /* 016 */ + { .mk = { 0x43, 0 }, .brk = { 0xF0, 0x43, 0 } }, /* 017 */ + { .mk = { 0x44, 0 }, .brk = { 0xF0, 0x44, 0 } }, /* 018 */ + { .mk = { 0x4D, 0 }, .brk = { 0xF0, 0x4D, 0 } }, /* 019 */ + { .mk = { 0x54, 0 }, .brk = { 0xF0, 0x54, 0 } }, /* 01a */ + { .mk = { 0x5B, 0 }, .brk = { 0xF0, 0x5B, 0 } }, /* 01b */ + { .mk = { 0x5A, 0 }, .brk = { 0xF0, 0x5A, 0 } }, /* 01c */ + { .mk = { 0x14, 0 }, .brk = { 0xF0, 0x14, 0 } }, /* 01d */ + { .mk = { 0x1C, 0 }, .brk = { 0xF0, 0x1C, 0 } }, /* 01e */ + { .mk = { 0x1B, 0 }, .brk = { 0xF0, 0x1B, 0 } }, /* 01f */ + { .mk = { 0x23, 0 }, .brk = { 0xF0, 0x23, 0 } }, /* 020 */ + { .mk = { 0x2B, 0 }, .brk = { 0xF0, 0x2B, 0 } }, /* 021 */ + { .mk = { 0x34, 0 }, .brk = { 0xF0, 0x34, 0 } }, /* 022 */ + { .mk = { 0x33, 0 }, .brk = { 0xF0, 0x33, 0 } }, /* 023 */ + { .mk = { 0x3B, 0 }, .brk = { 0xF0, 0x3B, 0 } }, /* 024 */ + { .mk = { 0x42, 0 }, .brk = { 0xF0, 0x42, 0 } }, /* 025 */ + { .mk = { 0x4B, 0 }, .brk = { 0xF0, 0x4B, 0 } }, /* 026 */ + { .mk = { 0x4C, 0 }, .brk = { 0xF0, 0x4C, 0 } }, /* 027 */ + { .mk = { 0x52, 0 }, .brk = { 0xF0, 0x52, 0 } }, /* 028 */ + { .mk = { 0x0E, 0 }, .brk = { 0xF0, 0x0E, 0 } }, /* 029 */ + { .mk = { 0x12, 0 }, .brk = { 0xF0, 0x12, 0 } }, /* 02a */ + { .mk = { 0x5D, 0 }, .brk = { 0xF0, 0x5D, 0 } }, /* 02b */ + { .mk = { 0x1A, 0 }, .brk = { 0xF0, 0x1A, 0 } }, /* 02c */ + { .mk = { 0x22, 0 }, .brk = { 0xF0, 0x22, 0 } }, /* 02d */ + { .mk = { 0x21, 0 }, .brk = { 0xF0, 0x21, 0 } }, /* 02e */ + { .mk = { 0x2A, 0 }, .brk = { 0xF0, 0x2A, 0 } }, /* 02f */ + { .mk = { 0x32, 0 }, .brk = { 0xF0, 0x32, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xF0, 0x31, 0 } }, /* 031 */ + { .mk = { 0x3A, 0 }, .brk = { 0xF0, 0x3A, 0 } }, /* 032 */ + { .mk = { 0x41, 0 }, .brk = { 0xF0, 0x41, 0 } }, /* 033 */ + { .mk = { 0x49, 0 }, .brk = { 0xF0, 0x49, 0 } }, /* 034 */ + { .mk = { 0x4A, 0 }, .brk = { 0xF0, 0x4A, 0 } }, /* 035 */ + { .mk = { 0x59, 0 }, .brk = { 0xF0, 0x59, 0 } }, /* 036 */ + { .mk = { 0x7C, 0 }, .brk = { 0xF0, 0x7C, 0 } }, /* 037 */ + { .mk = { 0x11, 0 }, .brk = { 0xF0, 0x11, 0 } }, /* 038 */ + { .mk = { 0x29, 0 }, .brk = { 0xF0, 0x29, 0 } }, /* 039 */ + { .mk = { 0x58, 0 }, .brk = { 0xF0, 0x58, 0 } }, /* 03a */ + { .mk = { 0x05, 0 }, .brk = { 0xF0, 0x05, 0 } }, /* 03b */ + { .mk = { 0x06, 0 }, .brk = { 0xF0, 0x06, 0 } }, /* 03c */ + { .mk = { 0x04, 0 }, .brk = { 0xF0, 0x04, 0 } }, /* 03d */ + { .mk = { 0x0C, 0 }, .brk = { 0xF0, 0x0C, 0 } }, /* 03e */ + { .mk = { 0x03, 0 }, .brk = { 0xF0, 0x03, 0 } }, /* 03f */ + { .mk = { 0x0B, 0 }, .brk = { 0xF0, 0x0B, 0 } }, /* 040 */ + { .mk = { 0x83, 0 }, .brk = { 0xF0, 0x83, 0 } }, /* 041 */ + { .mk = { 0x0A, 0 }, .brk = { 0xF0, 0x0A, 0 } }, /* 042 */ + { .mk = { 0x01, 0 }, .brk = { 0xF0, 0x01, 0 } }, /* 043 */ + { .mk = { 0x09, 0 }, .brk = { 0xF0, 0x09, 0 } }, /* 044 */ + { .mk = { 0x77, 0 }, .brk = { 0xF0, 0x77, 0 } }, /* 045 */ + { .mk = { 0x7E, 0 }, .brk = { 0xF0, 0x7E, 0 } }, /* 046 */ + { .mk = { 0x6C, 0 }, .brk = { 0xF0, 0x6C, 0 } }, /* 047 */ + { .mk = { 0x75, 0 }, .brk = { 0xF0, 0x75, 0 } }, /* 048 */ + { .mk = { 0x7D, 0 }, .brk = { 0xF0, 0x7D, 0 } }, /* 049 */ + { .mk = { 0x7B, 0 }, .brk = { 0xF0, 0x7B, 0 } }, /* 04a */ + { .mk = { 0x6B, 0 }, .brk = { 0xF0, 0x6B, 0 } }, /* 04b */ + { .mk = { 0x73, 0 }, .brk = { 0xF0, 0x73, 0 } }, /* 04c */ + { .mk = { 0x74, 0 }, .brk = { 0xF0, 0x74, 0 } }, /* 04d */ + { .mk = { 0x79, 0 }, .brk = { 0xF0, 0x79, 0 } }, /* 04e */ + { .mk = { 0x69, 0 }, .brk = { 0xF0, 0x69, 0 } }, /* 04f */ + { .mk = { 0x72, 0 }, .brk = { 0xF0, 0x72, 0 } }, /* 050 */ + { .mk = { 0x7A, 0 }, .brk = { 0xF0, 0x7A, 0 } }, /* 051 */ + { .mk = { 0x70, 0 }, .brk = { 0xF0, 0x70, 0 } }, /* 052 */ + { .mk = { 0x71, 0 }, .brk = { 0xF0, 0x71, 0 } }, /* 053 */ + { .mk = { 0x84, 0 }, .brk = { 0xF0, 0x84, 0 } }, /* 054 */ + { .mk = { 0x60, 0 }, .brk = { 0xF0, 0x60, 0 } }, /* 055 */ + { .mk = { 0x61, 0 }, .brk = { 0xF0, 0x61, 0 } }, /* 056 */ + { .mk = { 0x78, 0 }, .brk = { 0xF0, 0x78, 0 } }, /* 057 */ + { .mk = { 0x07, 0 }, .brk = { 0xF0, 0x07, 0 } }, /* 058 */ + { .mk = { 0x0F, 0 }, .brk = { 0xF0, 0x0F, 0 } }, /* 059 */ + { .mk = { 0x17, 0 }, .brk = { 0xF0, 0x17, 0 } }, /* 05a */ + { .mk = { 0x1F, 0 }, .brk = { 0xF0, 0x1F, 0 } }, /* 05b */ + { .mk = { 0x27, 0 }, .brk = { 0xF0, 0x27, 0 } }, /* 05c */ + { .mk = { 0x2F, 0 }, .brk = { 0xF0, 0x2F, 0 } }, /* 05d */ + { .mk = { 0x37, 0 }, .brk = { 0xF0, 0x37, 0 } }, /* 05e */ + { .mk = { 0x3F, 0 }, .brk = { 0xF0, 0x3F, 0 } }, /* 05f */ + { .mk = { 0x47, 0 }, .brk = { 0xF0, 0x47, 0 } }, /* 060 */ + { .mk = { 0x4F, 0 }, .brk = { 0xF0, 0x4F, 0 } }, /* 061 */ + { .mk = { 0x56, 0 }, .brk = { 0xF0, 0x56, 0 } }, /* 062 */ + { .mk = { 0x5E, 0 }, .brk = { 0xF0, 0x5E, 0 } }, /* 063 */ + { .mk = { 0x08, 0 }, .brk = { 0xF0, 0x08, 0 } }, /* 064 */ + { .mk = { 0x10, 0 }, .brk = { 0xF0, 0x10, 0 } }, /* 065 */ + { .mk = { 0x18, 0 }, .brk = { 0xF0, 0x18, 0 } }, /* 066 */ + { .mk = { 0x20, 0 }, .brk = { 0xF0, 0x20, 0 } }, /* 067 */ + { .mk = { 0x28, 0 }, .brk = { 0xF0, 0x28, 0 } }, /* 068 */ + { .mk = { 0x30, 0 }, .brk = { 0xF0, 0x30, 0 } }, /* 069 */ + { .mk = { 0x38, 0 }, .brk = { 0xF0, 0x38, 0 } }, /* 06a */ + { .mk = { 0x40, 0 }, .brk = { 0xF0, 0x40, 0 } }, /* 06b */ + { .mk = { 0x48, 0 }, .brk = { 0xF0, 0x48, 0 } }, /* 06c */ + { .mk = { 0x50, 0 }, .brk = { 0xF0, 0x50, 0 } }, /* 06d */ + { .mk = { 0x57, 0 }, .brk = { 0xF0, 0x57, 0 } }, /* 06e */ + { .mk = { 0x6F, 0 }, .brk = { 0xF0, 0x6F, 0 } }, /* 06f */ + { .mk = { 0x13, 0 }, .brk = { 0xF0, 0x13, 0 } }, /* 070 */ + { .mk = { 0x19, 0 }, .brk = { 0xF0, 0x19, 0 } }, /* 071 */ + { .mk = { 0x39, 0 }, .brk = { 0xF0, 0x39, 0 } }, /* 072 */ + { .mk = { 0x51, 0 }, .brk = { 0xF0, 0x51, 0 } }, /* 073 */ + { .mk = { 0x53, 0 }, .brk = { 0xF0, 0x53, 0 } }, /* 074 */ + { .mk = { 0x5C, 0 }, .brk = { 0xF0, 0x5C, 0 } }, /* 075 */ + { .mk = { 0x5F, 0 }, .brk = { 0xF0, 0x5F, 0 } }, /* 076 */ + { .mk = { 0x62, 0 }, .brk = { 0xF0, 0x62, 0 } }, /* 077 */ + { .mk = { 0x63, 0 }, .brk = { 0xF0, 0x63, 0 } }, /* 078 */ + { .mk = { 0x64, 0 }, .brk = { 0xF0, 0x64, 0 } }, /* 079 */ + { .mk = { 0x65, 0 }, .brk = { 0xF0, 0x65, 0 } }, /* 07a */ + { .mk = { 0x67, 0 }, .brk = { 0xF0, 0x67, 0 } }, /* 07b */ + { .mk = { 0x68, 0 }, .brk = { 0xF0, 0x68, 0 } }, /* 07c */ + { .mk = { 0x6A, 0 }, .brk = { 0xF0, 0x6A, 0 } }, /* 07d */ + { .mk = { 0x6D, 0 }, .brk = { 0xF0, 0x6D, 0 } }, /* 07e */ + { .mk = { 0x6E, 0 }, .brk = { 0xF0, 0x6E, 0 } }, /* 07f */ + { .mk = { 0x80, 0 }, .brk = { 0xf0, 0x80, 0 } }, /* 080 */ + { .mk = { 0x81, 0 }, .brk = { 0xf0, 0x81, 0 } }, /* 081 */ + { .mk = { 0x82, 0 }, .brk = { 0xf0, 0x82, 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0x85, 0 }, .brk = { 0xf0, 0x54, 0 } }, /* 085 */ + { .mk = { 0x86, 0 }, .brk = { 0xf0, 0x86, 0 } }, /* 086 */ + { .mk = { 0x87, 0 }, .brk = { 0xf0, 0x87, 0 } }, /* 087 */ + { .mk = { 0x88, 0 }, .brk = { 0xf0, 0x88, 0 } }, /* 088 */ + { .mk = { 0x89, 0 }, .brk = { 0xf0, 0x89, 0 } }, /* 089 */ + { .mk = { 0x8a, 0 }, .brk = { 0xf0, 0x8a, 0 } }, /* 08a */ + { .mk = { 0x8b, 0 }, .brk = { 0xf0, 0x8b, 0 } }, /* 08b */ + { .mk = { 0x8c, 0 }, .brk = { 0xf0, 0x8c, 0 } }, /* 08c */ + { .mk = { 0x8d, 0 }, .brk = { 0xf0, 0x8d, 0 } }, /* 08d */ + { .mk = { 0x8e, 0 }, .brk = { 0xf0, 0x8e, 0 } }, /* 08e */ + { .mk = { 0x8f, 0 }, .brk = { 0xf0, 0x8f, 0 } }, /* 08f */ + { .mk = { 0x90, 0 }, .brk = { 0xf0, 0x90, 0 } }, /* 090 */ + { .mk = { 0x91, 0 }, .brk = { 0xf0, 0x91, 0 } }, /* 091 */ + { .mk = { 0x92, 0 }, .brk = { 0xf0, 0x92, 0 } }, /* 092 */ + { .mk = { 0x93, 0 }, .brk = { 0xf0, 0x93, 0 } }, /* 093 */ + { .mk = { 0x94, 0 }, .brk = { 0xf0, 0x94, 0 } }, /* 094 */ + { .mk = { 0x95, 0 }, .brk = { 0xf0, 0x95, 0 } }, /* 095 */ + { .mk = { 0x96, 0 }, .brk = { 0xf0, 0x96, 0 } }, /* 096 */ + { .mk = { 0x97, 0 }, .brk = { 0xf0, 0x97, 0 } }, /* 097 */ + { .mk = { 0x98, 0 }, .brk = { 0xf0, 0x98, 0 } }, /* 098 */ + { .mk = { 0x99, 0 }, .brk = { 0xf0, 0x99, 0 } }, /* 099 */ + { .mk = { 0x9a, 0 }, .brk = { 0xf0, 0x9a, 0 } }, /* 09a */ + { .mk = { 0x9b, 0 }, .brk = { 0xf0, 0x9b, 0 } }, /* 09b */ + { .mk = { 0x9c, 0 }, .brk = { 0xf0, 0x9c, 0 } }, /* 09c */ + { .mk = { 0x9d, 0 }, .brk = { 0xf0, 0x9d, 0 } }, /* 09d */ + { .mk = { 0x9e, 0 }, .brk = { 0xf0, 0x9e, 0 } }, /* 09e */ + { .mk = { 0x9f, 0 }, .brk = { 0xf0, 0x9f, 0 } }, /* 09f */ + { .mk = { 0xa0, 0 }, .brk = { 0xf0, 0xa0, 0 } }, /* 0a0 */ + { .mk = { 0xa1, 0 }, .brk = { 0xf0, 0xa1, 0 } }, /* 0a1 */ + { .mk = { 0xa2, 0 }, .brk = { 0xf0, 0xa2, 0 } }, /* 0a2 */ + { .mk = { 0xa3, 0 }, .brk = { 0xf0, 0xa3, 0 } }, /* 0a3 */ + { .mk = { 0xa4, 0 }, .brk = { 0xf0, 0xa4, 0 } }, /* 0a4 */ + { .mk = { 0xa5, 0 }, .brk = { 0xf0, 0xa5, 0 } }, /* 0a5 */ + { .mk = { 0xa6, 0 }, .brk = { 0xf0, 0xa6, 0 } }, /* 0a6 */ + { .mk = { 0xa7, 0 }, .brk = { 0xf0, 0xa7, 0 } }, /* 0a7 */ + { .mk = { 0xa8, 0 }, .brk = { 0xf0, 0xa8, 0 } }, /* 0a8 */ + { .mk = { 0xa9, 0 }, .brk = { 0xf0, 0xa9, 0 } }, /* 0a9 */ + { .mk = { 0xaa, 0 }, .brk = { 0xf0, 0xaa, 0 } }, /* 0aa */ + { .mk = { 0xab, 0 }, .brk = { 0xf0, 0xab, 0 } }, /* 0ab */ + { .mk = { 0xac, 0 }, .brk = { 0xf0, 0xac, 0 } }, /* 0ac */ + { .mk = { 0xad, 0 }, .brk = { 0xf0, 0xad, 0 } }, /* 0ad */ + { .mk = { 0xae, 0 }, .brk = { 0xf0, 0xae, 0 } }, /* 0ae */ + { .mk = { 0xaf, 0 }, .brk = { 0xf0, 0xaf, 0 } }, /* 0af */ + { .mk = { 0xb0, 0 }, .brk = { 0xf0, 0xb0, 0 } }, /* 0b0 */ + { .mk = { 0xb1, 0 }, .brk = { 0xf0, 0xb1, 0 } }, /* 0b1 */ + { .mk = { 0xb2, 0 }, .brk = { 0xf0, 0xb2, 0 } }, /* 0b2 */ + { .mk = { 0xb3, 0 }, .brk = { 0xf0, 0xb3, 0 } }, /* 0b3 */ + { .mk = { 0xb4, 0 }, .brk = { 0xf0, 0xb4, 0 } }, /* 0b4 */ + { .mk = { 0xb5, 0 }, .brk = { 0xf0, 0xb5, 0 } }, /* 0b5 */ + { .mk = { 0xb6, 0 }, .brk = { 0xf0, 0xb6, 0 } }, /* 0b6 */ + { .mk = { 0xb7, 0 }, .brk = { 0xf0, 0xb7, 0 } }, /* 0b7 */ + { .mk = { 0xb8, 0 }, .brk = { 0xf0, 0xb8, 0 } }, /* 0b8 */ + { .mk = { 0xb9, 0 }, .brk = { 0xf0, 0xb9, 0 } }, /* 0b9 */ + { .mk = { 0xba, 0 }, .brk = { 0xf0, 0xba, 0 } }, /* 0ba */ + { .mk = { 0xbb, 0 }, .brk = { 0xf0, 0xbb, 0 } }, /* 0bb */ + { .mk = { 0xbc, 0 }, .brk = { 0xf0, 0xbc, 0 } }, /* 0bc */ + { .mk = { 0xbd, 0 }, .brk = { 0xf0, 0xbd, 0 } }, /* 0bd */ + { .mk = { 0xbe, 0 }, .brk = { 0xf0, 0xbe, 0 } }, /* 0be */ + { .mk = { 0xbf, 0 }, .brk = { 0xf0, 0xbf, 0 } }, /* 0bf */ + { .mk = { 0xc0, 0 }, .brk = { 0xf0, 0xc0, 0 } }, /* 0c0 */ + { .mk = { 0xc1, 0 }, .brk = { 0xf0, 0xc1, 0 } }, /* 0c1 */ + { .mk = { 0xc2, 0 }, .brk = { 0xf0, 0xc2, 0 } }, /* 0c2 */ + { .mk = { 0xc3, 0 }, .brk = { 0xf0, 0xc3, 0 } }, /* 0c3 */ + { .mk = { 0xc4, 0 }, .brk = { 0xf0, 0xc4, 0 } }, /* 0c4 */ + { .mk = { 0xc5, 0 }, .brk = { 0xf0, 0xc5, 0 } }, /* 0c5 */ + { .mk = { 0xc6, 0 }, .brk = { 0xf0, 0xc6, 0 } }, /* 0c6 */ + { .mk = { 0xc7, 0 }, .brk = { 0xf0, 0xc7, 0 } }, /* 0c7 */ + { .mk = { 0xc8, 0 }, .brk = { 0xf0, 0xc8, 0 } }, /* 0c8 */ + { .mk = { 0xc9, 0 }, .brk = { 0xf0, 0xc9, 0 } }, /* 0c9 */ + { .mk = { 0xca, 0 }, .brk = { 0xf0, 0xca, 0 } }, /* 0ca */ + { .mk = { 0xcb, 0 }, .brk = { 0xf0, 0xcb, 0 } }, /* 0cb */ + { .mk = { 0xcc, 0 }, .brk = { 0xf0, 0xcc, 0 } }, /* 0cc */ + { .mk = { 0xcd, 0 }, .brk = { 0xf0, 0xcd, 0 } }, /* 0cd */ + { .mk = { 0xce, 0 }, .brk = { 0xf0, 0xce, 0 } }, /* 0ce */ + { .mk = { 0xcf, 0 }, .brk = { 0xf0, 0xcf, 0 } }, /* 0cf */ + { .mk = { 0xd0, 0 }, .brk = { 0xf0, 0xd0, 0 } }, /* 0d0 */ + { .mk = { 0xd1, 0 }, .brk = { 0xf0, 0xd0, 0 } }, /* 0d1 */ + { .mk = { 0xd2, 0 }, .brk = { 0xf0, 0xd2, 0 } }, /* 0d2 */ + { .mk = { 0xd3, 0 }, .brk = { 0xf0, 0xd3, 0 } }, /* 0d3 */ + { .mk = { 0xd4, 0 }, .brk = { 0xf0, 0xd4, 0 } }, /* 0d4 */ + { .mk = { 0xd5, 0 }, .brk = { 0xf0, 0xd5, 0 } }, /* 0d5 */ + { .mk = { 0xd6, 0 }, .brk = { 0xf0, 0xd6, 0 } }, /* 0d6 */ + { .mk = { 0xd7, 0 }, .brk = { 0xf0, 0xd7, 0 } }, /* 0d7 */ + { .mk = { 0xd8, 0 }, .brk = { 0xf0, 0xd8, 0 } }, /* 0d8 */ + { .mk = { 0xd9, 0 }, .brk = { 0xf0, 0xd9, 0 } }, /* 0d9 */ + { .mk = { 0xda, 0 }, .brk = { 0xf0, 0xda, 0 } }, /* 0da */ + { .mk = { 0xdb, 0 }, .brk = { 0xf0, 0xdb, 0 } }, /* 0db */ + { .mk = { 0xdc, 0 }, .brk = { 0xf0, 0xdc, 0 } }, /* 0dc */ + { .mk = { 0xdd, 0 }, .brk = { 0xf0, 0xdd, 0 } }, /* 0dd */ + { .mk = { 0xde, 0 }, .brk = { 0xf0, 0xde, 0 } }, /* 0de */ + { .mk = { 0xdf, 0 }, .brk = { 0xf0, 0xdf, 0 } }, /* 0df */ + { .mk = { 0xe0, 0 }, .brk = { 0xf0, 0xe0, 0 } }, /* 0e0 */ + { .mk = { 0xe1, 0 }, .brk = { 0xf0, 0xe1, 0 } }, /* 0e1 */ + { .mk = { 0xe2, 0 }, .brk = { 0xf0, 0xe2, 0 } }, /* 0e2 */ + { .mk = { 0xe3, 0 }, .brk = { 0xf0, 0xe3, 0 } }, /* 0e3 */ + { .mk = { 0xe4, 0 }, .brk = { 0xf0, 0xe4, 0 } }, /* 0e4 */ + { .mk = { 0xe5, 0 }, .brk = { 0xf0, 0xe5, 0 } }, /* 0e5 */ + { .mk = { 0xe6, 0 }, .brk = { 0xf0, 0xe6, 0 } }, /* 0e6 */ + { .mk = { 0xe7, 0 }, .brk = { 0xf0, 0xe7, 0 } }, /* 0e7 */ + { .mk = { 0xe8, 0 }, .brk = { 0xf0, 0xe8, 0 } }, /* 0e8 */ + { .mk = { 0xe9, 0 }, .brk = { 0xf0, 0xe9, 0 } }, /* 0e9 */ + { .mk = { 0xea, 0 }, .brk = { 0xf0, 0xea, 0 } }, /* 0ea */ + { .mk = { 0xeb, 0 }, .brk = { 0xf0, 0xeb, 0 } }, /* 0eb */ + { .mk = { 0xec, 0 }, .brk = { 0xf0, 0xec, 0 } }, /* 0ec */ + { .mk = { 0xed, 0 }, .brk = { 0xf0, 0xed, 0 } }, /* 0ed */ + { .mk = { 0xee, 0 }, .brk = { 0xf0, 0xee, 0 } }, /* 0ee */ + { .mk = { 0xef, 0 }, .brk = { 0xf0, 0xef, 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { .mk = { 0xf3, 0 }, .brk = { 0xf0, 0xf3, 0 } }, /* 0f3 */ + { .mk = { 0xf4, 0 }, .brk = { 0xf0, 0xf4, 0 } }, /* 0f4 */ + { .mk = { 0xf5, 0 }, .brk = { 0xf0, 0xf5, 0 } }, /* 0f5 */ + { .mk = { 0xf6, 0 }, .brk = { 0xf0, 0xf6, 0 } }, /* 0f6 */ + { .mk = { 0xf7, 0 }, .brk = { 0xf0, 0xf7, 0 } }, /* 0f7 */ + { .mk = { 0xf8, 0 }, .brk = { 0xf0, 0xf8, 0 } }, /* 0f8 */ + { .mk = { 0xf9, 0 }, .brk = { 0xf0, 0xf9, 0 } }, /* 0f9 */ + { .mk = { 0xfa, 0 }, .brk = { 0xf0, 0xfa, 0 } }, /* 0fa */ + { .mk = { 0xfb, 0 }, .brk = { 0xf0, 0xfb, 0 } }, /* 0fb */ + { .mk = { 0xfc, 0 }, .brk = { 0xf0, 0xfc, 0 } }, /* 0fc */ + { .mk = { 0xfd, 0 }, .brk = { 0xf0, 0xfd, 0 } }, /* 0fd */ + { .mk = { 0xfe, 0 }, .brk = { 0xf0, 0xfe, 0 } }, /* 0fe */ + { .mk = { 0xff, 0 }, .brk = { 0xf0, 0xff, 0 } }, /* 0ff */ + { .mk = {0xe1, 0x14, 0 }, .brk = { 0xe1, 0xf0, 0x14, 0 } }, /* 100 */ + { .mk = {0xe0, 0x76, 0 }, .brk = { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ + { .mk = {0xe0, 0x16, 0 }, .brk = { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ + { .mk = {0xe0, 0x1E, 0 }, .brk = { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ + { .mk = {0xe0, 0x26, 0 }, .brk = { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ + { .mk = {0xe0, 0x25, 0 }, .brk = { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ + { .mk = {0xe0, 0x2E, 0 }, .brk = { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ + { .mk = {0xe0, 0x36, 0 }, .brk = { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ + { .mk = {0xe0, 0x3D, 0 }, .brk = { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ + { .mk = {0xe0, 0x3E, 0 }, .brk = { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ + { .mk = {0xe0, 0x46, 0 }, .brk = { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ + { .mk = {0xe0, 0x45, 0 }, .brk = { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ + { .mk = {0xe0, 0x4E, 0 }, .brk = { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = {0xe0, 0x66, 0 }, .brk = { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ + { .mk = {0xe0, 0x0D, 0 }, .brk = { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ + { .mk = {0xe0, 0x15, 0 }, .brk = { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ + { .mk = {0xe0, 0x1D, 0 }, .brk = { 0xe0, 0xF0, 0x1D, 0 } }, /* 112 */ + { .mk = {0xe0, 0x24, 0 }, .brk = { 0xe0, 0xF0, 0x24, 0 } }, /* 113 */ + { .mk = {0xe0, 0x2D, 0 }, .brk = { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ + { .mk = {0xe0, 0x2C, 0 }, .brk = { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ + { .mk = {0xe0, 0x35, 0 }, .brk = { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ + { .mk = {0xe0, 0x3C, 0 }, .brk = { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ + { .mk = {0xe0, 0x43, 0 }, .brk = { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ + { .mk = {0xe0, 0x44, 0 }, .brk = { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ + { .mk = {0xe0, 0x4D, 0 }, .brk = { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ + { .mk = {0xe0, 0x54, 0 }, .brk = { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ + { .mk = {0xe0, 0x5B, 0 }, .brk = { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ + { .mk = {0xe0, 0x5A, 0 }, .brk = { 0xe0, 0xF0, 0x5A, 0 } }, /* 11c */ + { .mk = {0xe0, 0x14, 0 }, .brk = { 0xe0, 0xF0, 0x14, 0 } }, /* 11d */ + { .mk = {0xe0, 0x1C, 0 }, .brk = { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ + { .mk = {0xe0, 0x1B, 0 }, .brk = { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ + { .mk = {0xe0, 0x23, 0 }, .brk = { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ + { .mk = {0xe0, 0x2B, 0 }, .brk = { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ + { .mk = {0xe0, 0x34, 0 }, .brk = { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ + { .mk = {0xe0, 0x33, 0 }, .brk = { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ + { .mk = {0xe0, 0x3B, 0 }, .brk = { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ + { .mk = {0xe0, 0x42, 0 }, .brk = { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ + { .mk = {0xe0, 0x4B, 0 }, .brk = { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = {0xe0, 0x1A, 0 }, .brk = { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ + { .mk = {0xe0, 0x22, 0 }, .brk = { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ + { .mk = {0xe0, 0x21, 0 }, .brk = { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ + { .mk = {0xe0, 0x2A, 0 }, .brk = { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ + { .mk = {0xe0, 0x32, 0 }, .brk = { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ + { .mk = {0xe0, 0x31, 0 }, .brk = { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ + { .mk = {0xe0, 0x3A, 0 }, .brk = { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = {0xe0, 0x49, 0 }, .brk = { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ + { .mk = {0xe0, 0x4A, 0 }, .brk = { 0xe0, 0xF0, 0x4A, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = {0xe0, 0x7C, 0 }, .brk = { 0xe0, 0xF0, 0x7C, 0 } }, /* 137 */ + { .mk = {0xe0, 0x11, 0 }, .brk = { 0xe0, 0xF0, 0x11, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ + { .mk = {0xe0, 0x05, 0 }, .brk = { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ + { .mk = {0xe0, 0x06, 0 }, .brk = { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ + { .mk = {0xe0, 0x04, 0 }, .brk = { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ + { .mk = {0xe0, 0x0C, 0 }, .brk = { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ + { .mk = {0xe0, 0x03, 0 }, .brk = { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ + { .mk = {0xe0, 0x0B, 0 }, .brk = { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ + { .mk = {0xe0, 0x02, 0 }, .brk = { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ + { .mk = {0xe0, 0x0A, 0 }, .brk = { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ + { .mk = {0xe0, 0x01, 0 }, .brk = { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ + { .mk = {0xe0, 0x09, 0 }, .brk = { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = {0xe0, 0x7E, 0 }, .brk = { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ + { .mk = {0xe0, 0x6C, 0 }, .brk = { 0xe0, 0xF0, 0x6C, 0 } }, /* 147 */ + { .mk = {0xe0, 0x75, 0 }, .brk = { 0xe0, 0xF0, 0x75, 0 } }, /* 148 */ + { .mk = {0xe0, 0x7D, 0 }, .brk = { 0xe0, 0xF0, 0x7D, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = {0xe0, 0x6B, 0 }, .brk = { 0xe0, 0xF0, 0x6B, 0 } }, /* 14b */ + { .mk = {0xe0, 0x73, 0 }, .brk = { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ + { .mk = {0xe0, 0x74, 0 }, .brk = { 0xe0, 0xF0, 0x74, 0 } }, /* 14d */ + { .mk = {0xe0, 0x79, 0 }, .brk = { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ + { .mk = {0xe0, 0x69, 0 }, .brk = { 0xe0, 0xF0, 0x69, 0 } }, /* 14f */ + { .mk = {0xe0, 0x72, 0 }, .brk = { 0xe0, 0xF0, 0x72, 0 } }, /* 150 */ + { .mk = {0xe0, 0x7A, 0 }, .brk = { 0xe0, 0xF0, 0x7A, 0 } }, /* 151 */ + { .mk = {0xe0, 0x70, 0 }, .brk = { 0xe0, 0xF0, 0x70, 0 } }, /* 152 */ + { .mk = {0xe0, 0x71, 0 }, .brk = { 0xe0, 0xF0, 0x71, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = {0xe0, 0x60, 0 }, .brk = { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = {0xe0, 0x78, 0 }, .brk = { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ + { .mk = {0xe0, 0x07, 0 }, .brk = { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ + { .mk = {0xe0, 0x0F, 0 }, .brk = { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ + { .mk = {0xe0, 0x17, 0 }, .brk = { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ + { .mk = {0xe0, 0x1F, 0 }, .brk = { 0xe0, 0xF0, 0x1F, 0 } }, /* 15b */ + { .mk = {0xe0, 0x27, 0 }, .brk = { 0xe0, 0xF0, 0x27, 0 } }, /* 15c */ + { .mk = {0xe0, 0x2F, 0 }, .brk = { 0xe0, 0xF0, 0x2F, 0 } }, /* 15d */ + { .mk = {0xe0, 0x37, 0 }, .brk = { 0xe0, 0xF0, 0x37, 0 } }, /* 15e */ + { .mk = {0xe0, 0x3F, 0 }, .brk = { 0xe0, 0xF0, 0x3F, 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = {0xe0, 0x4F, 0 }, .brk = { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ + { .mk = {0xe0, 0x56, 0 }, .brk = { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ + { .mk = {0xe0, 0x5E, 0 }, .brk = { 0xe0, 0xF0, 0x5E, 0 } }, /* 163 */ + { .mk = {0xe0, 0x08, 0 }, .brk = { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ + { .mk = {0xe0, 0x10, 0 }, .brk = { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ + { .mk = {0xe0, 0x18, 0 }, .brk = { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ + { .mk = {0xe0, 0x20, 0 }, .brk = { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ + { .mk = {0xe0, 0x28, 0 }, .brk = { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ + { .mk = {0xe0, 0x30, 0 }, .brk = { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ + { .mk = {0xe0, 0x38, 0 }, .brk = { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ + { .mk = {0xe0, 0x40, 0 }, .brk = { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ + { .mk = {0xe0, 0x48, 0 }, .brk = { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ + { .mk = {0xe0, 0x50, 0 }, .brk = { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ + { .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = {0xe0, 0x13, 0 }, .brk = { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ + { .mk = {0xe0, 0x19, 0 }, .brk = { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ + { .mk = {0xe0, 0x39, 0 }, .brk = { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ + { .mk = {0xe0, 0x51, 0 }, .brk = { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ + { .mk = {0xe0, 0x53, 0 }, .brk = { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ + { .mk = {0xe0, 0x5C, 0 }, .brk = { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = {0xe0, 0x62, 0 }, .brk = { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ + { .mk = {0xe0, 0x63, 0 }, .brk = { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ + { .mk = {0xe0, 0x64, 0 }, .brk = { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ + { .mk = {0xe0, 0x65, 0 }, .brk = { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ + { .mk = {0xe0, 0x67, 0 }, .brk = { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ + { .mk = {0xe0, 0x68, 0 }, .brk = { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ + { .mk = {0xe0, 0x6A, 0 }, .brk = { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ + { .mk = {0xe0, 0x6D, 0 }, .brk = { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ + { .mk = {0xe0, 0x6E, 0 }, .brk = { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cv */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = {0xe0, 0xe1, 0 }, .brk = { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = {0xe0, 0xee, 0 }, .brk = { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = {0xe0, 0xf1, 0 }, .brk = { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = {0xe0, 0xfe, 0 }, .brk = { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ + { .mk = {0xe0, 0xff, 0 }, .brk = { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ // clang-format on }; static const scancode scancode_set3[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x08, 0 }, { 0xf0, 0x08, 0 } }, /* 001 */ - { { 0x16, 0 }, { 0xf0, 0x16, 0 } }, /* 002 */ - { { 0x1E, 0 }, { 0xf0, 0x1E, 0 } }, /* 003 */ - { { 0x26, 0 }, { 0xf0, 0x26, 0 } }, /* 004 */ - { { 0x25, 0 }, { 0xf0, 0x25, 0 } }, /* 005 */ - { { 0x2E, 0 }, { 0xf0, 0x2E, 0 } }, /* 006 */ - { { 0x36, 0 }, { 0xf0, 0x36, 0 } }, /* 007 */ - { { 0x3D, 0 }, { 0xf0, 0x3D, 0 } }, /* 008 */ - { { 0x3E, 0 }, { 0xf0, 0x3E, 0 } }, /* 009 */ - { { 0x46, 0 }, { 0xf0, 0x46, 0 } }, /* 00a */ - { { 0x45, 0 }, { 0xf0, 0x45, 0 } }, /* 00b */ - { { 0x4E, 0 }, { 0xf0, 0x4E, 0 } }, /* 00c */ - { { 0x55, 0 }, { 0xf0, 0x55, 0 } }, /* 00d */ - { { 0x66, 0 }, { 0xf0, 0x66, 0 } }, /* 00e */ - { { 0x0D, 0 }, { 0xf0, 0x0D, 0 } }, /* 00f */ - { { 0x15, 0 }, { 0xf0, 0x15, 0 } }, /* 010 */ - { { 0x1D, 0 }, { 0xf0, 0x1D, 0 } }, /* 011 */ - { { 0x24, 0 }, { 0xf0, 0x24, 0 } }, /* 012 */ - { { 0x2D, 0 }, { 0xf0, 0x2D, 0 } }, /* 013 */ - { { 0x2C, 0 }, { 0xf0, 0x2C, 0 } }, /* 014 */ - { { 0x35, 0 }, { 0xf0, 0x35, 0 } }, /* 015 */ - { { 0x3C, 0 }, { 0xf0, 0x3C, 0 } }, /* 016 */ - { { 0x43, 0 }, { 0xf0, 0x43, 0 } }, /* 017 */ - { { 0x44, 0 }, { 0xf0, 0x44, 0 } }, /* 018 */ - { { 0x4D, 0 }, { 0xf0, 0x4D, 0 } }, /* 019 */ - { { 0x54, 0 }, { 0xf0, 0x54, 0 } }, /* 01a */ - { { 0x5B, 0 }, { 0xf0, 0x5B, 0 } }, /* 01b */ - { { 0x5A, 0 }, { 0xf0, 0x5A, 0 } }, /* 01c */ - { { 0x11, 0 }, { 0xf0, 0x11, 0 } }, /* 01d */ - { { 0x1C, 0 }, { 0xf0, 0x1C, 0 } }, /* 01e */ - { { 0x1B, 0 }, { 0xf0, 0x1B, 0 } }, /* 01f */ - { { 0x23, 0 }, { 0xf0, 0x23, 0 } }, /* 020 */ - { { 0x2B, 0 }, { 0xf0, 0x2B, 0 } }, /* 021 */ - { { 0x34, 0 }, { 0xf0, 0x34, 0 } }, /* 022 */ - { { 0x33, 0 }, { 0xf0, 0x33, 0 } }, /* 023 */ - { { 0x3B, 0 }, { 0xf0, 0x3B, 0 } }, /* 024 */ - { { 0x42, 0 }, { 0xf0, 0x42, 0 } }, /* 025 */ - { { 0x4B, 0 }, { 0xf0, 0x4B, 0 } }, /* 026 */ - { { 0x4C, 0 }, { 0xf0, 0x4C, 0 } }, /* 027 */ - { { 0x52, 0 }, { 0xf0, 0x52, 0 } }, /* 028 */ - { { 0x0E, 0 }, { 0xf0, 0x0E, 0 } }, /* 029 */ - { { 0x12, 0 }, { 0xf0, 0x12, 0 } }, /* 02a */ - { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 02b */ - { { 0x1A, 0 }, { 0xf0, 0x1A, 0 } }, /* 02c */ - { { 0x22, 0 }, { 0xf0, 0x22, 0 } }, /* 02d */ - { { 0x21, 0 }, { 0xf0, 0x21, 0 } }, /* 02e */ - { { 0x2A, 0 }, { 0xf0, 0x2A, 0 } }, /* 02f */ - { { 0x32, 0 }, { 0xf0, 0x32, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xf0, 0x31, 0 } }, /* 031 */ - { { 0x3A, 0 }, { 0xf0, 0x3A, 0 } }, /* 032 */ - { { 0x41, 0 }, { 0xf0, 0x41, 0 } }, /* 033 */ - { { 0x49, 0 }, { 0xf0, 0x49, 0 } }, /* 034 */ - { { 0x4A, 0 }, { 0xf0, 0x4A, 0 } }, /* 035 */ - { { 0x59, 0 }, { 0xf0, 0x59, 0 } }, /* 036 */ - { { 0x7E, 0 }, { 0xf0, 0x7E, 0 } }, /* 037 */ - { { 0x19, 0 }, { 0xf0, 0x19, 0 } }, /* 038 */ - { { 0x29, 0 }, { 0xf0, 0x29, 0 } }, /* 039 */ - { { 0x14, 0 }, { 0xf0, 0x14, 0 } }, /* 03a */ - { { 0x07, 0 }, { 0xf0, 0x07, 0 } }, /* 03b */ - { { 0x0F, 0 }, { 0xf0, 0x0F, 0 } }, /* 03c */ - { { 0x17, 0 }, { 0xf0, 0x17, 0 } }, /* 03d */ - { { 0x1F, 0 }, { 0xf0, 0x1F, 0 } }, /* 03e */ - { { 0x27, 0 }, { 0xf0, 0x27, 0 } }, /* 03f */ - { { 0x2F, 0 }, { 0xf0, 0x2F, 0 } }, /* 040 */ - { { 0x37, 0 }, { 0xf0, 0x37, 0 } }, /* 041 */ - { { 0x3F, 0 }, { 0xf0, 0x3F, 0 } }, /* 042 */ - { { 0x47, 0 }, { 0xf0, 0x47, 0 } }, /* 043 */ - { { 0x4F, 0 }, { 0xf0, 0x4F, 0 } }, /* 044 */ - { { 0x76, 0 }, { 0xf0, 0x76, 0 } }, /* 045 */ - { { 0x5F, 0 }, { 0xf0, 0x5F, 0 } }, /* 046 */ - { { 0x6C, 0 }, { 0xf0, 0x6C, 0 } }, /* 047 */ - { { 0x75, 0 }, { 0xf0, 0x75, 0 } }, /* 048 */ - { { 0x7D, 0 }, { 0xf0, 0x7D, 0 } }, /* 049 */ - { { 0x84, 0 }, { 0xf0, 0x84, 0 } }, /* 04a */ - { { 0x6B, 0 }, { 0xf0, 0x6B, 0 } }, /* 04b */ - { { 0x73, 0 }, { 0xf0, 0x73, 0 } }, /* 04c */ - { { 0x74, 0 }, { 0xf0, 0x74, 0 } }, /* 04d */ - { { 0x7C, 0 }, { 0xf0, 0x7C, 0 } }, /* 04e */ - { { 0x69, 0 }, { 0xf0, 0x69, 0 } }, /* 04f */ - { { 0x72, 0 }, { 0xf0, 0x72, 0 } }, /* 050 */ - { { 0x7A, 0 }, { 0xf0, 0x7A, 0 } }, /* 051 */ - { { 0x70, 0 }, { 0xf0, 0x70, 0 } }, /* 052 */ - { { 0x71, 0 }, { 0xf0, 0x71, 0 } }, /* 053 */ - { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 054 */ - { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, /* 055 */ - { { 0 }, { 0 } }, /* 056 */ - { { 0x56, 0 }, { 0xf0, 0x56, 0 } }, /* 057 */ - { { 0x5E, 0 }, { 0xf0, 0x5E, 0 } }, /* 058 */ - { { 0 }, { 0 } }, /* 059 */ - { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, /* 05b */ - { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, /* 05d */ - { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, /* 05f */ - { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, /* 061 */ - { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, /* 063 */ - { { 0 }, { 0 } }, /* 064 */ - { { 0x10, 0 }, { 0xf0, 0x10, 0 } }, /* 065 */ - { { 0x18, 0 }, { 0xf0, 0x18, 0 } }, /* 066 */ - { { 0x20, 0 }, { 0xf0, 0x20, 0 } }, /* 067 */ - { { 0x28, 0 }, { 0xf0, 0x28, 0 } }, /* 068 */ - { { 0x30, 0 }, { 0xf0, 0x30, 0 } }, /* 069 */ - { { 0x38, 0 }, { 0xf0, 0x38, 0 } }, /* 06a */ - { { 0x40, 0 }, { 0xf0, 0x40, 0 } }, /* 06b */ - { { 0x48, 0 }, { 0xf0, 0x48, 0 } }, /* 06c */ - { { 0x50, 0 }, { 0xf0, 0x50, 0 } }, /* 06d */ - { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, /* 06f */ - { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 070 */ - { { 0 }, { 0 } }, /* 071 */ - { { 0 }, { 0 } }, /* 072 */ - { { 0x51, 0 }, { 0xf0, 0x51, 0 } }, /* 073 */ - { { 0x53, 0 }, { 0xf0, 0x53, 0 } }, /* 074 */ - { { 0x5C, 0 }, { 0xf0, 0x5C, 0 } }, /* 075 */ - { { 0 }, { 0 } }, /* 076 */ - { { 0x62, 0 }, { 0xf0, 0x62, 0 } }, /* 077 */ - { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, /* 078 */ - { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 079 */ - { { 0 }, { 0 } }, /* 07a */ - { { 0x85, 0 }, { 0xf0, 0x85, 0 } }, /* 07b */ - { { 0x68, 0 }, { 0xf0, 0x68, 0 } }, /* 07c */ - { { 0x13, 0 }, { 0xf0, 0x13, 0 } }, /* 07d */ - { { 0 }, { 0 } }, /* 07e */ - { { 0 }, { 0 } }, /* 07f */ - { { 0x80, 0 }, { 0xf0, 0x80, 0 } }, /* 080 */ - { { 0x81, 0 }, { 0xf0, 0x81, 0 } }, /* 081 */ - { { 0x82, 0 }, { 0xf0, 0x82, 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0x85, 0 }, { 0xf0, 0x54, 0 } }, /* 085 */ - { { 0x86, 0 }, { 0xf0, 0x86, 0 } }, /* 086 */ - { { 0x87, 0 }, { 0xf0, 0x87, 0 } }, /* 087 */ - { { 0x88, 0 }, { 0xf0, 0x88, 0 } }, /* 087 */ - { { 0x89, 0 }, { 0xf0, 0x89, 0 } }, /* 088 */ - { { 0x8a, 0 }, { 0xf0, 0x8a, 0 } }, /* 089 */ - { { 0x8b, 0 }, { 0xf0, 0x8b, 0 } }, /* 08b */ - { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, /* 08d */ - { { 0x8e, 0 }, { 0xf0, 0x8e, 0 } }, /* 08e */ - { { 0x8f, 0 }, { 0xf0, 0x8f, 0 } }, /* 08f */ - { { 0x90, 0 }, { 0xf0, 0x90, 0 } }, /* 090 */ - { { 0x91, 0 }, { 0xf0, 0x91, 0 } }, /* 091 */ - { { 0x92, 0 }, { 0xf0, 0x92, 0 } }, /* 092 */ - { { 0x93, 0 }, { 0xf0, 0x93, 0 } }, /* 093 */ - { { 0x94, 0 }, { 0xf0, 0x94, 0 } }, /* 094 */ - { { 0x95, 0 }, { 0xf0, 0x95, 0 } }, /* 095 */ - { { 0x96, 0 }, { 0xf0, 0x96, 0 } }, /* 096 */ - { { 0x97, 0 }, { 0xf0, 0x97, 0 } }, /* 097 */ - { { 0x98, 0 }, { 0xf0, 0x98, 0 } }, /* 098 */ - { { 0x99, 0 }, { 0xf0, 0x99, 0 } }, /* 099 */ - { { 0x9a, 0 }, { 0xf0, 0x9a, 0 } }, /* 09a */ - { { 0x9b, 0 }, { 0xf0, 0x9b, 0 } }, /* 09b */ - { { 0x9c, 0 }, { 0xf0, 0x9c, 0 } }, /* 09c */ - { { 0x9d, 0 }, { 0xf0, 0x9d, 0 } }, /* 09d */ - { { 0x9e, 0 }, { 0xf0, 0x9e, 0 } }, /* 09e */ - { { 0x9f, 0 }, { 0xf0, 0x9f, 0 } }, /* 09f */ - { { 0xa0, 0 }, { 0xf0, 0xa0, 0 } }, /* 0a0 */ - { { 0xa1, 0 }, { 0xf0, 0xa1, 0 } }, /* 0a1 */ - { { 0xa2, 0 }, { 0xf0, 0xa2, 0 } }, /* 0a2 */ - { { 0xa3, 0 }, { 0xf0, 0xa3, 0 } }, /* 0a3 */ - { { 0xa4, 0 }, { 0xf0, 0xa4, 0 } }, /* 0a4 */ - { { 0xa5, 0 }, { 0xf0, 0xa5, 0 } }, /* 0a5 */ - { { 0xa6, 0 }, { 0xf0, 0xa6, 0 } }, /* 0a6 */ - { { 0xa7, 0 }, { 0xf0, 0xa7, 0 } }, /* 0a7 */ - { { 0xa8, 0 }, { 0xf0, 0xa8, 0 } }, /* 0a8 */ - { { 0xa9, 0 }, { 0xf0, 0xa9, 0 } }, /* 0a9 */ - { { 0xaa, 0 }, { 0xf0, 0xaa, 0 } }, /* 0aa */ - { { 0xab, 0 }, { 0xf0, 0xab, 0 } }, /* 0ab */ - { { 0xac, 0 }, { 0xf0, 0xac, 0 } }, /* 0ac */ - { { 0xad, 0 }, { 0xf0, 0xad, 0 } }, /* 0ad */ - { { 0xae, 0 }, { 0xf0, 0xae, 0 } }, /* 0ae */ - { { 0xaf, 0 }, { 0xf0, 0xaf, 0 } }, /* 0af */ - { { 0xb0, 0 }, { 0xf0, 0xb0, 0 } }, /* 0b0 */ - { { 0xb1, 0 }, { 0xf0, 0xb1, 0 } }, /* 0b1 */ - { { 0xb2, 0 }, { 0xf0, 0xb2, 0 } }, /* 0b2 */ - { { 0xb3, 0 }, { 0xf0, 0xb3, 0 } }, /* 0b3 */ - { { 0xb4, 0 }, { 0xf0, 0xb4, 0 } }, /* 0b4 */ - { { 0xb5, 0 }, { 0xf0, 0xb5, 0 } }, /* 0b5 */ - { { 0xb6, 0 }, { 0xf0, 0xb6, 0 } }, /* 0b6 */ - { { 0xb7, 0 }, { 0xf0, 0xb7, 0 } }, /* 0b7 */ - { { 0xb8, 0 }, { 0xf0, 0xb8, 0 } }, /* 0b8 */ - { { 0xb9, 0 }, { 0xf0, 0xb9, 0 } }, /* 0b9 */ - { { 0xba, 0 }, { 0xf0, 0xba, 0 } }, /* 0ba */ - { { 0xbb, 0 }, { 0xf0, 0xbb, 0 } }, /* 0bb */ - { { 0xbc, 0 }, { 0xf0, 0xbc, 0 } }, /* 0bc */ - { { 0xbd, 0 }, { 0xf0, 0xbd, 0 } }, /* 0bd */ - { { 0xbe, 0 }, { 0xf0, 0xbe, 0 } }, /* 0be */ - { { 0xbf, 0 }, { 0xf0, 0xbf, 0 } }, /* 0bf */ - { { 0xc0, 0 }, { 0xf0, 0xc0, 0 } }, /* 0c0 */ - { { 0xc1, 0 }, { 0xf0, 0xc1, 0 } }, /* 0c1 */ - { { 0xc2, 0 }, { 0xf0, 0xc2, 0 } }, /* 0c2 */ - { { 0xc3, 0 }, { 0xf0, 0xc3, 0 } }, /* 0c3 */ - { { 0xc4, 0 }, { 0xf0, 0xc4, 0 } }, /* 0c4 */ - { { 0xc5, 0 }, { 0xf0, 0xc5, 0 } }, /* 0c5 */ - { { 0xc6, 0 }, { 0xf0, 0xc6, 0 } }, /* 0c6 */ - { { 0xc7, 0 }, { 0xf0, 0xc7, 0 } }, /* 0c7 */ - { { 0xc8, 0 }, { 0xf0, 0xc8, 0 } }, /* 0c8 */ - { { 0xc9, 0 }, { 0xf0, 0xc9, 0 } }, /* 0c9 */ - { { 0xca, 0 }, { 0xf0, 0xca, 0 } }, /* 0ca */ - { { 0xcb, 0 }, { 0xf0, 0xcb, 0 } }, /* 0cb */ - { { 0xcc, 0 }, { 0xf0, 0xcc, 0 } }, /* 0cc */ - { { 0xcd, 0 }, { 0xf0, 0xcd, 0 } }, /* 0cd */ - { { 0xce, 0 }, { 0xf0, 0xce, 0 } }, /* 0ce */ - { { 0xcf, 0 }, { 0xf0, 0xcf, 0 } }, /* 0cf */ - { { 0xd0, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d0 */ - { { 0xd1, 0 }, { 0xf0, 0xd0, 0 } }, /* 0d1 */ - { { 0xd2, 0 }, { 0xf0, 0xd2, 0 } }, /* 0d2 */ - { { 0xd3, 0 }, { 0xf0, 0xd3, 0 } }, /* 0d3 */ - { { 0xd4, 0 }, { 0xf0, 0xd4, 0 } }, /* 0d4 */ - { { 0xd5, 0 }, { 0xf0, 0xd5, 0 } }, /* 0d5 */ - { { 0xd6, 0 }, { 0xf0, 0xd6, 0 } }, /* 0d6 */ - { { 0xd7, 0 }, { 0xf0, 0xd7, 0 } }, /* 0d7 */ - { { 0xd8, 0 }, { 0xf0, 0xd8, 0 } }, /* 0d8 */ - { { 0xd9, 0 }, { 0xf0, 0xd9, 0 } }, /* 0d9 */ - { { 0xda, 0 }, { 0xf0, 0xda, 0 } }, /* 0da */ - { { 0xdb, 0 }, { 0xf0, 0xdb, 0 } }, /* 0db */ - { { 0xdc, 0 }, { 0xf0, 0xdc, 0 } }, /* 0dc */ - { { 0xdd, 0 }, { 0xf0, 0xdd, 0 } }, /* 0dd */ - { { 0xde, 0 }, { 0xf0, 0xde, 0 } }, /* 0de */ - { { 0xdf, 0 }, { 0xf0, 0xdf, 0 } }, /* 0df */ - { { 0xe0, 0 }, { 0xf0, 0xe0, 0 } }, /* 0e0 */ - { { 0xe1, 0 }, { 0xf0, 0xe1, 0 } }, /* 0e1 */ - { { 0xe2, 0 }, { 0xf0, 0xe2, 0 } }, /* 0e2 */ - { { 0xe3, 0 }, { 0xf0, 0xe3, 0 } }, /* 0e3 */ - { { 0xe4, 0 }, { 0xf0, 0xe4, 0 } }, /* 0e4 */ - { { 0xe5, 0 }, { 0xf0, 0xe5, 0 } }, /* 0e5 */ - { { 0xe6, 0 }, { 0xf0, 0xe6, 0 } }, /* 0e6 */ - { { 0xe7, 0 }, { 0xf0, 0xe7, 0 } }, /* 0e7 */ - { { 0xe8, 0 }, { 0xf0, 0xe8, 0 } }, /* 0e7 */ - { { 0xe9, 0 }, { 0xf0, 0xe9, 0 } }, /* 0e8 */ - { { 0xea, 0 }, { 0xf0, 0xea, 0 } }, /* 0e9 */ - { { 0xeb, 0 }, { 0xf0, 0xeb, 0 } }, /* 0eb */ - { { 0xec, 0 }, { 0xf0, 0xec, 0 } }, /* 0ec */ - { { 0xed, 0 }, { 0xf0, 0xed, 0 } }, /* 0ed */ - { { 0xee, 0 }, { 0xf0, 0xee, 0 } }, /* 0ee */ - { { 0xef, 0 }, { 0xf0, 0xef, 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0xf1, 0 }, { 0xf0, 0xf1, 0 } }, /* 0f1 */ - { { 0xf2, 0 }, { 0xf0, 0xf2, 0 } }, /* 0f2 */ - { { 0xf3, 0 }, { 0xf0, 0xf3, 0 } }, /* 0f3 */ - { { 0xf4, 0 }, { 0xf0, 0xf4, 0 } }, /* 0f4 */ - { { 0xf5, 0 }, { 0xf0, 0xf5, 0 } }, /* 0f5 */ - { { 0xf6, 0 }, { 0xf0, 0xf6, 0 } }, /* 0f6 */ - { { 0xf7, 0 }, { 0xf0, 0xf7, 0 } }, /* 0f7 */ - { { 0xf8, 0 }, { 0xf0, 0xf8, 0 } }, /* 0f8 */ - { { 0xf9, 0 }, { 0xf0, 0xf9, 0 } }, /* 0f9 */ - { { 0xfa, 0 }, { 0xf0, 0xfa, 0 } }, /* 0fa */ - { { 0xfb, 0 }, { 0xf0, 0xfb, 0 } }, /* 0fb */ - { { 0xfc, 0 }, { 0xf0, 0xfc, 0 } }, /* 0fc */ - { { 0xfd, 0 }, { 0xf0, 0xfd, 0 } }, /* 0fd */ - { { 0xfe, 0 }, { 0xf0, 0xfe, 0 } }, /* 0fe */ - { { 0xff, 0 }, { 0xf0, 0xff, 0 } }, /* 0ff */ - { { 0x62, 0 }, { 0xF0, 0x62, 0 } }, /* 100 */ - { { 0xe0, 0x76, 0 }, { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ - { { 0xe0, 0x1E, 0 }, { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ - { { 0xe0, 0x25, 0 }, { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ - { { 0xe0, 0x2E, 0 }, { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ - { { 0xe0, 0x36, 0 }, { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ - { { 0xe0, 0x3D, 0 }, { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ - { { 0xe0, 0x3E, 0 }, { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ - { { 0xe0, 0x45, 0 }, { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ - { { 0xe0, 0x4E, 0 }, { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ - { { 0xe0, 0x0D, 0 }, { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ - { { 0xe0, 0x1D, 0 }, { 0xe0, 0xF0, 0x1D, 0 } }, /* 111 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xF0, 0x24, 0 } }, /* 112 */ - { { 0xe0, 0x2D, 0 }, { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ - { { 0xe0, 0x2C, 0 }, { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ - { { 0xe0, 0x35, 0 }, { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ - { { 0xe0, 0x3C, 0 }, { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ - { { 0xe0, 0x43, 0 }, { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ - { { 0xe0, 0x4D, 0 }, { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ - { { 0xe0, 0x54, 0 }, { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ - { { 0xe0, 0x5B, 0 }, { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ - { { 0x79, 0 }, { 0xf0, 0x79, 0 } }, /* 11c */ - { { 0x58, 0 }, { 0xf0, 0x58, 0 } }, /* 11d */ - { { 0xe0, 0x1C, 0 }, { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ - { { 0xe0, 0x1B, 0 }, { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ - { { 0xe0, 0x2B, 0 }, { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ - { { 0xe0, 0x33, 0 }, { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ - { { 0xe0, 0x3B, 0 }, { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ - { { 0xe0, 0x4B, 0 }, { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0xe0, 0x1A, 0 }, { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ - { { 0xe0, 0x21, 0 }, { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ - { { 0xe0, 0x2A, 0 }, { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ - { { 0xe0, 0x31, 0 }, { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ - { { 0xe0, 0x3A, 0 }, { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ - { { 0x77, 0 }, { 0xf0, 0x77, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0x57, 0 }, { 0xf0, 0x57, 0 } }, /* 137 */ - { { 0x39, 0 }, { 0xf0, 0x39, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ - { { 0xe0, 0x05, 0 }, { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ - { { 0xe0, 0x0C, 0 }, { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ - { { 0xe0, 0x03, 0 }, { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ - { { 0xe0, 0x0B, 0 }, { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ - { { 0xe0, 0x0A, 0 }, { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ - { { 0xe0, 0x01, 0 }, { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0xe0, 0x7E, 0 }, { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ - { { 0x6E, 0 }, { 0xf0, 0x6E, 0 } }, /* 147 */ - { { 0x63, 0 }, { 0xf0, 0x63, 0 } }, /* 148 */ - { { 0x6F, 0 }, { 0xf0, 0x6F, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0x61, 0 }, { 0xf0, 0x61, 0 } }, /* 14b */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ - { { 0x6A, 0 }, { 0xf0, 0x6A, 0 } }, /* 14d */ - { { 0xe0, 0x79, 0 }, { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ - { { 0x65, 0 }, { 0xf0, 0x65, 0 } }, /* 14f */ - { { 0x60, 0 }, { 0xf0, 0x60, 0 } }, /* 150 */ - { { 0x6D, 0 }, { 0xf0, 0x6D, 0 } }, /* 151 */ - { { 0x67, 0 }, { 0xf0, 0x67, 0 } }, /* 152 */ - { { 0x64, 0 }, { 0xf0, 0x64, 0 } }, /* 153 */ - { { 0xd4, 0 }, { 0xf0, 0xD4, 0 } }, /* 154 */ - { { 0xe0, 0x60, 0 }, { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ - { { 0xe0, 0x0F, 0 }, { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ - { { 0xe0, 0x17, 0 }, { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ - { { 0x8B, 0 }, { 0xf0, 0x8B, 0 } }, /* 15b */ - { { 0x8C, 0 }, { 0xf0, 0x8C, 0 } }, /* 15c */ - { { 0x8D, 0 }, { 0xf0, 0x8D, 0 } }, /* 15d */ - { { 0 }, { 0 } }, /* 15e */ - { { 0x7F, 0 }, { 0xf0, 0x7F, 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0xe0, 0x4F, 0 }, { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ - { { 0xe0, 0x56, 0 }, { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ - { { 0 }, { 0 } }, /* 163 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ - { { 0xe0, 0x28, 0 }, { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ - { { 0xe0, 0x57, 0 }, { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ - { { 0xe0, 0x19, 0 }, { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ - { { 0xe0, 0x39, 0 }, { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ - { { 0xe0, 0x51, 0 }, { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ - { { 0xe0, 0x5C, 0 }, { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ - { { 0xe0, 0x65, 0 }, { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ - { { 0xe0, 0x67, 0 }, { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ - { { 0xe0, 0x6A, 0 }, { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ - { { 0xe0, 0x6D, 0 }, { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ - { { 0xe0, 0x6E, 0 }, { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0xe0, 0xe1, 0 }, { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0xe0, 0xee, 0 }, { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0xe0, 0xf1, 0 }, { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0xe0, 0xfe, 0 }, { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ - { { 0xe0, 0xff, 0 }, { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x08, 0 }, .brk = { 0xf0, 0x08, 0 } }, /* 001 */ + { .mk = { 0x16, 0 }, .brk = { 0xf0, 0x16, 0 } }, /* 002 */ + { .mk = { 0x1E, 0 }, .brk = { 0xf0, 0x1E, 0 } }, /* 003 */ + { .mk = { 0x26, 0 }, .brk = { 0xf0, 0x26, 0 } }, /* 004 */ + { .mk = { 0x25, 0 }, .brk = { 0xf0, 0x25, 0 } }, /* 005 */ + { .mk = { 0x2E, 0 }, .brk = { 0xf0, 0x2E, 0 } }, /* 006 */ + { .mk = { 0x36, 0 }, .brk = { 0xf0, 0x36, 0 } }, /* 007 */ + { .mk = { 0x3D, 0 }, .brk = { 0xf0, 0x3D, 0 } }, /* 008 */ + { .mk = { 0x3E, 0 }, .brk = { 0xf0, 0x3E, 0 } }, /* 009 */ + { .mk = { 0x46, 0 }, .brk = { 0xf0, 0x46, 0 } }, /* 00a */ + { .mk = { 0x45, 0 }, .brk = { 0xf0, 0x45, 0 } }, /* 00b */ + { .mk = { 0x4E, 0 }, .brk = { 0xf0, 0x4E, 0 } }, /* 00c */ + { .mk = { 0x55, 0 }, .brk = { 0xf0, 0x55, 0 } }, /* 00d */ + { .mk = { 0x66, 0 }, .brk = { 0xf0, 0x66, 0 } }, /* 00e */ + { .mk = { 0x0D, 0 }, .brk = { 0xf0, 0x0D, 0 } }, /* 00f */ + { .mk = { 0x15, 0 }, .brk = { 0xf0, 0x15, 0 } }, /* 010 */ + { .mk = { 0x1D, 0 }, .brk = { 0xf0, 0x1D, 0 } }, /* 011 */ + { .mk = { 0x24, 0 }, .brk = { 0xf0, 0x24, 0 } }, /* 012 */ + { .mk = { 0x2D, 0 }, .brk = { 0xf0, 0x2D, 0 } }, /* 013 */ + { .mk = { 0x2C, 0 }, .brk = { 0xf0, 0x2C, 0 } }, /* 014 */ + { .mk = { 0x35, 0 }, .brk = { 0xf0, 0x35, 0 } }, /* 015 */ + { .mk = { 0x3C, 0 }, .brk = { 0xf0, 0x3C, 0 } }, /* 016 */ + { .mk = { 0x43, 0 }, .brk = { 0xf0, 0x43, 0 } }, /* 017 */ + { .mk = { 0x44, 0 }, .brk = { 0xf0, 0x44, 0 } }, /* 018 */ + { .mk = { 0x4D, 0 }, .brk = { 0xf0, 0x4D, 0 } }, /* 019 */ + { .mk = { 0x54, 0 }, .brk = { 0xf0, 0x54, 0 } }, /* 01a */ + { .mk = { 0x5B, 0 }, .brk = { 0xf0, 0x5B, 0 } }, /* 01b */ + { .mk = { 0x5A, 0 }, .brk = { 0xf0, 0x5A, 0 } }, /* 01c */ + { .mk = { 0x11, 0 }, .brk = { 0xf0, 0x11, 0 } }, /* 01d */ + { .mk = { 0x1C, 0 }, .brk = { 0xf0, 0x1C, 0 } }, /* 01e */ + { .mk = { 0x1B, 0 }, .brk = { 0xf0, 0x1B, 0 } }, /* 01f */ + { .mk = { 0x23, 0 }, .brk = { 0xf0, 0x23, 0 } }, /* 020 */ + { .mk = { 0x2B, 0 }, .brk = { 0xf0, 0x2B, 0 } }, /* 021 */ + { .mk = { 0x34, 0 }, .brk = { 0xf0, 0x34, 0 } }, /* 022 */ + { .mk = { 0x33, 0 }, .brk = { 0xf0, 0x33, 0 } }, /* 023 */ + { .mk = { 0x3B, 0 }, .brk = { 0xf0, 0x3B, 0 } }, /* 024 */ + { .mk = { 0x42, 0 }, .brk = { 0xf0, 0x42, 0 } }, /* 025 */ + { .mk = { 0x4B, 0 }, .brk = { 0xf0, 0x4B, 0 } }, /* 026 */ + { .mk = { 0x4C, 0 }, .brk = { 0xf0, 0x4C, 0 } }, /* 027 */ + { .mk = { 0x52, 0 }, .brk = { 0xf0, 0x52, 0 } }, /* 028 */ + { .mk = { 0x0E, 0 }, .brk = { 0xf0, 0x0E, 0 } }, /* 029 */ + { .mk = { 0x12, 0 }, .brk = { 0xf0, 0x12, 0 } }, /* 02a */ + { .mk = { 0x5C, 0 }, .brk = { 0xf0, 0x5C, 0 } }, /* 02b */ + { .mk = { 0x1A, 0 }, .brk = { 0xf0, 0x1A, 0 } }, /* 02c */ + { .mk = { 0x22, 0 }, .brk = { 0xf0, 0x22, 0 } }, /* 02d */ + { .mk = { 0x21, 0 }, .brk = { 0xf0, 0x21, 0 } }, /* 02e */ + { .mk = { 0x2A, 0 }, .brk = { 0xf0, 0x2A, 0 } }, /* 02f */ + { .mk = { 0x32, 0 }, .brk = { 0xf0, 0x32, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xf0, 0x31, 0 } }, /* 031 */ + { .mk = { 0x3A, 0 }, .brk = { 0xf0, 0x3A, 0 } }, /* 032 */ + { .mk = { 0x41, 0 }, .brk = { 0xf0, 0x41, 0 } }, /* 033 */ + { .mk = { 0x49, 0 }, .brk = { 0xf0, 0x49, 0 } }, /* 034 */ + { .mk = { 0x4A, 0 }, .brk = { 0xf0, 0x4A, 0 } }, /* 035 */ + { .mk = { 0x59, 0 }, .brk = { 0xf0, 0x59, 0 } }, /* 036 */ + { .mk = { 0x7E, 0 }, .brk = { 0xf0, 0x7E, 0 } }, /* 037 */ + { .mk = { 0x19, 0 }, .brk = { 0xf0, 0x19, 0 } }, /* 038 */ + { .mk = { 0x29, 0 }, .brk = { 0xf0, 0x29, 0 } }, /* 039 */ + { .mk = { 0x14, 0 }, .brk = { 0xf0, 0x14, 0 } }, /* 03a */ + { .mk = { 0x07, 0 }, .brk = { 0xf0, 0x07, 0 } }, /* 03b */ + { .mk = { 0x0F, 0 }, .brk = { 0xf0, 0x0F, 0 } }, /* 03c */ + { .mk = { 0x17, 0 }, .brk = { 0xf0, 0x17, 0 } }, /* 03d */ + { .mk = { 0x1F, 0 }, .brk = { 0xf0, 0x1F, 0 } }, /* 03e */ + { .mk = { 0x27, 0 }, .brk = { 0xf0, 0x27, 0 } }, /* 03f */ + { .mk = { 0x2F, 0 }, .brk = { 0xf0, 0x2F, 0 } }, /* 040 */ + { .mk = { 0x37, 0 }, .brk = { 0xf0, 0x37, 0 } }, /* 041 */ + { .mk = { 0x3F, 0 }, .brk = { 0xf0, 0x3F, 0 } }, /* 042 */ + { .mk = { 0x47, 0 }, .brk = { 0xf0, 0x47, 0 } }, /* 043 */ + { .mk = { 0x4F, 0 }, .brk = { 0xf0, 0x4F, 0 } }, /* 044 */ + { .mk = { 0x76, 0 }, .brk = { 0xf0, 0x76, 0 } }, /* 045 */ + { .mk = { 0x5F, 0 }, .brk = { 0xf0, 0x5F, 0 } }, /* 046 */ + { .mk = { 0x6C, 0 }, .brk = { 0xf0, 0x6C, 0 } }, /* 047 */ + { .mk = { 0x75, 0 }, .brk = { 0xf0, 0x75, 0 } }, /* 048 */ + { .mk = { 0x7D, 0 }, .brk = { 0xf0, 0x7D, 0 } }, /* 049 */ + { .mk = { 0x84, 0 }, .brk = { 0xf0, 0x84, 0 } }, /* 04a */ + { .mk = { 0x6B, 0 }, .brk = { 0xf0, 0x6B, 0 } }, /* 04b */ + { .mk = { 0x73, 0 }, .brk = { 0xf0, 0x73, 0 } }, /* 04c */ + { .mk = { 0x74, 0 }, .brk = { 0xf0, 0x74, 0 } }, /* 04d */ + { .mk = { 0x7C, 0 }, .brk = { 0xf0, 0x7C, 0 } }, /* 04e */ + { .mk = { 0x69, 0 }, .brk = { 0xf0, 0x69, 0 } }, /* 04f */ + { .mk = { 0x72, 0 }, .brk = { 0xf0, 0x72, 0 } }, /* 050 */ + { .mk = { 0x7A, 0 }, .brk = { 0xf0, 0x7A, 0 } }, /* 051 */ + { .mk = { 0x70, 0 }, .brk = { 0xf0, 0x70, 0 } }, /* 052 */ + { .mk = { 0x71, 0 }, .brk = { 0xf0, 0x71, 0 } }, /* 053 */ + { .mk = { 0x57, 0 }, .brk = { 0xf0, 0x57, 0 } }, /* 054 */ + { .mk = { 0x60, 0 }, .brk = { 0xf0, 0x60, 0 } }, /* 055 */ + { .mk = { 0 }, .brk = { 0 } }, /* 056 */ + { .mk = { 0x56, 0 }, .brk = { 0xf0, 0x56, 0 } }, /* 057 */ + { .mk = { 0x5E, 0 }, .brk = { 0xf0, 0x5E, 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0x10, 0 }, .brk = { 0xf0, 0x10, 0 } }, /* 065 */ + { .mk = { 0x18, 0 }, .brk = { 0xf0, 0x18, 0 } }, /* 066 */ + { .mk = { 0x20, 0 }, .brk = { 0xf0, 0x20, 0 } }, /* 067 */ + { .mk = { 0x28, 0 }, .brk = { 0xf0, 0x28, 0 } }, /* 068 */ + { .mk = { 0x30, 0 }, .brk = { 0xf0, 0x30, 0 } }, /* 069 */ + { .mk = { 0x38, 0 }, .brk = { 0xf0, 0x38, 0 } }, /* 06a */ + { .mk = { 0x40, 0 }, .brk = { 0xf0, 0x40, 0 } }, /* 06b */ + { .mk = { 0x48, 0 }, .brk = { 0xf0, 0x48, 0 } }, /* 06c */ + { .mk = { 0x50, 0 }, .brk = { 0xf0, 0x50, 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0x87, 0 }, .brk = { 0xf0, 0x87, 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0x51, 0 }, .brk = { 0xf0, 0x51, 0 } }, /* 073 */ + { .mk = { 0x53, 0 }, .brk = { 0xf0, 0x53, 0 } }, /* 074 */ + { .mk = { 0x5C, 0 }, .brk = { 0xf0, 0x5C, 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0x62, 0 }, .brk = { 0xf0, 0x62, 0 } }, /* 077 */ + { .mk = { 0x63, 0 }, .brk = { 0xf0, 0x63, 0 } }, /* 078 */ + { .mk = { 0x86, 0 }, .brk = { 0xf0, 0x86, 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0x85, 0 }, .brk = { 0xf0, 0x85, 0 } }, /* 07b */ + { .mk = { 0x68, 0 }, .brk = { 0xf0, 0x68, 0 } }, /* 07c */ + { .mk = { 0x13, 0 }, .brk = { 0xf0, 0x13, 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 0 } }, /* 07f */ + { .mk = { 0x80, 0 }, .brk = { 0xf0, 0x80, 0 } }, /* 080 */ + { .mk = { 0x81, 0 }, .brk = { 0xf0, 0x81, 0 } }, /* 081 */ + { .mk = { 0x82, 0 }, .brk = { 0xf0, 0x82, 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0x85, 0 }, .brk = { 0xf0, 0x54, 0 } }, /* 085 */ + { .mk = { 0x86, 0 }, .brk = { 0xf0, 0x86, 0 } }, /* 086 */ + { .mk = { 0x87, 0 }, .brk = { 0xf0, 0x87, 0 } }, /* 087 */ + { .mk = { 0x88, 0 }, .brk = { 0xf0, 0x88, 0 } }, /* 087 */ + { .mk = { 0x89, 0 }, .brk = { 0xf0, 0x89, 0 } }, /* 088 */ + { .mk = { 0x8a, 0 }, .brk = { 0xf0, 0x8a, 0 } }, /* 089 */ + { .mk = { 0x8b, 0 }, .brk = { 0xf0, 0x8b, 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0x8e, 0 }, .brk = { 0xf0, 0x8e, 0 } }, /* 08e */ + { .mk = { 0x8f, 0 }, .brk = { 0xf0, 0x8f, 0 } }, /* 08f */ + { .mk = { 0x90, 0 }, .brk = { 0xf0, 0x90, 0 } }, /* 090 */ + { .mk = { 0x91, 0 }, .brk = { 0xf0, 0x91, 0 } }, /* 091 */ + { .mk = { 0x92, 0 }, .brk = { 0xf0, 0x92, 0 } }, /* 092 */ + { .mk = { 0x93, 0 }, .brk = { 0xf0, 0x93, 0 } }, /* 093 */ + { .mk = { 0x94, 0 }, .brk = { 0xf0, 0x94, 0 } }, /* 094 */ + { .mk = { 0x95, 0 }, .brk = { 0xf0, 0x95, 0 } }, /* 095 */ + { .mk = { 0x96, 0 }, .brk = { 0xf0, 0x96, 0 } }, /* 096 */ + { .mk = { 0x97, 0 }, .brk = { 0xf0, 0x97, 0 } }, /* 097 */ + { .mk = { 0x98, 0 }, .brk = { 0xf0, 0x98, 0 } }, /* 098 */ + { .mk = { 0x99, 0 }, .brk = { 0xf0, 0x99, 0 } }, /* 099 */ + { .mk = { 0x9a, 0 }, .brk = { 0xf0, 0x9a, 0 } }, /* 09a */ + { .mk = { 0x9b, 0 }, .brk = { 0xf0, 0x9b, 0 } }, /* 09b */ + { .mk = { 0x9c, 0 }, .brk = { 0xf0, 0x9c, 0 } }, /* 09c */ + { .mk = { 0x9d, 0 }, .brk = { 0xf0, 0x9d, 0 } }, /* 09d */ + { .mk = { 0x9e, 0 }, .brk = { 0xf0, 0x9e, 0 } }, /* 09e */ + { .mk = { 0x9f, 0 }, .brk = { 0xf0, 0x9f, 0 } }, /* 09f */ + { .mk = { 0xa0, 0 }, .brk = { 0xf0, 0xa0, 0 } }, /* 0a0 */ + { .mk = { 0xa1, 0 }, .brk = { 0xf0, 0xa1, 0 } }, /* 0a1 */ + { .mk = { 0xa2, 0 }, .brk = { 0xf0, 0xa2, 0 } }, /* 0a2 */ + { .mk = { 0xa3, 0 }, .brk = { 0xf0, 0xa3, 0 } }, /* 0a3 */ + { .mk = { 0xa4, 0 }, .brk = { 0xf0, 0xa4, 0 } }, /* 0a4 */ + { .mk = { 0xa5, 0 }, .brk = { 0xf0, 0xa5, 0 } }, /* 0a5 */ + { .mk = { 0xa6, 0 }, .brk = { 0xf0, 0xa6, 0 } }, /* 0a6 */ + { .mk = { 0xa7, 0 }, .brk = { 0xf0, 0xa7, 0 } }, /* 0a7 */ + { .mk = { 0xa8, 0 }, .brk = { 0xf0, 0xa8, 0 } }, /* 0a8 */ + { .mk = { 0xa9, 0 }, .brk = { 0xf0, 0xa9, 0 } }, /* 0a9 */ + { .mk = { 0xaa, 0 }, .brk = { 0xf0, 0xaa, 0 } }, /* 0aa */ + { .mk = { 0xab, 0 }, .brk = { 0xf0, 0xab, 0 } }, /* 0ab */ + { .mk = { 0xac, 0 }, .brk = { 0xf0, 0xac, 0 } }, /* 0ac */ + { .mk = { 0xad, 0 }, .brk = { 0xf0, 0xad, 0 } }, /* 0ad */ + { .mk = { 0xae, 0 }, .brk = { 0xf0, 0xae, 0 } }, /* 0ae */ + { .mk = { 0xaf, 0 }, .brk = { 0xf0, 0xaf, 0 } }, /* 0af */ + { .mk = { 0xb0, 0 }, .brk = { 0xf0, 0xb0, 0 } }, /* 0b0 */ + { .mk = { 0xb1, 0 }, .brk = { 0xf0, 0xb1, 0 } }, /* 0b1 */ + { .mk = { 0xb2, 0 }, .brk = { 0xf0, 0xb2, 0 } }, /* 0b2 */ + { .mk = { 0xb3, 0 }, .brk = { 0xf0, 0xb3, 0 } }, /* 0b3 */ + { .mk = { 0xb4, 0 }, .brk = { 0xf0, 0xb4, 0 } }, /* 0b4 */ + { .mk = { 0xb5, 0 }, .brk = { 0xf0, 0xb5, 0 } }, /* 0b5 */ + { .mk = { 0xb6, 0 }, .brk = { 0xf0, 0xb6, 0 } }, /* 0b6 */ + { .mk = { 0xb7, 0 }, .brk = { 0xf0, 0xb7, 0 } }, /* 0b7 */ + { .mk = { 0xb8, 0 }, .brk = { 0xf0, 0xb8, 0 } }, /* 0b8 */ + { .mk = { 0xb9, 0 }, .brk = { 0xf0, 0xb9, 0 } }, /* 0b9 */ + { .mk = { 0xba, 0 }, .brk = { 0xf0, 0xba, 0 } }, /* 0ba */ + { .mk = { 0xbb, 0 }, .brk = { 0xf0, 0xbb, 0 } }, /* 0bb */ + { .mk = { 0xbc, 0 }, .brk = { 0xf0, 0xbc, 0 } }, /* 0bc */ + { .mk = { 0xbd, 0 }, .brk = { 0xf0, 0xbd, 0 } }, /* 0bd */ + { .mk = { 0xbe, 0 }, .brk = { 0xf0, 0xbe, 0 } }, /* 0be */ + { .mk = { 0xbf, 0 }, .brk = { 0xf0, 0xbf, 0 } }, /* 0bf */ + { .mk = { 0xc0, 0 }, .brk = { 0xf0, 0xc0, 0 } }, /* 0c0 */ + { .mk = { 0xc1, 0 }, .brk = { 0xf0, 0xc1, 0 } }, /* 0c1 */ + { .mk = { 0xc2, 0 }, .brk = { 0xf0, 0xc2, 0 } }, /* 0c2 */ + { .mk = { 0xc3, 0 }, .brk = { 0xf0, 0xc3, 0 } }, /* 0c3 */ + { .mk = { 0xc4, 0 }, .brk = { 0xf0, 0xc4, 0 } }, /* 0c4 */ + { .mk = { 0xc5, 0 }, .brk = { 0xf0, 0xc5, 0 } }, /* 0c5 */ + { .mk = { 0xc6, 0 }, .brk = { 0xf0, 0xc6, 0 } }, /* 0c6 */ + { .mk = { 0xc7, 0 }, .brk = { 0xf0, 0xc7, 0 } }, /* 0c7 */ + { .mk = { 0xc8, 0 }, .brk = { 0xf0, 0xc8, 0 } }, /* 0c8 */ + { .mk = { 0xc9, 0 }, .brk = { 0xf0, 0xc9, 0 } }, /* 0c9 */ + { .mk = { 0xca, 0 }, .brk = { 0xf0, 0xca, 0 } }, /* 0ca */ + { .mk = { 0xcb, 0 }, .brk = { 0xf0, 0xcb, 0 } }, /* 0cb */ + { .mk = { 0xcc, 0 }, .brk = { 0xf0, 0xcc, 0 } }, /* 0cc */ + { .mk = { 0xcd, 0 }, .brk = { 0xf0, 0xcd, 0 } }, /* 0cd */ + { .mk = { 0xce, 0 }, .brk = { 0xf0, 0xce, 0 } }, /* 0ce */ + { .mk = { 0xcf, 0 }, .brk = { 0xf0, 0xcf, 0 } }, /* 0cf */ + { .mk = { 0xd0, 0 }, .brk = { 0xf0, 0xd0, 0 } }, /* 0d0 */ + { .mk = { 0xd1, 0 }, .brk = { 0xf0, 0xd0, 0 } }, /* 0d1 */ + { .mk = { 0xd2, 0 }, .brk = { 0xf0, 0xd2, 0 } }, /* 0d2 */ + { .mk = { 0xd3, 0 }, .brk = { 0xf0, 0xd3, 0 } }, /* 0d3 */ + { .mk = { 0xd4, 0 }, .brk = { 0xf0, 0xd4, 0 } }, /* 0d4 */ + { .mk = { 0xd5, 0 }, .brk = { 0xf0, 0xd5, 0 } }, /* 0d5 */ + { .mk = { 0xd6, 0 }, .brk = { 0xf0, 0xd6, 0 } }, /* 0d6 */ + { .mk = { 0xd7, 0 }, .brk = { 0xf0, 0xd7, 0 } }, /* 0d7 */ + { .mk = { 0xd8, 0 }, .brk = { 0xf0, 0xd8, 0 } }, /* 0d8 */ + { .mk = { 0xd9, 0 }, .brk = { 0xf0, 0xd9, 0 } }, /* 0d9 */ + { .mk = { 0xda, 0 }, .brk = { 0xf0, 0xda, 0 } }, /* 0da */ + { .mk = { 0xdb, 0 }, .brk = { 0xf0, 0xdb, 0 } }, /* 0db */ + { .mk = { 0xdc, 0 }, .brk = { 0xf0, 0xdc, 0 } }, /* 0dc */ + { .mk = { 0xdd, 0 }, .brk = { 0xf0, 0xdd, 0 } }, /* 0dd */ + { .mk = { 0xde, 0 }, .brk = { 0xf0, 0xde, 0 } }, /* 0de */ + { .mk = { 0xdf, 0 }, .brk = { 0xf0, 0xdf, 0 } }, /* 0df */ + { .mk = { 0xe0, 0 }, .brk = { 0xf0, 0xe0, 0 } }, /* 0e0 */ + { .mk = { 0xe1, 0 }, .brk = { 0xf0, 0xe1, 0 } }, /* 0e1 */ + { .mk = { 0xe2, 0 }, .brk = { 0xf0, 0xe2, 0 } }, /* 0e2 */ + { .mk = { 0xe3, 0 }, .brk = { 0xf0, 0xe3, 0 } }, /* 0e3 */ + { .mk = { 0xe4, 0 }, .brk = { 0xf0, 0xe4, 0 } }, /* 0e4 */ + { .mk = { 0xe5, 0 }, .brk = { 0xf0, 0xe5, 0 } }, /* 0e5 */ + { .mk = { 0xe6, 0 }, .brk = { 0xf0, 0xe6, 0 } }, /* 0e6 */ + { .mk = { 0xe7, 0 }, .brk = { 0xf0, 0xe7, 0 } }, /* 0e7 */ + { .mk = { 0xe8, 0 }, .brk = { 0xf0, 0xe8, 0 } }, /* 0e7 */ + { .mk = { 0xe9, 0 }, .brk = { 0xf0, 0xe9, 0 } }, /* 0e8 */ + { .mk = { 0xea, 0 }, .brk = { 0xf0, 0xea, 0 } }, /* 0e9 */ + { .mk = { 0xeb, 0 }, .brk = { 0xf0, 0xeb, 0 } }, /* 0eb */ + { .mk = { 0xec, 0 }, .brk = { 0xf0, 0xec, 0 } }, /* 0ec */ + { .mk = { 0xed, 0 }, .brk = { 0xf0, 0xed, 0 } }, /* 0ed */ + { .mk = { 0xee, 0 }, .brk = { 0xf0, 0xee, 0 } }, /* 0ee */ + { .mk = { 0xef, 0 }, .brk = { 0xf0, 0xef, 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { .mk = { 0xf3, 0 }, .brk = { 0xf0, 0xf3, 0 } }, /* 0f3 */ + { .mk = { 0xf4, 0 }, .brk = { 0xf0, 0xf4, 0 } }, /* 0f4 */ + { .mk = { 0xf5, 0 }, .brk = { 0xf0, 0xf5, 0 } }, /* 0f5 */ + { .mk = { 0xf6, 0 }, .brk = { 0xf0, 0xf6, 0 } }, /* 0f6 */ + { .mk = { 0xf7, 0 }, .brk = { 0xf0, 0xf7, 0 } }, /* 0f7 */ + { .mk = { 0xf8, 0 }, .brk = { 0xf0, 0xf8, 0 } }, /* 0f8 */ + { .mk = { 0xf9, 0 }, .brk = { 0xf0, 0xf9, 0 } }, /* 0f9 */ + { .mk = { 0xfa, 0 }, .brk = { 0xf0, 0xfa, 0 } }, /* 0fa */ + { .mk = { 0xfb, 0 }, .brk = { 0xf0, 0xfb, 0 } }, /* 0fb */ + { .mk = { 0xfc, 0 }, .brk = { 0xf0, 0xfc, 0 } }, /* 0fc */ + { .mk = { 0xfd, 0 }, .brk = { 0xf0, 0xfd, 0 } }, /* 0fd */ + { .mk = { 0xfe, 0 }, .brk = { 0xf0, 0xfe, 0 } }, /* 0fe */ + { .mk = { 0xff, 0 }, .brk = { 0xf0, 0xff, 0 } }, /* 0ff */ + { .mk = { 0x62, 0 }, .brk = { 0xF0, 0x62, 0 } }, /* 100 */ + { .mk = {0xe0, 0x76, 0 }, .brk = { 0xe0, 0xF0, 0x76, 0 } }, /* 101 */ + { .mk = {0xe0, 0x16, 0 }, .brk = { 0xe0, 0xF0, 0x16, 0 } }, /* 102 */ + { .mk = {0xe0, 0x1E, 0 }, .brk = { 0xe0, 0xF0, 0x1E, 0 } }, /* 103 */ + { .mk = {0xe0, 0x26, 0 }, .brk = { 0xe0, 0xF0, 0x26, 0 } }, /* 104 */ + { .mk = {0xe0, 0x25, 0 }, .brk = { 0xe0, 0xF0, 0x25, 0 } }, /* 105 */ + { .mk = {0xe0, 0x2E, 0 }, .brk = { 0xe0, 0xF0, 0x2E, 0 } }, /* 106 */ + { .mk = {0xe0, 0x36, 0 }, .brk = { 0xe0, 0xF0, 0x36, 0 } }, /* 107 */ + { .mk = {0xe0, 0x3D, 0 }, .brk = { 0xe0, 0xF0, 0x3D, 0 } }, /* 108 */ + { .mk = {0xe0, 0x3E, 0 }, .brk = { 0xe0, 0xF0, 0x3E, 0 } }, /* 109 */ + { .mk = {0xe0, 0x46, 0 }, .brk = { 0xe0, 0xF0, 0x46, 0 } }, /* 10a */ + { .mk = {0xe0, 0x45, 0 }, .brk = { 0xe0, 0xF0, 0x45, 0 } }, /* 10b */ + { .mk = {0xe0, 0x4E, 0 }, .brk = { 0xe0, 0xF0, 0x4E, 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = {0xe0, 0x66, 0 }, .brk = { 0xe0, 0xF0, 0x66, 0 } }, /* 10e */ + { .mk = {0xe0, 0x0D, 0 }, .brk = { 0xe0, 0xF0, 0x0D, 0 } }, /* 10f */ + { .mk = {0xe0, 0x15, 0 }, .brk = { 0xe0, 0xF0, 0x15, 0 } }, /* 110 */ + { .mk = {0xe0, 0x1D, 0 }, .brk = { 0xe0, 0xF0, 0x1D, 0 } }, /* 111 */ + { .mk = {0xe0, 0x24, 0 }, .brk = { 0xe0, 0xF0, 0x24, 0 } }, /* 112 */ + { .mk = {0xe0, 0x2D, 0 }, .brk = { 0xe0, 0xF0, 0x2D, 0 } }, /* 113 */ + { .mk = {0xe0, 0x2C, 0 }, .brk = { 0xe0, 0xF0, 0x2C, 0 } }, /* 114 */ + { .mk = {0xe0, 0x35, 0 }, .brk = { 0xe0, 0xF0, 0x35, 0 } }, /* 115 */ + { .mk = {0xe0, 0x3C, 0 }, .brk = { 0xe0, 0xF0, 0x3C, 0 } }, /* 116 */ + { .mk = {0xe0, 0x43, 0 }, .brk = { 0xe0, 0xF0, 0x43, 0 } }, /* 117 */ + { .mk = {0xe0, 0x44, 0 }, .brk = { 0xe0, 0xF0, 0x44, 0 } }, /* 118 */ + { .mk = {0xe0, 0x4D, 0 }, .brk = { 0xe0, 0xF0, 0x4D, 0 } }, /* 119 */ + { .mk = {0xe0, 0x54, 0 }, .brk = { 0xe0, 0xF0, 0x54, 0 } }, /* 11a */ + { .mk = {0xe0, 0x5B, 0 }, .brk = { 0xe0, 0xF0, 0x5B, 0 } }, /* 11b */ + { .mk = { 0x79, 0 }, .brk = { 0xf0, 0x79, 0 } }, /* 11c */ + { .mk = { 0x58, 0 }, .brk = { 0xf0, 0x58, 0 } }, /* 11d */ + { .mk = {0xe0, 0x1C, 0 }, .brk = { 0xe0, 0xF0, 0x1C, 0 } }, /* 11e */ + { .mk = {0xe0, 0x1B, 0 }, .brk = { 0xe0, 0xF0, 0x1B, 0 } }, /* 11f */ + { .mk = {0xe0, 0x23, 0 }, .brk = { 0xe0, 0xF0, 0x23, 0 } }, /* 120 */ + { .mk = {0xe0, 0x2B, 0 }, .brk = { 0xe0, 0xF0, 0x2B, 0 } }, /* 121 */ + { .mk = {0xe0, 0x34, 0 }, .brk = { 0xe0, 0xF0, 0x34, 0 } }, /* 122 */ + { .mk = {0xe0, 0x33, 0 }, .brk = { 0xe0, 0xF0, 0x33, 0 } }, /* 123 */ + { .mk = {0xe0, 0x3B, 0 }, .brk = { 0xe0, 0xF0, 0x3B, 0 } }, /* 124 */ + { .mk = {0xe0, 0x42, 0 }, .brk = { 0xe0, 0xF0, 0x42, 0 } }, /* 125 */ + { .mk = {0xe0, 0x4B, 0 }, .brk = { 0xe0, 0xF0, 0x4B, 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = {0xe0, 0x1A, 0 }, .brk = { 0xe0, 0xF0, 0x1A, 0 } }, /* 12c */ + { .mk = {0xe0, 0x22, 0 }, .brk = { 0xe0, 0xF0, 0x22, 0 } }, /* 12d */ + { .mk = {0xe0, 0x21, 0 }, .brk = { 0xe0, 0xF0, 0x21, 0 } }, /* 12e */ + { .mk = {0xe0, 0x2A, 0 }, .brk = { 0xe0, 0xF0, 0x2A, 0 } }, /* 12f */ + { .mk = {0xe0, 0x32, 0 }, .brk = { 0xe0, 0xF0, 0x32, 0 } }, /* 130 */ + { .mk = {0xe0, 0x31, 0 }, .brk = { 0xe0, 0xF0, 0x31, 0 } }, /* 131 */ + { .mk = {0xe0, 0x3A, 0 }, .brk = { 0xe0, 0xF0, 0x3A, 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = {0xe0, 0x49, 0 }, .brk = { 0xe0, 0xF0, 0x49, 0 } }, /* 134 */ + { .mk = { 0x77, 0 }, .brk = { 0xf0, 0x77, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x57, 0 }, .brk = { 0xf0, 0x57, 0 } }, /* 137 */ + { .mk = { 0x39, 0 }, .brk = { 0xf0, 0x39, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xF0, 0x58, 0 } }, /* 13a */ + { .mk = {0xe0, 0x05, 0 }, .brk = { 0xe0, 0xF0, 0x05, 0 } }, /* 13b */ + { .mk = {0xe0, 0x06, 0 }, .brk = { 0xe0, 0xF0, 0x06, 0 } }, /* 13c */ + { .mk = {0xe0, 0x04, 0 }, .brk = { 0xe0, 0xF0, 0x04, 0 } }, /* 13d */ + { .mk = {0xe0, 0x0C, 0 }, .brk = { 0xe0, 0xF0, 0x0C, 0 } }, /* 13e */ + { .mk = {0xe0, 0x03, 0 }, .brk = { 0xe0, 0xF0, 0x03, 0 } }, /* 13f */ + { .mk = {0xe0, 0x0B, 0 }, .brk = { 0xe0, 0xF0, 0x0B, 0 } }, /* 140 */ + { .mk = {0xe0, 0x02, 0 }, .brk = { 0xe0, 0xF0, 0x02, 0 } }, /* 141 */ + { .mk = {0xe0, 0x0A, 0 }, .brk = { 0xe0, 0xF0, 0x0A, 0 } }, /* 142 */ + { .mk = {0xe0, 0x01, 0 }, .brk = { 0xe0, 0xF0, 0x01, 0 } }, /* 143 */ + { .mk = {0xe0, 0x09, 0 }, .brk = { 0xe0, 0xF0, 0x09, 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = {0xe0, 0x7E, 0 }, .brk = { 0xe0, 0xF0, 0x7E, 0 } }, /* 146 */ + { .mk = { 0x6E, 0 }, .brk = { 0xf0, 0x6E, 0 } }, /* 147 */ + { .mk = { 0x63, 0 }, .brk = { 0xf0, 0x63, 0 } }, /* 148 */ + { .mk = { 0x6F, 0 }, .brk = { 0xf0, 0x6F, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x61, 0 }, .brk = { 0xf0, 0x61, 0 } }, /* 14b */ + { .mk = {0xe0, 0x73, 0 }, .brk = { 0xe0, 0xF0, 0x73, 0 } }, /* 14c */ + { .mk = { 0x6A, 0 }, .brk = { 0xf0, 0x6A, 0 } }, /* 14d */ + { .mk = {0xe0, 0x79, 0 }, .brk = { 0xe0, 0xF0, 0x79, 0 } }, /* 14e */ + { .mk = { 0x65, 0 }, .brk = { 0xf0, 0x65, 0 } }, /* 14f */ + { .mk = { 0x60, 0 }, .brk = { 0xf0, 0x60, 0 } }, /* 150 */ + { .mk = { 0x6D, 0 }, .brk = { 0xf0, 0x6D, 0 } }, /* 151 */ + { .mk = { 0x67, 0 }, .brk = { 0xf0, 0x67, 0 } }, /* 152 */ + { .mk = { 0x64, 0 }, .brk = { 0xf0, 0x64, 0 } }, /* 153 */ + { .mk = { 0xd4, 0 }, .brk = { 0xf0, 0xD4, 0 } }, /* 154 */ + { .mk = {0xe0, 0x60, 0 }, .brk = { 0xe0, 0xF0, 0x60, 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = {0xe0, 0x78, 0 }, .brk = { 0xe0, 0xF0, 0x78, 0 } }, /* 157 */ + { .mk = {0xe0, 0x07, 0 }, .brk = { 0xe0, 0xF0, 0x07, 0 } }, /* 158 */ + { .mk = {0xe0, 0x0F, 0 }, .brk = { 0xe0, 0xF0, 0x0F, 0 } }, /* 159 */ + { .mk = {0xe0, 0x17, 0 }, .brk = { 0xe0, 0xF0, 0x17, 0 } }, /* 15a */ + { .mk = { 0x8B, 0 }, .brk = { 0xf0, 0x8B, 0 } }, /* 15b */ + { .mk = { 0x8C, 0 }, .brk = { 0xf0, 0x8C, 0 } }, /* 15c */ + { .mk = { 0x8D, 0 }, .brk = { 0xf0, 0x8D, 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0x7F, 0 }, .brk = { 0xf0, 0x7F, 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = {0xe0, 0x4F, 0 }, .brk = { 0xe0, 0xF0, 0x4F, 0 } }, /* 161 */ + { .mk = {0xe0, 0x56, 0 }, .brk = { 0xe0, 0xF0, 0x56, 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = {0xe0, 0x08, 0 }, .brk = { 0xe0, 0xF0, 0x08, 0 } }, /* 164 */ + { .mk = {0xe0, 0x10, 0 }, .brk = { 0xe0, 0xF0, 0x10, 0 } }, /* 165 */ + { .mk = {0xe0, 0x18, 0 }, .brk = { 0xe0, 0xF0, 0x18, 0 } }, /* 166 */ + { .mk = {0xe0, 0x20, 0 }, .brk = { 0xe0, 0xF0, 0x20, 0 } }, /* 167 */ + { .mk = {0xe0, 0x28, 0 }, .brk = { 0xe0, 0xF0, 0x28, 0 } }, /* 168 */ + { .mk = {0xe0, 0x30, 0 }, .brk = { 0xe0, 0xF0, 0x30, 0 } }, /* 169 */ + { .mk = {0xe0, 0x38, 0 }, .brk = { 0xe0, 0xF0, 0x38, 0 } }, /* 16a */ + { .mk = {0xe0, 0x40, 0 }, .brk = { 0xe0, 0xF0, 0x40, 0 } }, /* 16b */ + { .mk = {0xe0, 0x48, 0 }, .brk = { 0xe0, 0xF0, 0x48, 0 } }, /* 16c */ + { .mk = {0xe0, 0x50, 0 }, .brk = { 0xe0, 0xF0, 0x50, 0 } }, /* 16d */ + { .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xF0, 0x57, 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = {0xe0, 0x13, 0 }, .brk = { 0xe0, 0xF0, 0x13, 0 } }, /* 170 */ + { .mk = {0xe0, 0x19, 0 }, .brk = { 0xe0, 0xF0, 0x19, 0 } }, /* 171 */ + { .mk = {0xe0, 0x39, 0 }, .brk = { 0xe0, 0xF0, 0x39, 0 } }, /* 172 */ + { .mk = {0xe0, 0x51, 0 }, .brk = { 0xe0, 0xF0, 0x51, 0 } }, /* 173 */ + { .mk = {0xe0, 0x53, 0 }, .brk = { 0xe0, 0xF0, 0x53, 0 } }, /* 174 */ + { .mk = {0xe0, 0x5C, 0 }, .brk = { 0xe0, 0xF0, 0x5C, 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = {0xe0, 0x62, 0 }, .brk = { 0xe0, 0xF0, 0x62, 0 } }, /* 177 */ + { .mk = {0xe0, 0x63, 0 }, .brk = { 0xe0, 0xF0, 0x63, 0 } }, /* 178 */ + { .mk = {0xe0, 0x64, 0 }, .brk = { 0xe0, 0xF0, 0x64, 0 } }, /* 179 */ + { .mk = {0xe0, 0x65, 0 }, .brk = { 0xe0, 0xF0, 0x65, 0 } }, /* 17a */ + { .mk = {0xe0, 0x67, 0 }, .brk = { 0xe0, 0xF0, 0x67, 0 } }, /* 17b */ + { .mk = {0xe0, 0x68, 0 }, .brk = { 0xe0, 0xF0, 0x68, 0 } }, /* 17c */ + { .mk = {0xe0, 0x6A, 0 }, .brk = { 0xe0, 0xF0, 0x6A, 0 } }, /* 17d */ + { .mk = {0xe0, 0x6D, 0 }, .brk = { 0xe0, 0xF0, 0x6D, 0 } }, /* 17e */ + { .mk = {0xe0, 0x6E, 0 }, .brk = { 0xe0, 0xF0, 0x6E, 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = {0xe0, 0xe1, 0 }, .brk = { 0xe0, 0xF0, 0xE1, 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = {0xe0, 0xee, 0 }, .brk = { 0xe0, 0xF0, 0xEE, 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = {0xe0, 0xf1, 0 }, .brk = { 0xe0, 0xF0, 0xF1, 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = {0xe0, 0xfe, 0 }, .brk = { 0xe0, 0xF0, 0xFE, 0 } }, /* 1fe */ + { .mk = {0xe0, 0xff, 0 }, .brk = { 0xe0, 0xF0, 0xFF, 0 } } /* 1ff */ // clang-format on }; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index ea2564aa9..63882222e 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -90,518 +90,518 @@ typedef struct xtkbd_t { /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ const scancode scancode_xt[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ - { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, /* 055 */ - { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, /* 057 */ - { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, /* 059 */ - { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, /* 05b */ - { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, /* 05d */ - { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, /* 05f */ - { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, /* 061 */ - { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, /* 063 */ - { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, /* 065 */ - { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, /* 067 */ - { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, /* 069 */ - { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, /* 06b */ - { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, /* 06d */ - { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, /* 06f */ - { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, /* 071 */ - { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, /* 073 */ - { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, /* 075 */ - { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, /* 077 */ - { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, /* 079 */ - { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, /* 07b */ - { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, /* 07d */ - { { 0 }, { 0 } }, /* 07e */ - { { 0 }, { 0 } }, /* 07f */ - { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, /* 081 */ - { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, /* 085 */ - { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, /* 087 */ - { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, /* 089 */ - { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, /* 08b */ - { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, /* 08d */ - { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, /* 08f */ - { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, /* 091 */ - { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, /* 093 */ - { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, /* 095 */ - { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, /* 097 */ - { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, /* 099 */ - { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, /* 09b */ - { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, /* 09d */ - { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, /* 09f */ - { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, /* 0a1 */ - { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, /* 0a3 */ - { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, /* 0a5 */ - { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, /* 0a7 */ - { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, /* 0a9 */ - { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, /* 0ab */ - { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, /* 0ad */ - { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, /* 0af */ - { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, /* 0b1 */ - { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, /* 0b3 */ - { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, /* 0b5 */ - { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, /* 0b7 */ - { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, /* 0b9 */ - { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, /* 0bb */ - { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, /* 0bd */ - { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, /* 0bf */ - { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, /* 0c1 */ - { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, /* 0c3 */ - { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, /* 0c5 */ - { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, /* 0c7 */ - { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, /* 0c9 */ - { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, /* 0cb */ - { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, /* 0cd */ - { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, /* 0cf */ - { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, /* 0d1 */ - { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, /* 0d3 */ - { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, /* 0d5 */ - { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, /* 0d7 */ - { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, /* 0d9 */ - { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, /* 0db */ - { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, /* 0dd */ - { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, /* 0df */ - { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, /* 0e1 */ - { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, /* 0e3 */ - { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, /* 0e5 */ - { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, /* 0e7 */ - { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, /* 0e9 */ - { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, /* 0eb */ - { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, /* 0ed */ - { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, /* 0f1 */ - { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, /* 0f3 */ - { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, /* 0f5 */ - { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, /* 0f7 */ - { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, /* 0f9 */ - { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, /* 0fb */ - { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, /* 0fd */ - { { 0 }, { 0 } }, /* 0fe */ - { { 0 }, { 0 } }, /* 0ff */ - { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, /* 101 */ - { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, /* 103 */ - { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, /* 105 */ - { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, /* 107 */ - { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, /* 109 */ - { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, /* 10b */ - { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, /* 10f */ - { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, /* 111 */ - { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, /* 113 */ - { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, /* 115 */ - { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, /* 117 */ - { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, /* 119 */ - { { 0 }, { 0 } }, /* 11a */ - { { 0 }, { 0 } }, /* 11b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 11c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11d */ - { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, /* 11f */ - { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, /* 121 */ - { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, /* 123 */ - { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, /* 125 */ - { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, /* 12d */ - { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, /* 12f */ - { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, /* 131 */ - { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0 }, { 0 } }, /* 134 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, /* 13b */ - { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, /* 13d */ - { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, /* 13f */ - { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, /* 141 */ - { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, /* 143 */ - { { 0 }, { 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 148 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14b */ - { { 0 }, { 0 } }, /* 14c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14d */ - { { 0 }, { 0 } }, /* 14e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 150 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, /* 157 */ - { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, /* 159 */ - { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, /* 15b */ - { { 0 }, { 0 } }, /* 15c */ - { { 0 }, { 0 } }, /* 15d */ - { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, /* 161 */ - { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, /* 163 */ - { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, /* 165 */ - { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, /* 167 */ - { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, /* 169 */ - { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, /* 16b */ - { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, /* 16d */ - { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, /* 171 */ - { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, /* 173 */ - { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, /* 177 */ - { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, /* 179 */ - { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, /* 17b */ - { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, /* 17d */ - { { 0 }, { 0 } }, /* 17e */ - { { 0 }, { 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0 }, { 0 } }, /* 1fe */ - { { 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0 }, .brk = { 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0 }, .brk = { 0 } }, /* 056 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0 }, .brk = { 0 } }, /* 065 */ + { .mk = { 0 }, .brk = { 0 } }, /* 066 */ + { .mk = { 0 }, .brk = { 0 } }, /* 067 */ + { .mk = { 0 }, .brk = { 0 } }, /* 068 */ + { .mk = { 0 }, .brk = { 0 } }, /* 069 */ + { .mk = { 0 }, .brk = { 0 } }, /* 06a */ + { .mk = { 0 }, .brk = { 0 } }, /* 06b */ + { .mk = { 0 }, .brk = { 0 } }, /* 06c */ + { .mk = { 0 }, .brk = { 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0 }, .brk = { 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0 }, .brk = { 0 } }, /* 073 */ + { .mk = { 0 }, .brk = { 0 } }, /* 074 */ + { .mk = { 0 }, .brk = { 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0 }, .brk = { 0 } }, /* 077 */ + { .mk = { 0 }, .brk = { 0 } }, /* 078 */ + { .mk = { 0 }, .brk = { 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0 }, .brk = { 0 } }, /* 07b */ + { .mk = { 0 }, .brk = { 0 } }, /* 07c */ + { .mk = { 0 }, .brk = { 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 11c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 148 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 150 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0 }, .brk = { 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index a00e7d8e8..530362b89 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2350,518 +2350,518 @@ ams_read(uint16_t port, void *priv) static const scancode scancode_pc200[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ - { { 0x54, 0 }, { 0xd4, 0 } }, /* 054 */ - { { 0x55, 0 }, { 0xd5, 0 } }, /* 055 */ - { { 0x56, 0 }, { 0xd6, 0 } }, /* 056 */ - { { 0x57, 0 }, { 0xd7, 0 } }, /* 057 */ - { { 0x58, 0 }, { 0xd8, 0 } }, /* 058 */ - { { 0x59, 0 }, { 0xd9, 0 } }, /* 059 */ - { { 0x5a, 0 }, { 0xda, 0 } }, /* 05a */ - { { 0x5b, 0 }, { 0xdb, 0 } }, /* 05b */ - { { 0x5c, 0 }, { 0xdc, 0 } }, /* 05c */ - { { 0x5d, 0 }, { 0xdd, 0 } }, /* 05d */ - { { 0x5e, 0 }, { 0xde, 0 } }, /* 05e */ - { { 0x5f, 0 }, { 0xdf, 0 } }, /* 05f */ - { { 0x60, 0 }, { 0xe0, 0 } }, /* 060 */ - { { 0x61, 0 }, { 0xe1, 0 } }, /* 061 */ - { { 0x62, 0 }, { 0xe2, 0 } }, /* 062 */ - { { 0x63, 0 }, { 0xe3, 0 } }, /* 063 */ - { { 0x64, 0 }, { 0xe4, 0 } }, /* 064 */ - { { 0x65, 0 }, { 0xe5, 0 } }, /* 065 */ - { { 0x66, 0 }, { 0xe6, 0 } }, /* 066 */ - { { 0x67, 0 }, { 0xe7, 0 } }, /* 067 */ - { { 0x68, 0 }, { 0xe8, 0 } }, /* 068 */ - { { 0x69, 0 }, { 0xe9, 0 } }, /* 069 */ - { { 0x6a, 0 }, { 0xea, 0 } }, /* 06a */ - { { 0x6b, 0 }, { 0xeb, 0 } }, /* 06b */ - { { 0x6c, 0 }, { 0xec, 0 } }, /* 06c */ - { { 0x6d, 0 }, { 0xed, 0 } }, /* 06d */ - { { 0x6e, 0 }, { 0xee, 0 } }, /* 06e */ - { { 0x6f, 0 }, { 0xef, 0 } }, /* 06f */ - { { 0x70, 0 }, { 0xf0, 0 } }, /* 070 */ - { { 0x71, 0 }, { 0xf1, 0 } }, /* 071 */ - { { 0x72, 0 }, { 0xf2, 0 } }, /* 072 */ - { { 0x73, 0 }, { 0xf3, 0 } }, /* 073 */ - { { 0x74, 0 }, { 0xf4, 0 } }, /* 074 */ - { { 0x75, 0 }, { 0xf5, 0 } }, /* 075 */ - { { 0x76, 0 }, { 0xf6, 0 } }, /* 076 */ - { { 0x77, 0 }, { 0xf7, 0 } }, /* 077 */ - { { 0x78, 0 }, { 0xf8, 0 } }, /* 078 */ - { { 0x79, 0 }, { 0xf9, 0 } }, /* 079 */ - { { 0x7a, 0 }, { 0xfa, 0 } }, /* 07a */ - { { 0x7b, 0 }, { 0xfb, 0 } }, /* 07b */ - { { 0x7c, 0 }, { 0xfc, 0 } }, /* 07c */ - { { 0x7d, 0 }, { 0xfd, 0 } }, /* 07d */ - { { 0x7e, 0 }, { 0xfe, 0 } }, /* 07e */ - { { 0x7f, 0 }, { 0xff, 0 } }, /* 07f */ - { { 0x80, 0 }, { 0 } }, /* 080 */ - { { 0x81, 0 }, { 0 } }, /* 081 */ - { { 0x82, 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0x85, 0 }, { 0 } }, /* 085 */ - { { 0x86, 0 }, { 0 } }, /* 086 */ - { { 0x87, 0 }, { 0 } }, /* 087 */ - { { 0x88, 0 }, { 0 } }, /* 088 */ - { { 0x89, 0 }, { 0 } }, /* 089 */ - { { 0x8a, 0 }, { 0 } }, /* 08a */ - { { 0x8b, 0 }, { 0 } }, /* 08b */ - { { 0x8c, 0 }, { 0 } }, /* 08c */ - { { 0x8d, 0 }, { 0 } }, /* 08d */ - { { 0x8e, 0 }, { 0 } }, /* 08e */ - { { 0x8f, 0 }, { 0 } }, /* 08f */ - { { 0x90, 0 }, { 0 } }, /* 090 */ - { { 0x91, 0 }, { 0 } }, /* 091 */ - { { 0x92, 0 }, { 0 } }, /* 092 */ - { { 0x93, 0 }, { 0 } }, /* 093 */ - { { 0x94, 0 }, { 0 } }, /* 094 */ - { { 0x95, 0 }, { 0 } }, /* 095 */ - { { 0x96, 0 }, { 0 } }, /* 096 */ - { { 0x97, 0 }, { 0 } }, /* 097 */ - { { 0x98, 0 }, { 0 } }, /* 098 */ - { { 0x99, 0 }, { 0 } }, /* 099 */ - { { 0x9a, 0 }, { 0 } }, /* 09a */ - { { 0x9b, 0 }, { 0 } }, /* 09b */ - { { 0x9c, 0 }, { 0 } }, /* 09c */ - { { 0x9d, 0 }, { 0 } }, /* 09d */ - { { 0x9e, 0 }, { 0 } }, /* 09e */ - { { 0x9f, 0 }, { 0 } }, /* 09f */ - { { 0xa0, 0 }, { 0 } }, /* 0a0 */ - { { 0xa1, 0 }, { 0 } }, /* 0a1 */ - { { 0xa2, 0 }, { 0 } }, /* 0a2 */ - { { 0xa3, 0 }, { 0 } }, /* 0a3 */ - { { 0xa4, 0 }, { 0 } }, /* 0a4 */ - { { 0xa5, 0 }, { 0 } }, /* 0a5 */ - { { 0xa6, 0 }, { 0 } }, /* 0a6 */ - { { 0xa7, 0 }, { 0 } }, /* 0a7 */ - { { 0xa8, 0 }, { 0 } }, /* 0a8 */ - { { 0xa9, 0 }, { 0 } }, /* 0a9 */ - { { 0xaa, 0 }, { 0 } }, /* 0aa */ - { { 0xab, 0 }, { 0 } }, /* 0ab */ - { { 0xac, 0 }, { 0 } }, /* 0ac */ - { { 0xad, 0 }, { 0 } }, /* 0ad */ - { { 0xae, 0 }, { 0 } }, /* 0ae */ - { { 0xaf, 0 }, { 0 } }, /* 0af */ - { { 0xb0, 0 }, { 0 } }, /* 0b0 */ - { { 0xb1, 0 }, { 0 } }, /* 0b1 */ - { { 0xb2, 0 }, { 0 } }, /* 0b2 */ - { { 0xb3, 0 }, { 0 } }, /* 0b3 */ - { { 0xb4, 0 }, { 0 } }, /* 0b4 */ - { { 0xb5, 0 }, { 0 } }, /* 0b5 */ - { { 0xb6, 0 }, { 0 } }, /* 0b6 */ - { { 0xb7, 0 }, { 0 } }, /* 0b7 */ - { { 0xb8, 0 }, { 0 } }, /* 0b8 */ - { { 0xb9, 0 }, { 0 } }, /* 0b9 */ - { { 0xba, 0 }, { 0 } }, /* 0ba */ - { { 0xbb, 0 }, { 0 } }, /* 0bb */ - { { 0xbc, 0 }, { 0 } }, /* 0bc */ - { { 0xbd, 0 }, { 0 } }, /* 0bd */ - { { 0xbe, 0 }, { 0 } }, /* 0be */ - { { 0xbf, 0 }, { 0 } }, /* 0bf */ - { { 0xc0, 0 }, { 0 } }, /* 0c0 */ - { { 0xc1, 0 }, { 0 } }, /* 0c1 */ - { { 0xc2, 0 }, { 0 } }, /* 0c2 */ - { { 0xc3, 0 }, { 0 } }, /* 0c3 */ - { { 0xc4, 0 }, { 0 } }, /* 0c4 */ - { { 0xc5, 0 }, { 0 } }, /* 0c5 */ - { { 0xc6, 0 }, { 0 } }, /* 0c6 */ - { { 0xc7, 0 }, { 0 } }, /* 0c7 */ - { { 0xc8, 0 }, { 0 } }, /* 0c8 */ - { { 0xc9, 0 }, { 0 } }, /* 0c9 */ - { { 0xca, 0 }, { 0 } }, /* 0ca */ - { { 0xcb, 0 }, { 0 } }, /* 0cb */ - { { 0xcc, 0 }, { 0 } }, /* 0cc */ - { { 0xcd, 0 }, { 0 } }, /* 0cd */ - { { 0xce, 0 }, { 0 } }, /* 0ce */ - { { 0xcf, 0 }, { 0 } }, /* 0cf */ - { { 0xd0, 0 }, { 0 } }, /* 0d0 */ - { { 0xd1, 0 }, { 0 } }, /* 0d1 */ - { { 0xd2, 0 }, { 0 } }, /* 0d2 */ - { { 0xd3, 0 }, { 0 } }, /* 0d3 */ - { { 0xd4, 0 }, { 0 } }, /* 0d4 */ - { { 0xd5, 0 }, { 0 } }, /* 0d5 */ - { { 0xd6, 0 }, { 0 } }, /* 0d6 */ - { { 0xd7, 0 }, { 0 } }, /* 0d7 */ - { { 0xd8, 0 }, { 0 } }, /* 0d8 */ - { { 0xd9, 0 }, { 0 } }, /* 0d9 */ - { { 0xda, 0 }, { 0 } }, /* 0da */ - { { 0xdb, 0 }, { 0 } }, /* 0db */ - { { 0xdc, 0 }, { 0 } }, /* 0dc */ - { { 0xdd, 0 }, { 0 } }, /* 0dd */ - { { 0xde, 0 }, { 0 } }, /* 0de */ - { { 0xdf, 0 }, { 0 } }, /* 0df */ - { { 0xe0, 0 }, { 0 } }, /* 0e0 */ - { { 0xe1, 0 }, { 0 } }, /* 0e1 */ - { { 0xe2, 0 }, { 0 } }, /* 0e2 */ - { { 0xe3, 0 }, { 0 } }, /* 0e3 */ - { { 0xe4, 0 }, { 0 } }, /* 0e4 */ - { { 0xe5, 0 }, { 0 } }, /* 0e5 */ - { { 0xe6, 0 }, { 0 } }, /* 0e6 */ - { { 0xe7, 0 }, { 0 } }, /* 0e7 */ - { { 0xe8, 0 }, { 0 } }, /* 0e8 */ - { { 0xe9, 0 }, { 0 } }, /* 0e9 */ - { { 0xea, 0 }, { 0 } }, /* 0ea */ - { { 0xeb, 0 }, { 0 } }, /* 0eb */ - { { 0xec, 0 }, { 0 } }, /* 0ec */ - { { 0xed, 0 }, { 0 } }, /* 0ed */ - { { 0xee, 0 }, { 0 } }, /* 0ee */ - { { 0xef, 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0xf1, 0 }, { 0 } }, /* 0f1 */ - { { 0xf2, 0 }, { 0 } }, /* 0f2 */ - { { 0xf3, 0 }, { 0 } }, /* 0f3 */ - { { 0xf4, 0 }, { 0 } }, /* 0f4 */ - { { 0xf5, 0 }, { 0 } }, /* 0f5 */ - { { 0xf6, 0 }, { 0 } }, /* 0f6 */ - { { 0xf7, 0 }, { 0 } }, /* 0f7 */ - { { 0xf8, 0 }, { 0 } }, /* 0f8 */ - { { 0xf9, 0 }, { 0 } }, /* 0f9 */ - { { 0xfa, 0 }, { 0 } }, /* 0fa */ - { { 0xfb, 0 }, { 0 } }, /* 0fb */ - { { 0xfc, 0 }, { 0 } }, /* 0fc */ - { { 0xfd, 0 }, { 0 } }, /* 0fd */ - { { 0xfe, 0 }, { 0 } }, /* 0fe */ - { { 0xff, 0 }, { 0 } }, /* 0ff */ - { { 0xe1, 0x1d, 0 }, { 0xe1, 0x9d, 0 } }, /* 100 */ - { { 0xe0, 0x01, 0 }, { 0xe0, 0x81, 0 } }, /* 101 */ - { { 0xe0, 0x02, 0 }, { 0xe0, 0x82, 0 } }, /* 102 */ - { { 0xe0, 0x03, 0 }, { 0xe0, 0x83, 0 } }, /* 103 */ - { { 0xe0, 0x04, 0 }, { 0xe0, 0x84, 0 } }, /* 104 */ - { { 0xe0, 0x05, 0 }, { 0xe0, 0x85, 0 } }, /* 105 */ - { { 0xe0, 0x06, 0 }, { 0xe0, 0x86, 0 } }, /* 106 */ - { { 0xe0, 0x07, 0 }, { 0xe0, 0x87, 0 } }, /* 107 */ - { { 0xe0, 0x08, 0 }, { 0xe0, 0x88, 0 } }, /* 108 */ - { { 0xe0, 0x09, 0 }, { 0xe0, 0x89, 0 } }, /* 109 */ - { { 0xe0, 0x0a, 0 }, { 0xe0, 0x8a, 0 } }, /* 10a */ - { { 0xe0, 0x0b, 0 }, { 0xe0, 0x8b, 0 } }, /* 10b */ - { { 0xe0, 0x0c, 0 }, { 0xe0, 0x8c, 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0xe0, 0x0e, 0 }, { 0xe0, 0x8e, 0 } }, /* 10e */ - { { 0xe0, 0x0f, 0 }, { 0xe0, 0x8f, 0 } }, /* 10f */ - { { 0xe0, 0x10, 0 }, { 0xe0, 0x90, 0 } }, /* 110 */ - { { 0xe0, 0x11, 0 }, { 0xe0, 0x91, 0 } }, /* 111 */ - { { 0xe0, 0x12, 0 }, { 0xe0, 0x92, 0 } }, /* 112 */ - { { 0xe0, 0x13, 0 }, { 0xe0, 0x93, 0 } }, /* 113 */ - { { 0xe0, 0x14, 0 }, { 0xe0, 0x94, 0 } }, /* 114 */ - { { 0xe0, 0x15, 0 }, { 0xe0, 0x95, 0 } }, /* 115 */ - { { 0xe0, 0x16, 0 }, { 0xe0, 0x96, 0 } }, /* 116 */ - { { 0xe0, 0x17, 0 }, { 0xe0, 0x97, 0 } }, /* 117 */ - { { 0xe0, 0x18, 0 }, { 0xe0, 0x98, 0 } }, /* 118 */ - { { 0xe0, 0x19, 0 }, { 0xe0, 0x99, 0 } }, /* 119 */ - { { 0xe0, 0x1a, 0 }, { 0xe0, 0x9a, 0 } }, /* 11a */ - { { 0xe0, 0x1b, 0 }, { 0xe0, 0x9b, 0 } }, /* 11b */ - { { 0xe0, 0x1c, 0 }, { 0xe0, 0x9c, 0 } }, /* 11c */ - { { 0xe0, 0x1d, 0 }, { 0xe0, 0x9d, 0 } }, /* 11d */ - { { 0xe0, 0x1e, 0 }, { 0xe0, 0x9e, 0 } }, /* 11e */ - { { 0xe0, 0x1f, 0 }, { 0xe0, 0x9f, 0 } }, /* 11f */ - { { 0xe0, 0x20, 0 }, { 0xe0, 0xa0, 0 } }, /* 120 */ - { { 0xe0, 0x21, 0 }, { 0xe0, 0xa1, 0 } }, /* 121 */ - { { 0xe0, 0x22, 0 }, { 0xe0, 0xa2, 0 } }, /* 122 */ - { { 0xe0, 0x23, 0 }, { 0xe0, 0xa3, 0 } }, /* 123 */ - { { 0xe0, 0x24, 0 }, { 0xe0, 0xa4, 0 } }, /* 124 */ - { { 0xe0, 0x25, 0 }, { 0xe0, 0xa5, 0 } }, /* 125 */ - { { 0xe0, 0x26, 0 }, { 0xe0, 0xa6, 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0xe0, 0x2c, 0 }, { 0xe0, 0xac, 0 } }, /* 12c */ - { { 0xe0, 0x2d, 0 }, { 0xe0, 0xad, 0 } }, /* 12d */ - { { 0xe0, 0x2e, 0 }, { 0xe0, 0xae, 0 } }, /* 12e */ - { { 0xe0, 0x2f, 0 }, { 0xe0, 0xaf, 0 } }, /* 12f */ - { { 0xe0, 0x30, 0 }, { 0xe0, 0xb0, 0 } }, /* 130 */ - { { 0xe0, 0x31, 0 }, { 0xe0, 0xb1, 0 } }, /* 131 */ - { { 0xe0, 0x32, 0 }, { 0xe0, 0xb2, 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0xe0, 0x34, 0 }, { 0xe0, 0xb4, 0 } }, /* 134 */ - { { 0xe0, 0x35, 0 }, { 0xe0, 0xb5, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0xe0, 0x37, 0 }, { 0xe0, 0xb7, 0 } }, /* 137 */ - { { 0xe0, 0x38, 0 }, { 0xe0, 0xb8, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0xe0, 0x3a, 0 }, { 0xe0, 0xba, 0 } }, /* 13a */ - { { 0xe0, 0x3b, 0 }, { 0xe0, 0xbb, 0 } }, /* 13b */ - { { 0xe0, 0x3c, 0 }, { 0xe0, 0xbc, 0 } }, /* 13c */ - { { 0xe0, 0x3d, 0 }, { 0xe0, 0xbd, 0 } }, /* 13d */ - { { 0xe0, 0x3e, 0 }, { 0xe0, 0xbe, 0 } }, /* 13e */ - { { 0xe0, 0x3f, 0 }, { 0xe0, 0xbf, 0 } }, /* 13f */ - { { 0xe0, 0x40, 0 }, { 0xe0, 0xc0, 0 } }, /* 140 */ - { { 0xe0, 0x41, 0 }, { 0xe0, 0xc1, 0 } }, /* 141 */ - { { 0xe0, 0x42, 0 }, { 0xe0, 0xc2, 0 } }, /* 142 */ - { { 0xe0, 0x43, 0 }, { 0xe0, 0xc3, 0 } }, /* 143 */ - { { 0xe0, 0x44, 0 }, { 0xe0, 0xc4, 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0xe0, 0x46, 0 }, { 0xe0, 0xc6, 0 } }, /* 146 */ - { { 0xe0, 0x47, 0 }, { 0xe0, 0xc7, 0 } }, /* 147 */ - { { 0xe0, 0x48, 0 }, { 0xe0, 0xc8, 0 } }, /* 148 */ - { { 0xe0, 0x49, 0 }, { 0xe0, 0xc9, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0xe0, 0x4b, 0 }, { 0xe0, 0xcb, 0 } }, /* 14b */ - { { 0xe0, 0x4c, 0 }, { 0xe0, 0xcc, 0 } }, /* 14c */ - { { 0xe0, 0x4d, 0 }, { 0xe0, 0xcd, 0 } }, /* 14d */ - { { 0xe0, 0x4e, 0 }, { 0xe0, 0xce, 0 } }, /* 14e */ - { { 0xe0, 0x4f, 0 }, { 0xe0, 0xcf, 0 } }, /* 14f */ - { { 0xe0, 0x50, 0 }, { 0xe0, 0xd0, 0 } }, /* 150 */ - { { 0xe0, 0x51, 0 }, { 0xe0, 0xd1, 0 } }, /* 151 */ - { { 0xe0, 0x52, 0 }, { 0xe0, 0xd2, 0 } }, /* 152 */ - { { 0xe0, 0x53, 0 }, { 0xe0, 0xd3, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0xe0, 0x55, 0 }, { 0xe0, 0xd5, 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0xe0, 0x57, 0 }, { 0xe0, 0xd7, 0 } }, /* 157 */ - { { 0xe0, 0x58, 0 }, { 0xe0, 0xd8, 0 } }, /* 158 */ - { { 0xe0, 0x59, 0 }, { 0xe0, 0xd9, 0 } }, /* 159 */ - { { 0xe0, 0x5a, 0 }, { 0xe0, 0xaa, 0 } }, /* 15a */ - { { 0xe0, 0x5b, 0 }, { 0xe0, 0xdb, 0 } }, /* 15b */ - { { 0xe0, 0x5c, 0 }, { 0xe0, 0xdc, 0 } }, /* 15c */ - { { 0xe0, 0x5d, 0 }, { 0xe0, 0xdd, 0 } }, /* 15d */ - { { 0xe0, 0x5e, 0 }, { 0xe0, 0xee, 0 } }, /* 15e */ - { { 0xe0, 0x5f, 0 }, { 0xe0, 0xdf, 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0xe0, 0x61, 0 }, { 0xe0, 0xe1, 0 } }, /* 161 */ - { { 0xe0, 0x62, 0 }, { 0xe0, 0xe2, 0 } }, /* 162 */ - { { 0xe0, 0x63, 0 }, { 0xe0, 0xe3, 0 } }, /* 163 */ - { { 0xe0, 0x64, 0 }, { 0xe0, 0xe4, 0 } }, /* 164 */ - { { 0xe0, 0x65, 0 }, { 0xe0, 0xe5, 0 } }, /* 165 */ - { { 0xe0, 0x66, 0 }, { 0xe0, 0xe6, 0 } }, /* 166 */ - { { 0xe0, 0x67, 0 }, { 0xe0, 0xe7, 0 } }, /* 167 */ - { { 0xe0, 0x68, 0 }, { 0xe0, 0xe8, 0 } }, /* 168 */ - { { 0xe0, 0x69, 0 }, { 0xe0, 0xe9, 0 } }, /* 169 */ - { { 0xe0, 0x6a, 0 }, { 0xe0, 0xea, 0 } }, /* 16a */ - { { 0xe0, 0x6b, 0 }, { 0xe0, 0xeb, 0 } }, /* 16b */ - { { 0xe0, 0x6c, 0 }, { 0xe0, 0xec, 0 } }, /* 16c */ - { { 0xe0, 0x6d, 0 }, { 0xe0, 0xed, 0 } }, /* 16d */ - { { 0xe0, 0x6e, 0 }, { 0xe0, 0xee, 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0xe0, 0x70, 0 }, { 0xe0, 0xf0, 0 } }, /* 170 */ - { { 0xe0, 0x71, 0 }, { 0xe0, 0xf1, 0 } }, /* 171 */ - { { 0xe0, 0x72, 0 }, { 0xe0, 0xf2, 0 } }, /* 172 */ - { { 0xe0, 0x73, 0 }, { 0xe0, 0xf3, 0 } }, /* 173 */ - { { 0xe0, 0x74, 0 }, { 0xe0, 0xf4, 0 } }, /* 174 */ - { { 0xe0, 0x75, 0 }, { 0xe0, 0xf5, 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0xe0, 0x77, 0 }, { 0xe0, 0xf7, 0 } }, /* 177 */ - { { 0xe0, 0x78, 0 }, { 0xe0, 0xf8, 0 } }, /* 178 */ - { { 0xe0, 0x79, 0 }, { 0xe0, 0xf9, 0 } }, /* 179 */ - { { 0xe0, 0x7a, 0 }, { 0xe0, 0xfa, 0 } }, /* 17a */ - { { 0xe0, 0x7b, 0 }, { 0xe0, 0xfb, 0 } }, /* 17b */ - { { 0xe0, 0x7c, 0 }, { 0xe0, 0xfc, 0 } }, /* 17c */ - { { 0xe0, 0x7d, 0 }, { 0xe0, 0xfd, 0 } }, /* 17d */ - { { 0xe0, 0x7e, 0 }, { 0xe0, 0xfe, 0 } }, /* 17e */ - { { 0xe0, 0x7f, 0 }, { 0xe0, 0xff, 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0xe0, 0xe1, 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0xe0, 0xee, 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0xe0, 0xf1, 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0xe0, 0xfe, 0 }, { 0 } }, /* 1fe */ - { { 0xe0, 0xff, 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 054 */ + { .mk = { 0x55, 0 }, .brk = { 0xd5, 0 } }, /* 055 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 056 */ + { .mk = { 0x57, 0 }, .brk = { 0xd7, 0 } }, /* 057 */ + { .mk = { 0x58, 0 }, .brk = { 0xd8, 0 } }, /* 058 */ + { .mk = { 0x59, 0 }, .brk = { 0xd9, 0 } }, /* 059 */ + { .mk = { 0x5a, 0 }, .brk = { 0xda, 0 } }, /* 05a */ + { .mk = { 0x5b, 0 }, .brk = { 0xdb, 0 } }, /* 05b */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 05c */ + { .mk = { 0x5d, 0 }, .brk = { 0xdd, 0 } }, /* 05d */ + { .mk = { 0x5e, 0 }, .brk = { 0xde, 0 } }, /* 05e */ + { .mk = { 0x5f, 0 }, .brk = { 0xdf, 0 } }, /* 05f */ + { .mk = { 0x60, 0 }, .brk = { 0xe0, 0 } }, /* 060 */ + { .mk = { 0x61, 0 }, .brk = { 0xe1, 0 } }, /* 061 */ + { .mk = { 0x62, 0 }, .brk = { 0xe2, 0 } }, /* 062 */ + { .mk = { 0x63, 0 }, .brk = { 0xe3, 0 } }, /* 063 */ + { .mk = { 0x64, 0 }, .brk = { 0xe4, 0 } }, /* 064 */ + { .mk = { 0x65, 0 }, .brk = { 0xe5, 0 } }, /* 065 */ + { .mk = { 0x66, 0 }, .brk = { 0xe6, 0 } }, /* 066 */ + { .mk = { 0x67, 0 }, .brk = { 0xe7, 0 } }, /* 067 */ + { .mk = { 0x68, 0 }, .brk = { 0xe8, 0 } }, /* 068 */ + { .mk = { 0x69, 0 }, .brk = { 0xe9, 0 } }, /* 069 */ + { .mk = { 0x6a, 0 }, .brk = { 0xea, 0 } }, /* 06a */ + { .mk = { 0x6b, 0 }, .brk = { 0xeb, 0 } }, /* 06b */ + { .mk = { 0x6c, 0 }, .brk = { 0xec, 0 } }, /* 06c */ + { .mk = { 0x6d, 0 }, .brk = { 0xed, 0 } }, /* 06d */ + { .mk = { 0x6e, 0 }, .brk = { 0xee, 0 } }, /* 06e */ + { .mk = { 0x6f, 0 }, .brk = { 0xef, 0 } }, /* 06f */ + { .mk = { 0x70, 0 }, .brk = { 0xf0, 0 } }, /* 070 */ + { .mk = { 0x71, 0 }, .brk = { 0xf1, 0 } }, /* 071 */ + { .mk = { 0x72, 0 }, .brk = { 0xf2, 0 } }, /* 072 */ + { .mk = { 0x73, 0 }, .brk = { 0xf3, 0 } }, /* 073 */ + { .mk = { 0x74, 0 }, .brk = { 0xf4, 0 } }, /* 074 */ + { .mk = { 0x75, 0 }, .brk = { 0xf5, 0 } }, /* 075 */ + { .mk = { 0x76, 0 }, .brk = { 0xf6, 0 } }, /* 076 */ + { .mk = { 0x77, 0 }, .brk = { 0xf7, 0 } }, /* 077 */ + { .mk = { 0x78, 0 }, .brk = { 0xf8, 0 } }, /* 078 */ + { .mk = { 0x79, 0 }, .brk = { 0xf9, 0 } }, /* 079 */ + { .mk = { 0x7a, 0 }, .brk = { 0xfa, 0 } }, /* 07a */ + { .mk = { 0x7b, 0 }, .brk = { 0xfb, 0 } }, /* 07b */ + { .mk = { 0x7c, 0 }, .brk = { 0xfc, 0 } }, /* 07c */ + { .mk = { 0x7d, 0 }, .brk = { 0xfd, 0 } }, /* 07d */ + { .mk = { 0x7e, 0 }, .brk = { 0xfe, 0 } }, /* 07e */ + { .mk = { 0x7f, 0 }, .brk = { 0xff, 0 } }, /* 07f */ + { .mk = { 0x80, 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0x81, 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0x82, 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0x85, 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0x86, 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0x87, 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0x88, 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0x89, 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0x8a, 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0x8b, 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0x8c, 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0x8d, 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0x8e, 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0x8f, 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0x90, 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0x91, 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0x92, 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0x93, 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0x94, 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0x95, 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0x96, 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0x97, 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0x98, 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0x99, 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0x9a, 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0x9b, 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0x9c, 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0x9d, 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0x9e, 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0x9f, 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0xa0, 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0xa1, 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0xa2, 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0xa3, 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0xa4, 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0xa5, 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0xa6, 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0xa7, 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0xa8, 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0xa9, 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0xaa, 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0xab, 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0xac, 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0xad, 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0xae, 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0xaf, 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0xb0, 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0xb1, 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0xb2, 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0xb3, 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0xb4, 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0xb5, 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0xb6, 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0xb7, 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0xb8, 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0xb9, 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0xba, 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0xbb, 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0xbc, 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0xbd, 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0xbe, 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0xbf, 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0xc0, 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0xc1, 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0xc2, 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0xc3, 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0xc4, 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0xc5, 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0xc6, 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0xc7, 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0xc8, 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0xc9, 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0xca, 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0xcb, 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0xcc, 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0xcd, 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0xce, 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0xcf, 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0xd0, 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0xd1, 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0xd2, 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0xd3, 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0xd4, 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0xd5, 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0xd6, 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0xd7, 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0xd8, 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0xd9, 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0xda, 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0xdb, 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0xdc, 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0xdd, 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0xde, 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0xdf, 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0xe0, 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0xe1, 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0xe2, 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0xe3, 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0xe4, 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0xe5, 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0xe6, 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0xe7, 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0xe8, 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0xe9, 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0xea, 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0xeb, 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0xec, 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0xed, 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0xee, 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0xef, 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0xf3, 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0xf4, 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0xf5, 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0xf6, 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0xf7, 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0xf8, 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0xf9, 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0xfa, 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0xfb, 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0xfc, 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0xfd, 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0xfe, 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0xff, 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = {0xe1, 0x1d, 0 }, .brk = { 0xe1, 0x9d, 0 } }, /* 100 */ + { .mk = {0xe0, 0x01, 0 }, .brk = { 0xe0, 0x81, 0 } }, /* 101 */ + { .mk = {0xe0, 0x02, 0 }, .brk = { 0xe0, 0x82, 0 } }, /* 102 */ + { .mk = {0xe0, 0x03, 0 }, .brk = { 0xe0, 0x83, 0 } }, /* 103 */ + { .mk = {0xe0, 0x04, 0 }, .brk = { 0xe0, 0x84, 0 } }, /* 104 */ + { .mk = {0xe0, 0x05, 0 }, .brk = { 0xe0, 0x85, 0 } }, /* 105 */ + { .mk = {0xe0, 0x06, 0 }, .brk = { 0xe0, 0x86, 0 } }, /* 106 */ + { .mk = {0xe0, 0x07, 0 }, .brk = { 0xe0, 0x87, 0 } }, /* 107 */ + { .mk = {0xe0, 0x08, 0 }, .brk = { 0xe0, 0x88, 0 } }, /* 108 */ + { .mk = {0xe0, 0x09, 0 }, .brk = { 0xe0, 0x89, 0 } }, /* 109 */ + { .mk = {0xe0, 0x0a, 0 }, .brk = { 0xe0, 0x8a, 0 } }, /* 10a */ + { .mk = {0xe0, 0x0b, 0 }, .brk = { 0xe0, 0x8b, 0 } }, /* 10b */ + { .mk = {0xe0, 0x0c, 0 }, .brk = { 0xe0, 0x8c, 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = {0xe0, 0x0e, 0 }, .brk = { 0xe0, 0x8e, 0 } }, /* 10e */ + { .mk = {0xe0, 0x0f, 0 }, .brk = { 0xe0, 0x8f, 0 } }, /* 10f */ + { .mk = {0xe0, 0x10, 0 }, .brk = { 0xe0, 0x90, 0 } }, /* 110 */ + { .mk = {0xe0, 0x11, 0 }, .brk = { 0xe0, 0x91, 0 } }, /* 111 */ + { .mk = {0xe0, 0x12, 0 }, .brk = { 0xe0, 0x92, 0 } }, /* 112 */ + { .mk = {0xe0, 0x13, 0 }, .brk = { 0xe0, 0x93, 0 } }, /* 113 */ + { .mk = {0xe0, 0x14, 0 }, .brk = { 0xe0, 0x94, 0 } }, /* 114 */ + { .mk = {0xe0, 0x15, 0 }, .brk = { 0xe0, 0x95, 0 } }, /* 115 */ + { .mk = {0xe0, 0x16, 0 }, .brk = { 0xe0, 0x96, 0 } }, /* 116 */ + { .mk = {0xe0, 0x17, 0 }, .brk = { 0xe0, 0x97, 0 } }, /* 117 */ + { .mk = {0xe0, 0x18, 0 }, .brk = { 0xe0, 0x98, 0 } }, /* 118 */ + { .mk = {0xe0, 0x19, 0 }, .brk = { 0xe0, 0x99, 0 } }, /* 119 */ + { .mk = {0xe0, 0x1a, 0 }, .brk = { 0xe0, 0x9a, 0 } }, /* 11a */ + { .mk = {0xe0, 0x1b, 0 }, .brk = { 0xe0, 0x9b, 0 } }, /* 11b */ + { .mk = {0xe0, 0x1c, 0 }, .brk = { 0xe0, 0x9c, 0 } }, /* 11c */ + { .mk = {0xe0, 0x1d, 0 }, .brk = { 0xe0, 0x9d, 0 } }, /* 11d */ + { .mk = {0xe0, 0x1e, 0 }, .brk = { 0xe0, 0x9e, 0 } }, /* 11e */ + { .mk = {0xe0, 0x1f, 0 }, .brk = { 0xe0, 0x9f, 0 } }, /* 11f */ + { .mk = {0xe0, 0x20, 0 }, .brk = { 0xe0, 0xa0, 0 } }, /* 120 */ + { .mk = {0xe0, 0x21, 0 }, .brk = { 0xe0, 0xa1, 0 } }, /* 121 */ + { .mk = {0xe0, 0x22, 0 }, .brk = { 0xe0, 0xa2, 0 } }, /* 122 */ + { .mk = {0xe0, 0x23, 0 }, .brk = { 0xe0, 0xa3, 0 } }, /* 123 */ + { .mk = {0xe0, 0x24, 0 }, .brk = { 0xe0, 0xa4, 0 } }, /* 124 */ + { .mk = {0xe0, 0x25, 0 }, .brk = { 0xe0, 0xa5, 0 } }, /* 125 */ + { .mk = {0xe0, 0x26, 0 }, .brk = { 0xe0, 0xa6, 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = {0xe0, 0x2c, 0 }, .brk = { 0xe0, 0xac, 0 } }, /* 12c */ + { .mk = {0xe0, 0x2d, 0 }, .brk = { 0xe0, 0xad, 0 } }, /* 12d */ + { .mk = {0xe0, 0x2e, 0 }, .brk = { 0xe0, 0xae, 0 } }, /* 12e */ + { .mk = {0xe0, 0x2f, 0 }, .brk = { 0xe0, 0xaf, 0 } }, /* 12f */ + { .mk = {0xe0, 0x30, 0 }, .brk = { 0xe0, 0xb0, 0 } }, /* 130 */ + { .mk = {0xe0, 0x31, 0 }, .brk = { 0xe0, 0xb1, 0 } }, /* 131 */ + { .mk = {0xe0, 0x32, 0 }, .brk = { 0xe0, 0xb2, 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = {0xe0, 0x34, 0 }, .brk = { 0xe0, 0xb4, 0 } }, /* 134 */ + { .mk = {0xe0, 0x35, 0 }, .brk = { 0xe0, 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = {0xe0, 0x37, 0 }, .brk = { 0xe0, 0xb7, 0 } }, /* 137 */ + { .mk = {0xe0, 0x38, 0 }, .brk = { 0xe0, 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = {0xe0, 0x3a, 0 }, .brk = { 0xe0, 0xba, 0 } }, /* 13a */ + { .mk = {0xe0, 0x3b, 0 }, .brk = { 0xe0, 0xbb, 0 } }, /* 13b */ + { .mk = {0xe0, 0x3c, 0 }, .brk = { 0xe0, 0xbc, 0 } }, /* 13c */ + { .mk = {0xe0, 0x3d, 0 }, .brk = { 0xe0, 0xbd, 0 } }, /* 13d */ + { .mk = {0xe0, 0x3e, 0 }, .brk = { 0xe0, 0xbe, 0 } }, /* 13e */ + { .mk = {0xe0, 0x3f, 0 }, .brk = { 0xe0, 0xbf, 0 } }, /* 13f */ + { .mk = {0xe0, 0x40, 0 }, .brk = { 0xe0, 0xc0, 0 } }, /* 140 */ + { .mk = {0xe0, 0x41, 0 }, .brk = { 0xe0, 0xc1, 0 } }, /* 141 */ + { .mk = {0xe0, 0x42, 0 }, .brk = { 0xe0, 0xc2, 0 } }, /* 142 */ + { .mk = {0xe0, 0x43, 0 }, .brk = { 0xe0, 0xc3, 0 } }, /* 143 */ + { .mk = {0xe0, 0x44, 0 }, .brk = { 0xe0, 0xc4, 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = {0xe0, 0x46, 0 }, .brk = { 0xe0, 0xc6, 0 } }, /* 146 */ + { .mk = {0xe0, 0x47, 0 }, .brk = { 0xe0, 0xc7, 0 } }, /* 147 */ + { .mk = {0xe0, 0x48, 0 }, .brk = { 0xe0, 0xc8, 0 } }, /* 148 */ + { .mk = {0xe0, 0x49, 0 }, .brk = { 0xe0, 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = {0xe0, 0x4b, 0 }, .brk = { 0xe0, 0xcb, 0 } }, /* 14b */ + { .mk = {0xe0, 0x4c, 0 }, .brk = { 0xe0, 0xcc, 0 } }, /* 14c */ + { .mk = {0xe0, 0x4d, 0 }, .brk = { 0xe0, 0xcd, 0 } }, /* 14d */ + { .mk = {0xe0, 0x4e, 0 }, .brk = { 0xe0, 0xce, 0 } }, /* 14e */ + { .mk = {0xe0, 0x4f, 0 }, .brk = { 0xe0, 0xcf, 0 } }, /* 14f */ + { .mk = {0xe0, 0x50, 0 }, .brk = { 0xe0, 0xd0, 0 } }, /* 150 */ + { .mk = {0xe0, 0x51, 0 }, .brk = { 0xe0, 0xd1, 0 } }, /* 151 */ + { .mk = {0xe0, 0x52, 0 }, .brk = { 0xe0, 0xd2, 0 } }, /* 152 */ + { .mk = {0xe0, 0x53, 0 }, .brk = { 0xe0, 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = {0xe0, 0x55, 0 }, .brk = { 0xe0, 0xd5, 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xd7, 0 } }, /* 157 */ + { .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xd8, 0 } }, /* 158 */ + { .mk = {0xe0, 0x59, 0 }, .brk = { 0xe0, 0xd9, 0 } }, /* 159 */ + { .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xaa, 0 } }, /* 15a */ + { .mk = {0xe0, 0x5b, 0 }, .brk = { 0xe0, 0xdb, 0 } }, /* 15b */ + { .mk = {0xe0, 0x5c, 0 }, .brk = { 0xe0, 0xdc, 0 } }, /* 15c */ + { .mk = {0xe0, 0x5d, 0 }, .brk = { 0xe0, 0xdd, 0 } }, /* 15d */ + { .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 15e */ + { .mk = {0xe0, 0x5f, 0 }, .brk = { 0xe0, 0xdf, 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = {0xe0, 0x61, 0 }, .brk = { 0xe0, 0xe1, 0 } }, /* 161 */ + { .mk = {0xe0, 0x62, 0 }, .brk = { 0xe0, 0xe2, 0 } }, /* 162 */ + { .mk = {0xe0, 0x63, 0 }, .brk = { 0xe0, 0xe3, 0 } }, /* 163 */ + { .mk = {0xe0, 0x64, 0 }, .brk = { 0xe0, 0xe4, 0 } }, /* 164 */ + { .mk = {0xe0, 0x65, 0 }, .brk = { 0xe0, 0xe5, 0 } }, /* 165 */ + { .mk = {0xe0, 0x66, 0 }, .brk = { 0xe0, 0xe6, 0 } }, /* 166 */ + { .mk = {0xe0, 0x67, 0 }, .brk = { 0xe0, 0xe7, 0 } }, /* 167 */ + { .mk = {0xe0, 0x68, 0 }, .brk = { 0xe0, 0xe8, 0 } }, /* 168 */ + { .mk = {0xe0, 0x69, 0 }, .brk = { 0xe0, 0xe9, 0 } }, /* 169 */ + { .mk = {0xe0, 0x6a, 0 }, .brk = { 0xe0, 0xea, 0 } }, /* 16a */ + { .mk = {0xe0, 0x6b, 0 }, .brk = { 0xe0, 0xeb, 0 } }, /* 16b */ + { .mk = {0xe0, 0x6c, 0 }, .brk = { 0xe0, 0xec, 0 } }, /* 16c */ + { .mk = {0xe0, 0x6d, 0 }, .brk = { 0xe0, 0xed, 0 } }, /* 16d */ + { .mk = {0xe0, 0x6e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = {0xe0, 0x70, 0 }, .brk = { 0xe0, 0xf0, 0 } }, /* 170 */ + { .mk = {0xe0, 0x71, 0 }, .brk = { 0xe0, 0xf1, 0 } }, /* 171 */ + { .mk = {0xe0, 0x72, 0 }, .brk = { 0xe0, 0xf2, 0 } }, /* 172 */ + { .mk = {0xe0, 0x73, 0 }, .brk = { 0xe0, 0xf3, 0 } }, /* 173 */ + { .mk = {0xe0, 0x74, 0 }, .brk = { 0xe0, 0xf4, 0 } }, /* 174 */ + { .mk = {0xe0, 0x75, 0 }, .brk = { 0xe0, 0xf5, 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = {0xe0, 0x77, 0 }, .brk = { 0xe0, 0xf7, 0 } }, /* 177 */ + { .mk = {0xe0, 0x78, 0 }, .brk = { 0xe0, 0xf8, 0 } }, /* 178 */ + { .mk = {0xe0, 0x79, 0 }, .brk = { 0xe0, 0xf9, 0 } }, /* 179 */ + { .mk = {0xe0, 0x7a, 0 }, .brk = { 0xe0, 0xfa, 0 } }, /* 17a */ + { .mk = {0xe0, 0x7b, 0 }, .brk = { 0xe0, 0xfb, 0 } }, /* 17b */ + { .mk = {0xe0, 0x7c, 0 }, .brk = { 0xe0, 0xfc, 0 } }, /* 17c */ + { .mk = {0xe0, 0x7d, 0 }, .brk = { 0xe0, 0xfd, 0 } }, /* 17d */ + { .mk = {0xe0, 0x7e, 0 }, .brk = { 0xe0, 0xfe, 0 } }, /* 17e */ + { .mk = {0xe0, 0x7f, 0 }, .brk = { 0xe0, 0xff, 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = {0xe0, 0xe1, 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = {0xe0, 0xee, 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = {0xe0, 0xf1, 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = {0xe0, 0xfe, 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = {0xe0, 0xff, 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 593b673e2..437ac7d54 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -138,518 +138,518 @@ static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No addit static const scancode scancode_tandy[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 013 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x56, 0 }, { 0xd6, 0 } }, /* 053 */ - { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, /* 055 */ - { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, /* 057 */ - { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, /* 059 */ - { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, /* 05b */ - { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, /* 05d */ - { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, /* 05f */ - { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, /* 061 */ - { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, /* 063 */ - { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, /* 065 */ - { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, /* 067 */ - { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, /* 069 */ - { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, /* 06b */ - { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, /* 06d */ - { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, /* 06f */ - { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, /* 071 */ - { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, /* 073 */ - { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, /* 075 */ - { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, /* 077 */ - { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, /* 079 */ - { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, /* 07b */ - { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, /* 07d */ - { { 0 }, { 0 } }, /* 07e */ - { { 0 }, { 0 } }, /* 07f */ - { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, /* 081 */ - { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, /* 085 */ - { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, /* 087 */ - { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, /* 089 */ - { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, /* 08b */ - { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, /* 08d */ - { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, /* 08f */ - { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, /* 091 */ - { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, /* 093 */ - { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, /* 095 */ - { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, /* 097 */ - { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, /* 099 */ - { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, /* 09b */ - { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, /* 09d */ - { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, /* 09f */ - { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, /* 0a1 */ - { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, /* 0a3 */ - { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, /* 0a5 */ - { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, /* 0a7 */ - { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, /* 0a9 */ - { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, /* 0ab */ - { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, /* 0ad */ - { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, /* 0af */ - { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, /* 0b1 */ - { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, /* 0b3 */ - { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, /* 0b5 */ - { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, /* 0b7 */ - { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, /* 0b9 */ - { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, /* 0bb */ - { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, /* 0bd */ - { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, /* 0bf */ - { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, /* 0c1 */ - { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, /* 0c3 */ - { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, /* 0c5 */ - { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, /* 0c7 */ - { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, /* 0c9 */ - { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, /* 0cb */ - { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, /* 0cd */ - { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, /* 0cf */ - { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, /* 0d1 */ - { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, /* 0d3 */ - { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, /* 0d5 */ - { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, /* 0d7 */ - { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, /* 0d9 */ - { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, /* 0db */ - { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, /* 0dd */ - { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, /* 0df */ - { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, /* 0e1 */ - { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, /* 0e3 */ - { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, /* 0e5 */ - { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, /* 0e7 */ - { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, /* 0e9 */ - { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, /* 0eb */ - { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, /* 0ed */ - { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, /* 0f1 */ - { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, /* 0f3 */ - { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, /* 0f5 */ - { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, /* 0f7 */ - { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, /* 0f9 */ - { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, /* 0fb */ - { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, /* 0fd */ - { { 0 }, { 0 } }, /* 0fe */ - { { 0 }, { 0 } }, /* 0ff */ - { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, /* 101 */ - { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, /* 103 */ - { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, /* 105 */ - { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, /* 107 */ - { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, /* 109 */ - { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, /* 10b */ - { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, /* 10f */ - { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, /* 111 */ - { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, /* 113 */ - { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, /* 115 */ - { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, /* 117 */ - { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, /* 119 */ - { { 0 }, { 0 } }, /* 11a */ - { { 0 }, { 0 } }, /* 11b */ - { { 0x57, 0 }, { 0xd7, 0 } }, /* 11c */ - { { 0 }, { 0 } }, /* 11d */ - { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, /* 11f */ - { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, /* 121 */ - { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, /* 123 */ - { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, /* 125 */ - { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, /* 12d */ - { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, /* 12f */ - { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, /* 131 */ - { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0 }, { 0 } }, /* 134 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, /* 13b */ - { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, /* 13d */ - { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, /* 13f */ - { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, /* 141 */ - { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, /* 143 */ - { { 0 }, { 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 148 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 14b */ - { { 0 }, { 0 } }, /* 14c */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 14d */ - { { 0 }, { 0 } }, /* 14e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 150 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, /* 157 */ - { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, /* 159 */ - { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, /* 15b */ - { { 0 }, { 0 } }, /* 15c */ - { { 0 }, { 0 } }, /* 15d */ - { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, /* 161 */ - { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, /* 163 */ - { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, /* 165 */ - { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, /* 167 */ - { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, /* 169 */ - { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, /* 16b */ - { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, /* 16d */ - { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, /* 171 */ - { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, /* 173 */ - { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, /* 177 */ - { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, /* 179 */ - { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, /* 17b */ - { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, /* 17d */ - { { 0 }, { 0 } }, /* 17e */ - { { 0 }, { 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0 }, { 0 } }, /* 1fe */ - { { 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 013 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 053 */ + { .mk = { 0 }, .brk = { 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0 }, .brk = { 0 } }, /* 056 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0 }, .brk = { 0 } }, /* 065 */ + { .mk = { 0 }, .brk = { 0 } }, /* 066 */ + { .mk = { 0 }, .brk = { 0 } }, /* 067 */ + { .mk = { 0 }, .brk = { 0 } }, /* 068 */ + { .mk = { 0 }, .brk = { 0 } }, /* 069 */ + { .mk = { 0 }, .brk = { 0 } }, /* 06a */ + { .mk = { 0 }, .brk = { 0 } }, /* 06b */ + { .mk = { 0 }, .brk = { 0 } }, /* 06c */ + { .mk = { 0 }, .brk = { 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0 }, .brk = { 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0 }, .brk = { 0 } }, /* 073 */ + { .mk = { 0 }, .brk = { 0 } }, /* 074 */ + { .mk = { 0 }, .brk = { 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0 }, .brk = { 0 } }, /* 077 */ + { .mk = { 0 }, .brk = { 0 } }, /* 078 */ + { .mk = { 0 }, .brk = { 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0 }, .brk = { 0 } }, /* 07b */ + { .mk = { 0 }, .brk = { 0 } }, /* 07c */ + { .mk = { 0 }, .brk = { 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x57, 0 }, .brk = { 0xd7, 0 } }, /* 11c */ + { .mk = { 0 }, .brk = { 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 148 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 150 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0 }, .brk = { 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; static uint8_t crtcmask[32] = { diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index b6bcbf3ca..172880361 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -846,518 +846,518 @@ ms_poll(void *priv) */ const scancode scancode_olivetti_m24_deluxe[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 013 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 022 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ - { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, /* 055 */ - { { 0x5e, 0 }, { 0xde, 0 } }, /* 056 */ - { { 0x60, 0 }, { 0xe0, 0 } }, /* 057 */ - { { 0x61, 0 }, { 0xe1, 0 } }, /* 058 */ - { { 0 }, { 0 } }, /* 059 */ - { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, /* 05b */ - { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, /* 05d */ - { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, /* 05f */ - { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, /* 061 */ - { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, /* 063 */ - { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, /* 065 */ - { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, /* 067 */ - { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, /* 069 */ - { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, /* 06b */ - { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, /* 06d */ - { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, /* 06f */ - { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, /* 071 */ - { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, /* 073 */ - { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, /* 075 */ - { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, /* 077 */ - { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, /* 079 */ - { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, /* 07b */ - { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, /* 07d */ - { { 0 }, { 0 } }, /* 07e */ - { { 0 }, { 0 } }, /* 07f */ - { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, /* 081 */ - { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, /* 085 */ - { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, /* 087 */ - { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, /* 089 */ - { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, /* 08b */ - { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, /* 08d */ - { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, /* 08f */ - { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, /* 091 */ - { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, /* 093 */ - { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, /* 095 */ - { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, /* 097 */ - { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, /* 099 */ - { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, /* 09b */ - { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, /* 09d */ - { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, /* 09f */ - { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, /* 0a1 */ - { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, /* 0a3 */ - { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, /* 0a5 */ - { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, /* 0a7 */ - { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, /* 0a9 */ - { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, /* 0ab */ - { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, /* 0ad */ - { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, /* 0af */ - { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, /* 0b1 */ - { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, /* 0b3 */ - { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, /* 0b5 */ - { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, /* 0b7 */ - { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, /* 0b9 */ - { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, /* 0bb */ - { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, /* 0bd */ - { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, /* 0bf */ - { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, /* 0c1 */ - { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, /* 0c3 */ - { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, /* 0c5 */ - { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, /* 0c7 */ - { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, /* 0c9 */ - { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, /* 0cb */ - { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, /* 0cd */ - { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, /* 0cf */ - { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, /* 0d1 */ - { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, /* 0d3 */ - { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, /* 0d5 */ - { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, /* 0d7 */ - { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, /* 0d9 */ - { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, /* 0db */ - { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, /* 0dd */ - { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, /* 0df */ - { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, /* 0e1 */ - { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, /* 0e3 */ - { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, /* 0e5 */ - { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, /* 0e7 */ - { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, /* 0e9 */ - { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, /* 0eb */ - { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, /* 0ed */ - { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, /* 0f1 */ - { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, /* 0f3 */ - { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, /* 0f5 */ - { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, /* 0f7 */ - { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, /* 0f9 */ - { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, /* 0fb */ - { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, /* 0fd */ - { { 0 }, { 0 } }, /* 0fe */ - { { 0 }, { 0 } }, /* 0ff */ - { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, /* 101 */ - { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, /* 103 */ - { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, /* 105 */ - { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, /* 107 */ - { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, /* 109 */ - { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, /* 10b */ - { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, /* 10f */ - { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, /* 111 */ - { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, /* 113 */ - { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, /* 115 */ - { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, /* 117 */ - { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, /* 119 */ - { { 0 }, { 0 } }, /* 11a */ - { { 0 }, { 0 } }, /* 11b */ - { { 0x57, 0 }, { 0xd7, 0 } }, /* 11c */ - { { 0 }, { 0 } }, /* 11d */ - { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, /* 11f */ - { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, /* 121 */ - { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, /* 123 */ - { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, /* 125 */ - { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, /* 12d */ - { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, /* 12f */ - { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, /* 131 */ - { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0 }, { 0 } }, /* 134 */ - { { 0x5f, 0 }, { 0xdf, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ - { { 0x66, 0 }, { 0xe6, 0 } }, /* 138 */ - { { 0x55, 0 }, { 0xd5, 0 } }, /* 139 */ - { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, /* 13b */ - { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, /* 13d */ - { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, /* 13f */ - { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, /* 141 */ - { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, /* 143 */ - { { 0 }, { 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ - { { 0x63, 0 }, { 0xe3, 0 } }, /* 147 */ - { { 0x5b, 0 }, { 0xdb, 0 } }, /* 148 */ - { { 0x5c, 0 }, { 0xdc, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0x58, 0 }, { 0xd8, 0 } }, /* 14b */ - { { 0 }, { 0 } }, /* 14c */ - { { 0x5a, 0 }, { 0xda, 0 } }, /* 14d */ - { { 0 }, { 0 } }, /* 14e */ - { { 0x65, 0 }, { 0xe5, 0 } }, /* 14f */ - { { 0x59, 0 }, { 0xd9, 0 } }, /* 150 */ - { { 0x5d, 0 }, { 0xdd, 0 } }, /* 151 */ - { { 0x62, 0 }, { 0xe2, 0 } }, /* 152 */ - { { 0x64, 0 }, { 0xe4, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, /* 157 */ - { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, /* 159 */ - { { 0 }, { 0 } }, /* 15a */ - { { 0x54, 0 }, { 0xd4, 0 } }, /* 15b */ - { { 0x67, 0 }, { 0xe7, 0 } }, /* 15c */ - { { 0x56, 0 }, { 0xd6, 0 } }, /* 15d */ - { { 0 }, { 0 } }, /* 15e */ - { { 0 }, { 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, /* 161 */ - { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, /* 163 */ - { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, /* 165 */ - { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, /* 167 */ - { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, /* 169 */ - { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, /* 16b */ - { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, /* 16d */ - { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, /* 171 */ - { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, /* 173 */ - { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, /* 177 */ - { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, /* 179 */ - { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, /* 17b */ - { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, /* 17d */ - { { 0 }, { 0 } }, /* 17e */ - { { 0 }, { 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0 }, { 0 } }, /* 1fe */ - { { 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 013 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0 }, .brk = { 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x5e, 0 }, .brk = { 0xde, 0 } }, /* 056 */ + { .mk = { 0x60, 0 }, .brk = { 0xe0, 0 } }, /* 057 */ + { .mk = { 0x61, 0 }, .brk = { 0xe1, 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0 }, .brk = { 0 } }, /* 065 */ + { .mk = { 0 }, .brk = { 0 } }, /* 066 */ + { .mk = { 0 }, .brk = { 0 } }, /* 067 */ + { .mk = { 0 }, .brk = { 0 } }, /* 068 */ + { .mk = { 0 }, .brk = { 0 } }, /* 069 */ + { .mk = { 0 }, .brk = { 0 } }, /* 06a */ + { .mk = { 0 }, .brk = { 0 } }, /* 06b */ + { .mk = { 0 }, .brk = { 0 } }, /* 06c */ + { .mk = { 0 }, .brk = { 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0 }, .brk = { 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0 }, .brk = { 0 } }, /* 073 */ + { .mk = { 0 }, .brk = { 0 } }, /* 074 */ + { .mk = { 0 }, .brk = { 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0 }, .brk = { 0 } }, /* 077 */ + { .mk = { 0 }, .brk = { 0 } }, /* 078 */ + { .mk = { 0 }, .brk = { 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0 }, .brk = { 0 } }, /* 07b */ + { .mk = { 0 }, .brk = { 0 } }, /* 07c */ + { .mk = { 0 }, .brk = { 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x57, 0 }, .brk = { 0xd7, 0 } }, /* 11c */ + { .mk = { 0 }, .brk = { 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x5f, 0 }, .brk = { 0xdf, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x66, 0 }, .brk = { 0xe6, 0 } }, /* 138 */ + { .mk = { 0x55, 0 }, .brk = { 0xd5, 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x63, 0 }, .brk = { 0xe3, 0 } }, /* 147 */ + { .mk = { 0x5b, 0 }, .brk = { 0xdb, 0 } }, /* 148 */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x58, 0 }, .brk = { 0xd8, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x5a, 0 }, .brk = { 0xda, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x65, 0 }, .brk = { 0xe5, 0 } }, /* 14f */ + { .mk = { 0x59, 0 }, .brk = { 0xd9, 0 } }, /* 150 */ + { .mk = { 0x5d, 0 }, .brk = { 0xdd, 0 } }, /* 151 */ + { .mk = { 0x62, 0 }, .brk = { 0xe2, 0 } }, /* 152 */ + { .mk = { 0x64, 0 }, .brk = { 0xe4, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 15b */ + { .mk = { 0x67, 0 }, .brk = { 0xe7, 0 } }, /* 15c */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; @@ -1369,518 +1369,518 @@ const scancode scancode_olivetti_m24_deluxe[512] = { */ const scancode scancode_olivetti_m240[512] = { // clang-format off - { { 0 }, { 0 } }, /* 000 */ - { { 0x01, 0 }, { 0x81, 0 } }, /* 001 */ - { { 0x02, 0 }, { 0x82, 0 } }, /* 002 */ - { { 0x03, 0 }, { 0x83, 0 } }, /* 003 */ - { { 0x04, 0 }, { 0x84, 0 } }, /* 004 */ - { { 0x05, 0 }, { 0x85, 0 } }, /* 005 */ - { { 0x06, 0 }, { 0x86, 0 } }, /* 006 */ - { { 0x07, 0 }, { 0x87, 0 } }, /* 007 */ - { { 0x08, 0 }, { 0x88, 0 } }, /* 008 */ - { { 0x09, 0 }, { 0x89, 0 } }, /* 009 */ - { { 0x0a, 0 }, { 0x8a, 0 } }, /* 00a */ - { { 0x0b, 0 }, { 0x8b, 0 } }, /* 00b */ - { { 0x0c, 0 }, { 0x8c, 0 } }, /* 00c */ - { { 0x0d, 0 }, { 0x8d, 0 } }, /* 00d */ - { { 0x0e, 0 }, { 0x8e, 0 } }, /* 00e */ - { { 0x0f, 0 }, { 0x8f, 0 } }, /* 00f */ - { { 0x10, 0 }, { 0x90, 0 } }, /* 010 */ - { { 0x11, 0 }, { 0x91, 0 } }, /* 011 */ - { { 0x12, 0 }, { 0x92, 0 } }, /* 012 */ - { { 0x13, 0 }, { 0x93, 0 } }, /* 013 */ - { { 0x14, 0 }, { 0x94, 0 } }, /* 014 */ - { { 0x15, 0 }, { 0x95, 0 } }, /* 015 */ - { { 0x16, 0 }, { 0x96, 0 } }, /* 016 */ - { { 0x17, 0 }, { 0x97, 0 } }, /* 017 */ - { { 0x18, 0 }, { 0x98, 0 } }, /* 018 */ - { { 0x19, 0 }, { 0x99, 0 } }, /* 019 */ - { { 0x1a, 0 }, { 0x9a, 0 } }, /* 01a */ - { { 0x1b, 0 }, { 0x9b, 0 } }, /* 01b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 01c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 01d */ - { { 0x1e, 0 }, { 0x9e, 0 } }, /* 01e */ - { { 0x1f, 0 }, { 0x9f, 0 } }, /* 01f */ - { { 0x20, 0 }, { 0xa0, 0 } }, /* 020 */ - { { 0x21, 0 }, { 0xa1, 0 } }, /* 021 */ - { { 0x22, 0 }, { 0xa2, 0 } }, /* 023 */ - { { 0x23, 0 }, { 0xa3, 0 } }, /* 023 */ - { { 0x24, 0 }, { 0xa4, 0 } }, /* 024 */ - { { 0x25, 0 }, { 0xa5, 0 } }, /* 025 */ - { { 0x26, 0 }, { 0xa6, 0 } }, /* 026 */ - { { 0x27, 0 }, { 0xa7, 0 } }, /* 027 */ - { { 0x28, 0 }, { 0xa8, 0 } }, /* 028 */ - { { 0x29, 0 }, { 0xa9, 0 } }, /* 029 */ - { { 0x2a, 0 }, { 0xaa, 0 } }, /* 02a */ - { { 0x2b, 0 }, { 0xab, 0 } }, /* 02b */ - { { 0x2c, 0 }, { 0xac, 0 } }, /* 02c */ - { { 0x2d, 0 }, { 0xad, 0 } }, /* 02d */ - { { 0x2e, 0 }, { 0xae, 0 } }, /* 02e */ - { { 0x2f, 0 }, { 0xaf, 0 } }, /* 02f */ - { { 0x30, 0 }, { 0xb0, 0 } }, /* 030 */ - { { 0x31, 0 }, { 0xb1, 0 } }, /* 031 */ - { { 0x32, 0 }, { 0xb2, 0 } }, /* 032 */ - { { 0x33, 0 }, { 0xb3, 0 } }, /* 033 */ - { { 0x34, 0 }, { 0xb4, 0 } }, /* 034 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 035 */ - { { 0x36, 0 }, { 0xb6, 0 } }, /* 036 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 037 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 038 */ - { { 0x39, 0 }, { 0xb9, 0 } }, /* 039 */ - { { 0x3a, 0 }, { 0xba, 0 } }, /* 03a */ - { { 0x3b, 0 }, { 0xbb, 0 } }, /* 03b */ - { { 0x3c, 0 }, { 0xbc, 0 } }, /* 03c */ - { { 0x3d, 0 }, { 0xbd, 0 } }, /* 03d */ - { { 0x3e, 0 }, { 0xbe, 0 } }, /* 03e */ - { { 0x3f, 0 }, { 0xbf, 0 } }, /* 03f */ - { { 0x40, 0 }, { 0xc0, 0 } }, /* 040 */ - { { 0x41, 0 }, { 0xc1, 0 } }, /* 041 */ - { { 0x42, 0 }, { 0xc2, 0 } }, /* 042 */ - { { 0x43, 0 }, { 0xc3, 0 } }, /* 043 */ - { { 0x44, 0 }, { 0xc4, 0 } }, /* 044 */ - { { 0x45, 0 }, { 0xc5, 0 } }, /* 045 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 046 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 047 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 048 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 049 */ - { { 0x4a, 0 }, { 0xca, 0 } }, /* 04a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 04b */ - { { 0x4c, 0 }, { 0xcc, 0 } }, /* 04c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 04d */ - { { 0x4e, 0 }, { 0xce, 0 } }, /* 04e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 04f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 050 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 051 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 052 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 053 */ - { { 0 }, { 0 } }, /* 054 */ - { { 0 }, { 0 } }, /* 055 */ - { { 0 }, { 0 } }, /* 056 */ - { { 0 }, { 0 } }, /* 057 */ - { { 0 }, { 0 } }, /* 058 */ - { { 0 }, { 0 } }, /* 059 */ - { { 0 }, { 0 } }, /* 05a */ - { { 0 }, { 0 } }, /* 05b */ - { { 0 }, { 0 } }, /* 05c */ - { { 0 }, { 0 } }, /* 05d */ - { { 0 }, { 0 } }, /* 05e */ - { { 0 }, { 0 } }, /* 05f */ - { { 0 }, { 0 } }, /* 060 */ - { { 0 }, { 0 } }, /* 061 */ - { { 0 }, { 0 } }, /* 062 */ - { { 0 }, { 0 } }, /* 063 */ - { { 0 }, { 0 } }, /* 064 */ - { { 0 }, { 0 } }, /* 065 */ - { { 0 }, { 0 } }, /* 066 */ - { { 0 }, { 0 } }, /* 067 */ - { { 0 }, { 0 } }, /* 068 */ - { { 0 }, { 0 } }, /* 069 */ - { { 0 }, { 0 } }, /* 06a */ - { { 0 }, { 0 } }, /* 06b */ - { { 0 }, { 0 } }, /* 06c */ - { { 0 }, { 0 } }, /* 06d */ - { { 0 }, { 0 } }, /* 06e */ - { { 0 }, { 0 } }, /* 06f */ - { { 0 }, { 0 } }, /* 070 */ - { { 0 }, { 0 } }, /* 071 */ - { { 0 }, { 0 } }, /* 072 */ - { { 0 }, { 0 } }, /* 073 */ - { { 0 }, { 0 } }, /* 074 */ - { { 0 }, { 0 } }, /* 075 */ - { { 0 }, { 0 } }, /* 076 */ - { { 0 }, { 0 } }, /* 077 */ - { { 0 }, { 0 } }, /* 078 */ - { { 0 }, { 0 } }, /* 079 */ - { { 0 }, { 0 } }, /* 07a */ - { { 0 }, { 0 } }, /* 07b */ - { { 0 }, { 0 } }, /* 07c */ - { { 0 }, { 0 } }, /* 07d */ - { { 0 }, { 0 } }, /* 07e */ - { { 0 }, { 0 } }, /* 07f */ - { { 0 }, { 0 } }, /* 080 */ - { { 0 }, { 0 } }, /* 081 */ - { { 0 }, { 0 } }, /* 082 */ - { { 0 }, { 0 } }, /* 083 */ - { { 0 }, { 0 } }, /* 084 */ - { { 0 }, { 0 } }, /* 085 */ - { { 0 }, { 0 } }, /* 086 */ - { { 0 }, { 0 } }, /* 087 */ - { { 0 }, { 0 } }, /* 088 */ - { { 0 }, { 0 } }, /* 089 */ - { { 0 }, { 0 } }, /* 08a */ - { { 0 }, { 0 } }, /* 08b */ - { { 0 }, { 0 } }, /* 08c */ - { { 0 }, { 0 } }, /* 08d */ - { { 0 }, { 0 } }, /* 08e */ - { { 0 }, { 0 } }, /* 08f */ - { { 0 }, { 0 } }, /* 090 */ - { { 0 }, { 0 } }, /* 091 */ - { { 0 }, { 0 } }, /* 092 */ - { { 0 }, { 0 } }, /* 093 */ - { { 0 }, { 0 } }, /* 094 */ - { { 0 }, { 0 } }, /* 095 */ - { { 0 }, { 0 } }, /* 096 */ - { { 0 }, { 0 } }, /* 097 */ - { { 0 }, { 0 } }, /* 098 */ - { { 0 }, { 0 } }, /* 099 */ - { { 0 }, { 0 } }, /* 09a */ - { { 0 }, { 0 } }, /* 09b */ - { { 0 }, { 0 } }, /* 09c */ - { { 0 }, { 0 } }, /* 09d */ - { { 0 }, { 0 } }, /* 09e */ - { { 0 }, { 0 } }, /* 09f */ - { { 0 }, { 0 } }, /* 0a0 */ - { { 0 }, { 0 } }, /* 0a1 */ - { { 0 }, { 0 } }, /* 0a2 */ - { { 0 }, { 0 } }, /* 0a3 */ - { { 0 }, { 0 } }, /* 0a4 */ - { { 0 }, { 0 } }, /* 0a5 */ - { { 0 }, { 0 } }, /* 0a6 */ - { { 0 }, { 0 } }, /* 0a7 */ - { { 0 }, { 0 } }, /* 0a8 */ - { { 0 }, { 0 } }, /* 0a9 */ - { { 0 }, { 0 } }, /* 0aa */ - { { 0 }, { 0 } }, /* 0ab */ - { { 0 }, { 0 } }, /* 0ac */ - { { 0 }, { 0 } }, /* 0ad */ - { { 0 }, { 0 } }, /* 0ae */ - { { 0 }, { 0 } }, /* 0af */ - { { 0 }, { 0 } }, /* 0b0 */ - { { 0 }, { 0 } }, /* 0b1 */ - { { 0 }, { 0 } }, /* 0b2 */ - { { 0 }, { 0 } }, /* 0b3 */ - { { 0 }, { 0 } }, /* 0b4 */ - { { 0 }, { 0 } }, /* 0b5 */ - { { 0 }, { 0 } }, /* 0b6 */ - { { 0 }, { 0 } }, /* 0b7 */ - { { 0 }, { 0 } }, /* 0b8 */ - { { 0 }, { 0 } }, /* 0b9 */ - { { 0 }, { 0 } }, /* 0ba */ - { { 0 }, { 0 } }, /* 0bb */ - { { 0 }, { 0 } }, /* 0bc */ - { { 0 }, { 0 } }, /* 0bd */ - { { 0 }, { 0 } }, /* 0be */ - { { 0 }, { 0 } }, /* 0bf */ - { { 0 }, { 0 } }, /* 0c0 */ - { { 0 }, { 0 } }, /* 0c1 */ - { { 0 }, { 0 } }, /* 0c2 */ - { { 0 }, { 0 } }, /* 0c3 */ - { { 0 }, { 0 } }, /* 0c4 */ - { { 0 }, { 0 } }, /* 0c5 */ - { { 0 }, { 0 } }, /* 0c6 */ - { { 0 }, { 0 } }, /* 0c7 */ - { { 0 }, { 0 } }, /* 0c8 */ - { { 0 }, { 0 } }, /* 0c9 */ - { { 0 }, { 0 } }, /* 0ca */ - { { 0 }, { 0 } }, /* 0cb */ - { { 0 }, { 0 } }, /* 0cc */ - { { 0 }, { 0 } }, /* 0cd */ - { { 0 }, { 0 } }, /* 0ce */ - { { 0 }, { 0 } }, /* 0cf */ - { { 0 }, { 0 } }, /* 0d0 */ - { { 0 }, { 0 } }, /* 0d1 */ - { { 0 }, { 0 } }, /* 0d2 */ - { { 0 }, { 0 } }, /* 0d3 */ - { { 0 }, { 0 } }, /* 0d4 */ - { { 0 }, { 0 } }, /* 0d5 */ - { { 0 }, { 0 } }, /* 0d6 */ - { { 0 }, { 0 } }, /* 0d7 */ - { { 0 }, { 0 } }, /* 0d8 */ - { { 0 }, { 0 } }, /* 0d9 */ - { { 0 }, { 0 } }, /* 0da */ - { { 0 }, { 0 } }, /* 0db */ - { { 0 }, { 0 } }, /* 0dc */ - { { 0 }, { 0 } }, /* 0dd */ - { { 0 }, { 0 } }, /* 0de */ - { { 0 }, { 0 } }, /* 0df */ - { { 0 }, { 0 } }, /* 0e0 */ - { { 0 }, { 0 } }, /* 0e1 */ - { { 0 }, { 0 } }, /* 0e2 */ - { { 0 }, { 0 } }, /* 0e3 */ - { { 0 }, { 0 } }, /* 0e4 */ - { { 0 }, { 0 } }, /* 0e5 */ - { { 0 }, { 0 } }, /* 0e6 */ - { { 0 }, { 0 } }, /* 0e7 */ - { { 0 }, { 0 } }, /* 0e8 */ - { { 0 }, { 0 } }, /* 0e9 */ - { { 0 }, { 0 } }, /* 0ea */ - { { 0 }, { 0 } }, /* 0eb */ - { { 0 }, { 0 } }, /* 0ec */ - { { 0 }, { 0 } }, /* 0ed */ - { { 0 }, { 0 } }, /* 0ee */ - { { 0 }, { 0 } }, /* 0ef */ - { { 0 }, { 0 } }, /* 0f0 */ - { { 0 }, { 0 } }, /* 0f1 */ - { { 0 }, { 0 } }, /* 0f2 */ - { { 0 }, { 0 } }, /* 0f3 */ - { { 0 }, { 0 } }, /* 0f4 */ - { { 0 }, { 0 } }, /* 0f5 */ - { { 0 }, { 0 } }, /* 0f6 */ - { { 0 }, { 0 } }, /* 0f7 */ - { { 0 }, { 0 } }, /* 0f8 */ - { { 0 }, { 0 } }, /* 0f9 */ - { { 0 }, { 0 } }, /* 0fa */ - { { 0 }, { 0 } }, /* 0fb */ - { { 0 }, { 0 } }, /* 0fc */ - { { 0 }, { 0 } }, /* 0fd */ - { { 0 }, { 0 } }, /* 0fe */ - { { 0 }, { 0 } }, /* 0ff */ - { { 0 }, { 0 } }, /* 100 */ - { { 0 }, { 0 } }, /* 101 */ - { { 0 }, { 0 } }, /* 102 */ - { { 0 }, { 0 } }, /* 103 */ - { { 0 }, { 0 } }, /* 104 */ - { { 0 }, { 0 } }, /* 105 */ - { { 0 }, { 0 } }, /* 106 */ - { { 0 }, { 0 } }, /* 107 */ - { { 0 }, { 0 } }, /* 108 */ - { { 0 }, { 0 } }, /* 109 */ - { { 0 }, { 0 } }, /* 10a */ - { { 0 }, { 0 } }, /* 10b */ - { { 0 }, { 0 } }, /* 10c */ - { { 0 }, { 0 } }, /* 10d */ - { { 0 }, { 0 } }, /* 10e */ - { { 0 }, { 0 } }, /* 10f */ - { { 0 }, { 0 } }, /* 110 */ - { { 0 }, { 0 } }, /* 111 */ - { { 0 }, { 0 } }, /* 112 */ - { { 0 }, { 0 } }, /* 113 */ - { { 0 }, { 0 } }, /* 114 */ - { { 0 }, { 0 } }, /* 115 */ - { { 0 }, { 0 } }, /* 116 */ - { { 0 }, { 0 } }, /* 117 */ - { { 0 }, { 0 } }, /* 118 */ - { { 0 }, { 0 } }, /* 119 */ - { { 0 }, { 0 } }, /* 11a */ - { { 0 }, { 0 } }, /* 11b */ - { { 0x1c, 0 }, { 0x9c, 0 } }, /* 11c */ - { { 0x1d, 0 }, { 0x9d, 0 } }, /* 11d */ - { { 0 }, { 0 } }, /* 11e */ - { { 0 }, { 0 } }, /* 11f */ - { { 0 }, { 0 } }, /* 120 */ - { { 0 }, { 0 } }, /* 121 */ - { { 0 }, { 0 } }, /* 122 */ - { { 0 }, { 0 } }, /* 123 */ - { { 0 }, { 0 } }, /* 124 */ - { { 0 }, { 0 } }, /* 125 */ - { { 0 }, { 0 } }, /* 126 */ - { { 0 }, { 0 } }, /* 127 */ - { { 0 }, { 0 } }, /* 128 */ - { { 0 }, { 0 } }, /* 129 */ - { { 0 }, { 0 } }, /* 12a */ - { { 0 }, { 0 } }, /* 12b */ - { { 0 }, { 0 } }, /* 12c */ - { { 0 }, { 0 } }, /* 12d */ - { { 0 }, { 0 } }, /* 12e */ - { { 0 }, { 0 } }, /* 12f */ - { { 0 }, { 0 } }, /* 130 */ - { { 0 }, { 0 } }, /* 131 */ - { { 0 }, { 0 } }, /* 132 */ - { { 0 }, { 0 } }, /* 133 */ - { { 0 }, { 0 } }, /* 134 */ - { { 0x35, 0 }, { 0xb5, 0 } }, /* 135 */ - { { 0 }, { 0 } }, /* 136 */ - { { 0x37, 0 }, { 0xb7, 0 } }, /* 137 */ - { { 0x38, 0 }, { 0xb8, 0 } }, /* 138 */ - { { 0 }, { 0 } }, /* 139 */ - { { 0 }, { 0 } }, /* 13a */ - { { 0 }, { 0 } }, /* 13b */ - { { 0 }, { 0 } }, /* 13c */ - { { 0 }, { 0 } }, /* 13d */ - { { 0 }, { 0 } }, /* 13e */ - { { 0 }, { 0 } }, /* 13f */ - { { 0 }, { 0 } }, /* 140 */ - { { 0 }, { 0 } }, /* 141 */ - { { 0 }, { 0 } }, /* 142 */ - { { 0 }, { 0 } }, /* 143 */ - { { 0 }, { 0 } }, /* 144 */ - { { 0 }, { 0 } }, /* 145 */ - { { 0x46, 0 }, { 0xc6, 0 } }, /* 146 */ - { { 0x47, 0 }, { 0xc7, 0 } }, /* 147 */ - { { 0x48, 0 }, { 0xc8, 0 } }, /* 148 */ - { { 0x49, 0 }, { 0xc9, 0 } }, /* 149 */ - { { 0 }, { 0 } }, /* 14a */ - { { 0x4b, 0 }, { 0xcb, 0 } }, /* 14b */ - { { 0 }, { 0 } }, /* 14c */ - { { 0x4d, 0 }, { 0xcd, 0 } }, /* 14d */ - { { 0 }, { 0 } }, /* 14e */ - { { 0x4f, 0 }, { 0xcf, 0 } }, /* 14f */ - { { 0x50, 0 }, { 0xd0, 0 } }, /* 150 */ - { { 0x51, 0 }, { 0xd1, 0 } }, /* 151 */ - { { 0x52, 0 }, { 0xd2, 0 } }, /* 152 */ - { { 0x53, 0 }, { 0xd3, 0 } }, /* 153 */ - { { 0 }, { 0 } }, /* 154 */ - { { 0 }, { 0 } }, /* 155 */ - { { 0 }, { 0 } }, /* 156 */ - { { 0 }, { 0 } }, /* 157 */ - { { 0 }, { 0 } }, /* 158 */ - { { 0 }, { 0 } }, /* 159 */ - { { 0 }, { 0 } }, /* 15a */ - { { 0 }, { 0 } }, /* 15b */ - { { 0 }, { 0 } }, /* 15c */ - { { 0x54, 0 }, { 0xd4, 0 } }, /* 15d */ - { { 0x56, 0 }, { 0xd6, 0 } }, /* 15e */ - { { 0x5c, 0 }, { 0xdc, 0 } }, /* 15f */ - { { 0 }, { 0 } }, /* 160 */ - { { 0 }, { 0 } }, /* 161 */ - { { 0 }, { 0 } }, /* 162 */ - { { 0 }, { 0 } }, /* 163 */ - { { 0 }, { 0 } }, /* 164 */ - { { 0 }, { 0 } }, /* 165 */ - { { 0 }, { 0 } }, /* 166 */ - { { 0 }, { 0 } }, /* 167 */ - { { 0 }, { 0 } }, /* 168 */ - { { 0 }, { 0 } }, /* 169 */ - { { 0 }, { 0 } }, /* 16a */ - { { 0 }, { 0 } }, /* 16b */ - { { 0 }, { 0 } }, /* 16c */ - { { 0 }, { 0 } }, /* 16d */ - { { 0 }, { 0 } }, /* 16e */ - { { 0 }, { 0 } }, /* 16f */ - { { 0 }, { 0 } }, /* 170 */ - { { 0 }, { 0 } }, /* 171 */ - { { 0 }, { 0 } }, /* 172 */ - { { 0 }, { 0 } }, /* 173 */ - { { 0 }, { 0 } }, /* 174 */ - { { 0 }, { 0 } }, /* 175 */ - { { 0 }, { 0 } }, /* 176 */ - { { 0 }, { 0 } }, /* 177 */ - { { 0 }, { 0 } }, /* 178 */ - { { 0 }, { 0 } }, /* 179 */ - { { 0 }, { 0 } }, /* 17a */ - { { 0 }, { 0 } }, /* 17b */ - { { 0 }, { 0 } }, /* 17c */ - { { 0 }, { 0 } }, /* 17d */ - { { 0 }, { 0 } }, /* 17e */ - { { 0 }, { 0 } }, /* 17f */ - { { 0 }, { 0 } }, /* 180 */ - { { 0 }, { 0 } }, /* 181 */ - { { 0 }, { 0 } }, /* 182 */ - { { 0 }, { 0 } }, /* 183 */ - { { 0 }, { 0 } }, /* 184 */ - { { 0 }, { 0 } }, /* 185 */ - { { 0 }, { 0 } }, /* 186 */ - { { 0 }, { 0 } }, /* 187 */ - { { 0 }, { 0 } }, /* 188 */ - { { 0 }, { 0 } }, /* 189 */ - { { 0 }, { 0 } }, /* 18a */ - { { 0 }, { 0 } }, /* 18b */ - { { 0 }, { 0 } }, /* 18c */ - { { 0 }, { 0 } }, /* 18d */ - { { 0 }, { 0 } }, /* 18e */ - { { 0 }, { 0 } }, /* 18f */ - { { 0 }, { 0 } }, /* 190 */ - { { 0 }, { 0 } }, /* 191 */ - { { 0 }, { 0 } }, /* 192 */ - { { 0 }, { 0 } }, /* 193 */ - { { 0 }, { 0 } }, /* 194 */ - { { 0 }, { 0 } }, /* 195 */ - { { 0 }, { 0 } }, /* 196 */ - { { 0 }, { 0 } }, /* 197 */ - { { 0 }, { 0 } }, /* 198 */ - { { 0 }, { 0 } }, /* 199 */ - { { 0 }, { 0 } }, /* 19a */ - { { 0 }, { 0 } }, /* 19b */ - { { 0 }, { 0 } }, /* 19c */ - { { 0 }, { 0 } }, /* 19d */ - { { 0 }, { 0 } }, /* 19e */ - { { 0 }, { 0 } }, /* 19f */ - { { 0 }, { 0 } }, /* 1a0 */ - { { 0 }, { 0 } }, /* 1a1 */ - { { 0 }, { 0 } }, /* 1a2 */ - { { 0 }, { 0 } }, /* 1a3 */ - { { 0 }, { 0 } }, /* 1a4 */ - { { 0 }, { 0 } }, /* 1a5 */ - { { 0 }, { 0 } }, /* 1a6 */ - { { 0 }, { 0 } }, /* 1a7 */ - { { 0 }, { 0 } }, /* 1a8 */ - { { 0 }, { 0 } }, /* 1a9 */ - { { 0 }, { 0 } }, /* 1aa */ - { { 0 }, { 0 } }, /* 1ab */ - { { 0 }, { 0 } }, /* 1ac */ - { { 0 }, { 0 } }, /* 1ad */ - { { 0 }, { 0 } }, /* 1ae */ - { { 0 }, { 0 } }, /* 1af */ - { { 0 }, { 0 } }, /* 1b0 */ - { { 0 }, { 0 } }, /* 1b1 */ - { { 0 }, { 0 } }, /* 1b2 */ - { { 0 }, { 0 } }, /* 1b3 */ - { { 0 }, { 0 } }, /* 1b4 */ - { { 0 }, { 0 } }, /* 1b5 */ - { { 0 }, { 0 } }, /* 1b6 */ - { { 0 }, { 0 } }, /* 1b7 */ - { { 0 }, { 0 } }, /* 1b8 */ - { { 0 }, { 0 } }, /* 1b9 */ - { { 0 }, { 0 } }, /* 1ba */ - { { 0 }, { 0 } }, /* 1bb */ - { { 0 }, { 0 } }, /* 1bc */ - { { 0 }, { 0 } }, /* 1bd */ - { { 0 }, { 0 } }, /* 1be */ - { { 0 }, { 0 } }, /* 1bf */ - { { 0 }, { 0 } }, /* 1c0 */ - { { 0 }, { 0 } }, /* 1c1 */ - { { 0 }, { 0 } }, /* 1c2 */ - { { 0 }, { 0 } }, /* 1c3 */ - { { 0 }, { 0 } }, /* 1c4 */ - { { 0 }, { 0 } }, /* 1c5 */ - { { 0 }, { 0 } }, /* 1c6 */ - { { 0 }, { 0 } }, /* 1c7 */ - { { 0 }, { 0 } }, /* 1c8 */ - { { 0 }, { 0 } }, /* 1c9 */ - { { 0 }, { 0 } }, /* 1ca */ - { { 0 }, { 0 } }, /* 1cb */ - { { 0 }, { 0 } }, /* 1cc */ - { { 0 }, { 0 } }, /* 1cd */ - { { 0 }, { 0 } }, /* 1ce */ - { { 0 }, { 0 } }, /* 1cf */ - { { 0 }, { 0 } }, /* 1d0 */ - { { 0 }, { 0 } }, /* 1d1 */ - { { 0 }, { 0 } }, /* 1d2 */ - { { 0 }, { 0 } }, /* 1d3 */ - { { 0 }, { 0 } }, /* 1d4 */ - { { 0 }, { 0 } }, /* 1d5 */ - { { 0 }, { 0 } }, /* 1d6 */ - { { 0 }, { 0 } }, /* 1d7 */ - { { 0 }, { 0 } }, /* 1d8 */ - { { 0 }, { 0 } }, /* 1d9 */ - { { 0 }, { 0 } }, /* 1da */ - { { 0 }, { 0 } }, /* 1db */ - { { 0 }, { 0 } }, /* 1dc */ - { { 0 }, { 0 } }, /* 1dd */ - { { 0 }, { 0 } }, /* 1de */ - { { 0 }, { 0 } }, /* 1df */ - { { 0 }, { 0 } }, /* 1e0 */ - { { 0 }, { 0 } }, /* 1e1 */ - { { 0 }, { 0 } }, /* 1e2 */ - { { 0 }, { 0 } }, /* 1e3 */ - { { 0 }, { 0 } }, /* 1e4 */ - { { 0 }, { 0 } }, /* 1e5 */ - { { 0 }, { 0 } }, /* 1e6 */ - { { 0 }, { 0 } }, /* 1e7 */ - { { 0 }, { 0 } }, /* 1e8 */ - { { 0 }, { 0 } }, /* 1e9 */ - { { 0 }, { 0 } }, /* 1ea */ - { { 0 }, { 0 } }, /* 1eb */ - { { 0 }, { 0 } }, /* 1ec */ - { { 0 }, { 0 } }, /* 1ed */ - { { 0 }, { 0 } }, /* 1ee */ - { { 0 }, { 0 } }, /* 1ef */ - { { 0 }, { 0 } }, /* 1f0 */ - { { 0 }, { 0 } }, /* 1f1 */ - { { 0 }, { 0 } }, /* 1f2 */ - { { 0 }, { 0 } }, /* 1f3 */ - { { 0 }, { 0 } }, /* 1f4 */ - { { 0 }, { 0 } }, /* 1f5 */ - { { 0 }, { 0 } }, /* 1f6 */ - { { 0 }, { 0 } }, /* 1f7 */ - { { 0 }, { 0 } }, /* 1f8 */ - { { 0 }, { 0 } }, /* 1f9 */ - { { 0 }, { 0 } }, /* 1fa */ - { { 0 }, { 0 } }, /* 1fb */ - { { 0 }, { 0 } }, /* 1fc */ - { { 0 }, { 0 } }, /* 1fd */ - { { 0 }, { 0 } }, /* 1fe */ - { { 0 }, { 0 } } /* 1ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 023 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0 }, .brk = { 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0 }, .brk = { 0 } }, /* 056 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0 }, .brk = { 0 } }, /* 065 */ + { .mk = { 0 }, .brk = { 0 } }, /* 066 */ + { .mk = { 0 }, .brk = { 0 } }, /* 067 */ + { .mk = { 0 }, .brk = { 0 } }, /* 068 */ + { .mk = { 0 }, .brk = { 0 } }, /* 069 */ + { .mk = { 0 }, .brk = { 0 } }, /* 06a */ + { .mk = { 0 }, .brk = { 0 } }, /* 06b */ + { .mk = { 0 }, .brk = { 0 } }, /* 06c */ + { .mk = { 0 }, .brk = { 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0 }, .brk = { 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0 }, .brk = { 0 } }, /* 073 */ + { .mk = { 0 }, .brk = { 0 } }, /* 074 */ + { .mk = { 0 }, .brk = { 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0 }, .brk = { 0 } }, /* 077 */ + { .mk = { 0 }, .brk = { 0 } }, /* 078 */ + { .mk = { 0 }, .brk = { 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0 }, .brk = { 0 } }, /* 07b */ + { .mk = { 0 }, .brk = { 0 } }, /* 07c */ + { .mk = { 0 }, .brk = { 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 11c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 148 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 150 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0 }, .brk = { 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 15d */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 15e */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; From d82d8cefedb729b7193ab1687bc8960fb7310097 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:16:12 -0400 Subject: [PATCH 666/690] qt: Fix strings in enumeration of host drives --- src/qt/qt_mediamenu.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index a1d8a528c..5f1289740 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -157,10 +157,10 @@ MediaMenu::refresh(QMenu *parentMenu) #ifdef Q_OS_WINDOWS /* Loop through each Windows drive letter and test to see if it's a CDROM */ - for (auto &letter : driveLetters) { - auto drive = QString::asprintf("%c:\\", letter).toUtf8().constData(); - if (GetDriveType(drive) == DRIVE_CDROM) - menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DriveCDIcon), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter]() { cdromMount(i, 2, QString::asprintf(R"(\\.\%c:)", letter).toUtf8().constData()); })->setCheckable(false); + for (const auto &letter : driveLetters) { + auto drive = QString("%1:\\").arg(letter); + if (GetDriveType(drive.toUtf8().constData()) == DRIVE_CDROM) + menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DriveCDIcon), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter] { cdromMount(i, 2, QString(R"(\\.\%1:)").arg(letter)); })->setCheckable(false); } menu->addSeparator(); #endif // Q_OS_WINDOWS From a43693bbec3424915a1c5ce64e0fcb007c746c81 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:19:53 -0400 Subject: [PATCH 667/690] Add a library required for building on windows arm --- src/sound/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index f67630c47..764e08a8e 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -90,6 +90,9 @@ if(FLUIDSYNTH) target_link_libraries(86Box PkgConfig::FLUIDSYNTH) if(STATIC_BUILD) target_link_libraries(86Box -static ${FLUIDSYNTH_STATIC_LIBRARIES} -fopenmp) + if(WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + target_link_libraries(86Box psapi) + endif() endif() target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) From 421cbcb1656c8260130f8f534ea85c70debdc838 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:43:19 -0400 Subject: [PATCH 668/690] qt: UUID updates * Ensure relative paths are properly resolved * Do not display a mismatch prompt unless the system has configured NICs --- src/qt/qt_util.cpp | 29 +++++++++++++++++++++++++---- src/qt/qt_util.hpp | 1 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index 0a59cdf5d..5c9059272 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -14,6 +14,8 @@ * * Copyright 2022 Teemu Korhonen */ +#include +#include #include #include #include @@ -70,7 +72,11 @@ DlgFilter(std::initializer_list extensions, bool last) QString currentUuid() { - return QUuid::createUuidV5(QUuid{}, QString(usr_path)).toString(QUuid::WithoutBraces); + auto configPath = QFileInfo(cfg_path).dir().canonicalPath(); + if(!configPath.endsWith("/")) { + configPath.append("/"); + } + return QUuid::createUuidV5(QUuid{}, configPath).toString(QUuid::WithoutBraces); } bool compareUuid() @@ -82,6 +88,11 @@ bool compareUuid() storeCurrentUuid(); return true; } + // Do not prompt on mismatch if the system does not have any configured NICs. Just update the uuid + if(!hasConfiguredNICs() && uuid != currentUuid()) { + storeCurrentUuid(); + return true; + } // The uuid appears to be a valid, at least by length. // Compare with a simple string match return uuid == currentUuid(); @@ -99,14 +110,24 @@ generateNewMacAdresses() for (int i = 0; i < NET_CARD_MAX; ++i) { auto net_card = net_cards_conf[i]; if (net_card.device_num != 0) { - const auto network_device = network_card_getdevice(net_card.device_num); + const auto network_device = network_card_getdevice(net_card.device_num); device_context_t device_context; - - device_set_context(&device_context, network_device, i+1); + device_set_context(&device_context, network_device, i + 1); auto generatedMac = QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate()).toLower(); config_set_string(device_context.name, "mac", generatedMac.toUtf8().constData()); } } } +bool +hasConfiguredNICs() +{ + for (int i = 0; i < NET_CARD_MAX; ++i) { + if (const auto net_card = net_cards_conf[i]; net_card.device_num != 0) { + return true; + } + } + return false; +} + } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 07e44b621..6a0bdc30b 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -17,6 +17,7 @@ QString currentUuid(); void storeCurrentUuid(); bool compareUuid(); void generateNewMacAdresses(); +bool hasConfiguredNICs(); }; #endif From 2373771f4d53382c33c3a1890b8d143579a74bd3 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 28 Jun 2024 23:30:56 -0400 Subject: [PATCH 669/690] Support additional serial ports ala the MP5587-1/2 --- src/86box.c | 4 ++-- src/device/serial.c | 8 +++++++- src/include/86box/86box.h | 2 +- src/include/86box/serial.h | 12 ++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index 60423b2a1..16d7cf3de 100644 --- a/src/86box.c +++ b/src/86box.c @@ -171,8 +171,8 @@ int video_filter_method = 1; /* (C) video * int video_vsync = 0; /* (C) video */ int video_framerate = -1; /* (C) video */ char video_shader[512] = { '\0' }; /* (C) video */ -bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of - pass-through for serial ports */ +bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; /* (C) activation and kind of + pass-through for serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */ int postcard_enabled = 0; /* (C) enable POST card */ diff --git a/src/device/serial.c b/src/device/serial.c index 2a61347a1..ecc08f15d 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -912,7 +912,13 @@ 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; - if (next_inst == 3) + if (next_inst == 6) + serial_setup(dev, COM7_ADDR, COM7_IRQ); + else if (next_inst == 5) + serial_setup(dev, COM6_ADDR, COM6_IRQ); + else if (next_inst == 4) + serial_setup(dev, COM5_ADDR, COM5_IRQ); + else if (next_inst == 3) serial_setup(dev, COM4_ADDR, COM4_IRQ); else if (next_inst == 2) serial_setup(dev, COM3_ADDR, COM3_IRQ); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index f76d70797..0d57b4cae 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -21,7 +21,7 @@ #define EMU_86BOX_H /* Configuration values. */ -#define SERIAL_MAX 4 +#define SERIAL_MAX 7 #define PARALLEL_MAX 4 #define SCREEN_RES_X 640 #define SCREEN_RES_Y 480 diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index c2312f562..a205c7cec 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -43,6 +43,18 @@ #define COM3_IRQ 4 #define COM4_ADDR 0x02e8 #define COM4_IRQ 3 +// The following support being assingned IRQ 3, 4, 5, 9, 10, 11, 12 or 15 +// There doesn't appear to be any specific standard however +// So defaults have been chosen arbitarily +// TODO: Allow configuration of the IRQ in the UI +//#define COM5_ADDR 0x03f0 +//#define COM5_IRQ 3 +#define COM5_ADDR 0x02f0 +#define COM5_IRQ 11 +#define COM6_ADDR 0x03e0 +#define COM6_IRQ 10 +#define COM7_ADDR 0x02e0 +#define COM7_IRQ 9 struct serial_device_s; struct serial_s; From 571bab3efd566c19ae8e16a9a5fc4e543f712f75 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 2 Dec 2023 21:52:24 -0500 Subject: [PATCH 670/690] Named-initializers for 80386SX CPU's --- src/cpu/cpu_table.c | 222 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 207 insertions(+), 15 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 502b2c86e..1c67c4880 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1009,12 +1009,92 @@ const cpu_family_t cpu_families[] = { .name = "i386SX", .internal_name = "i386sx", .cpus = (const CPU[]) { - {"16", CPU_386SX, fpus_80386, 16000000, 1, 5000, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_386SX, fpus_80386, 20000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"25", CPU_386SX, fpus_80386, 25000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"33", CPU_386SX, fpus_80386, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386SX, fpus_80386, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", 0} + { + .name = "16", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386SX, @@ -1022,12 +1102,92 @@ const cpu_family_t cpu_families[] = { .name = "Am386SX", .internal_name = "am386sx", .cpus = (const CPU[]) { - {"16", CPU_386SX, fpus_80386, 16000000, 1, 5000, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_386SX, fpus_80386, 20000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"25", CPU_386SX, fpus_80386, 25000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"33", CPU_386SX, fpus_80386, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386SX, fpus_80386, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", 0} + { + .name = "16", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_386SX, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386DX, @@ -1081,9 +1241,41 @@ const cpu_family_t cpu_families[] = { .name = "M6117", .internal_name = "m6117", .cpus = (const CPU[]) { /* All timings and edx_reset values assumed. */ - {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2309, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2309, 0, 0, 0, 7,7,3,3, 5}, - {"", 0} + { + .name = "33", + .cpu_type = CPU_386SX, + .fpus = fpus_none, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2309, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_386SX, + .fpus = fpus_none, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x2309, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386SLC_IBM, From 13dac1020f3e72061d1dafd7bb2b6c79e24addd7 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 7 Dec 2023 21:54:55 -0500 Subject: [PATCH 671/690] Named-initializers for 80386DX CPU's --- src/cpu/cpu_table.c | 390 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 363 insertions(+), 27 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 1c67c4880..b9e81aa72 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1195,12 +1195,92 @@ const cpu_family_t cpu_families[] = { .name = "i386DX", .internal_name = "i386dx", .cpus = (const CPU[]) { - {"16", CPU_386DX, fpus_80386, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"33", CPU_386DX, fpus_80386, 33333333, 1, 5000, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386DX, fpus_80386, 40000000, 1, 5000, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"", 0} + { + .name = "16", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386DX_DESKPRO386, @@ -1208,10 +1288,58 @@ const cpu_family_t cpu_families[] = { .name = "i386DX", .internal_name = "i386dx_deskpro386", .cpus = (const CPU[]) { - {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"", 0} + { + .name = "16", + .cpu_type = CPU_386DX, + .fpus = fpus_80286, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386DX, @@ -1219,10 +1347,58 @@ const cpu_family_t cpu_families[] = { .name = "RapidCAD", .internal_name = "rapidcad", .cpus = (const CPU[]) { - {"25", CPU_RAPIDCAD, fpus_internal, 25000000, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"33", CPU_RAPIDCAD, fpus_internal, 33333333, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"40", CPU_RAPIDCAD, fpus_internal, 40000000, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"", 0} + { + .name = "25", + .cpu_type = CPU_RAPIDCAD, + .fpus = fpus_internal, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0340, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_SUPPORTS_DYNAREC, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_RAPIDCAD, + .fpus = fpus_internal, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0340, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_SUPPORTS_DYNAREC, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_RAPIDCAD, + .fpus = fpus_internal, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0340, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_SUPPORTS_DYNAREC, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386DX, @@ -1230,10 +1406,58 @@ const cpu_family_t cpu_families[] = { .name = "Am386DX", .internal_name = "am386dx", .cpus = (const CPU[]) { - {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"33", CPU_386DX, fpus_80386, 33333333, 1, 5000, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386DX, fpus_80386, 40000000, 1, 5000, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"", 0} + { + .name = "25", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_386DX, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x0308, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_M6117, @@ -1367,10 +1591,58 @@ const cpu_family_t cpu_families[] = { .name = "Cx486DLC", .internal_name = "cx486dlc", .cpus = (const CPU[]) { - {"25", CPU_486DLC, fpus_80386, 25000000, 1, 5000, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, - {"33", CPU_486DLC, fpus_80386, 33333333, 1, 5000, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4}, - {"40", CPU_486DLC, fpus_80386, 40000000, 1, 5000, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5}, - {"", 0} + { + .name = "25", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x401, + .cpuid_model = 0, + .cyrix_id = 0x0001, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 3 + }, + { + .name = "33", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 33333333, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x401, + .cpuid_model = 0, + .cyrix_id = 0x0001, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0x401, + .cpuid_model = 0, + .cyrix_id = 0x0001, + .cpu_flags = 0, + .mem_read_cycles = 7, + .mem_write_cycles = 7, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 5 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386DX, @@ -1378,11 +1650,75 @@ const cpu_family_t cpu_families[] = { .name = "Cx486DRx2", .internal_name = "cx486drx2", .cpus = (const CPU[]) { - {"32", CPU_486DLC, fpus_80386, 32000000, 2, 5000, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4}, - {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"50", CPU_486DLC, fpus_80386, 50000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"66", CPU_486DLC, fpus_80386, 66666666, 2, 5000, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, - {"", 0} + { + .name = "32", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 32000000, + .multi = 2, + .voltage = 5000, + .edx_reset = 0x407, + .cpuid_model = 0, + .cyrix_id = 0x0007, + .cpu_flags = 0, + .mem_read_cycles = 6, + .mem_write_cycles = 6, + .cache_read_cycles = 6, + .cache_write_cycles = 6, + .atclk_div = 4 + }, + { + .name = "40", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 40000000, + .multi = 2, + .voltage = 5000, + .edx_reset = 0x407, + .cpuid_model = 0, + .cyrix_id = 0x0007, + .cpu_flags = 0, + .mem_read_cycles = 8, + .mem_write_cycles = 8, + .cache_read_cycles = 6, + .cache_write_cycles = 6, + .atclk_div = 6 + }, + { + .name = "50", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 50000000, + .multi = 2, + .voltage = 5000, + .edx_reset = 0x407, + .cpuid_model = 0, + .cyrix_id = 0x0007, + .cpu_flags = 0, + .mem_read_cycles = 8, + .mem_write_cycles = 8, + .cache_read_cycles = 6, + .cache_write_cycles = 6, + .atclk_div = 6 + }, + { + .name = "66", + .cpu_type = CPU_486DLC, + .fpus = fpus_80386, + .rspeed = 66666666, + .multi = 2, + .voltage = 5000, + .edx_reset = 0x407, + .cpuid_model = 0, + .cyrix_id = 0x0007, + .cpu_flags = 0, + .mem_read_cycles = 12, + .mem_write_cycles = 12, + .cache_read_cycles = 6, + .cache_write_cycles = 6, + .atclk_div = 8 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_SOCKET1, From 597735ded641be0603da0b5dd1a90da9260bd065 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 29 Jun 2024 18:57:52 -0400 Subject: [PATCH 672/690] Fix null pointers in qt_settingsports.cpp --- src/qt/qt_settingsports.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 9b19df68d..a675d7cdb 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -59,13 +59,16 @@ SettingsPorts::SettingsPorts(QWidget *parent) cbox->setCurrentIndex(selectedRow); auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); - checkBox->setChecked(lpt_ports[i].enabled > 0); - cbox->setEnabled(lpt_ports[i].enabled > 0); + if (checkBox != NULL) + checkBox->setChecked(lpt_ports[i].enabled > 0); + if (cBox != NULL) + cbox->setEnabled(lpt_ports[i].enabled > 0); } for (int i = 0; i < SERIAL_MAX; i++) { auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); - checkBox->setChecked(com_ports[i].enabled > 0); + if (checkBox != NULL) + checkBox->setChecked(com_ports[i].enabled > 0); } ui->checkBoxSerialPassThru1->setChecked(serial_passthrough_enabled[0]); @@ -89,13 +92,16 @@ SettingsPorts::save() for (int i = 0; i < PARALLEL_MAX; i++) { auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); - lpt_ports[i].device = cbox->currentData().toInt(); - lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; + if (cBox != NULL) + lpt_ports[i].device = cbox->currentData().toInt(); + if (checkBox != NULL) + lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } for (int i = 0; i < SERIAL_MAX; i++) { auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); - com_ports[i].enabled = checkBox->isChecked() ? 1 : 0; + if (checkBox != NULL) + com_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } serial_passthrough_enabled[0] = ui->checkBoxSerialPassThru1->isChecked(); From 3a3eb133348066844e0886e6fdeb66104f5c2469 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 29 Jun 2024 19:21:57 -0400 Subject: [PATCH 673/690] Fix typos in qt_settingsports.cpp --- src/qt/qt_settingsports.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index a675d7cdb..f6486aa9a 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -61,7 +61,7 @@ SettingsPorts::SettingsPorts(QWidget *parent) auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); if (checkBox != NULL) checkBox->setChecked(lpt_ports[i].enabled > 0); - if (cBox != NULL) + if (cbox != NULL) cbox->setEnabled(lpt_ports[i].enabled > 0); } @@ -92,7 +92,7 @@ SettingsPorts::save() for (int i = 0; i < PARALLEL_MAX; i++) { auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); - if (cBox != NULL) + if (cbox != NULL) lpt_ports[i].device = cbox->currentData().toInt(); if (checkBox != NULL) lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; From eab504f3889adc2a36f5d47c55be7e2dfa748a13 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Jul 2024 01:47:42 +0200 Subject: [PATCH 674/690] x86seg.c: Make sure not to read beyond the end of the stack segment on stack transfers, fixes erroneous page faults when transferring 16-bit stacks to 32-bit stacks, fixes OS/2 2.0 build 6.141. --- src/cpu/x86seg.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 96ec726b0..61e9e558a 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -896,7 +896,7 @@ loadcscall(uint16_t seg) uint32_t oldsp; uint32_t newsp; uint32_t oldsp2; - uint16_t tempw; + uint32_t oldss_limit_high = cpu_state.seg_ss.limit_high; const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { @@ -1125,7 +1125,31 @@ loadcscall(uint16_t seg) } if (count) { while (count--) { - PUSHL(readmeml(oldssbase, oldsp + (count << 2))); + uint32_t temp_val; + switch (oldss_limit_high - oldsp - (count << 2)) { + default: + case 3: + /* We are at least an entire DWORD away from the limit, + read long. */ + PUSHL(readmeml(oldssbase, oldsp + (count << 2))); + break; + case 2: + /* We are 3 bytes away from the limit, + read word + byte. */ + temp_val = readmemw(oldssbase, oldsp + (count << 2)); + temp_val |= (readmemb(oldssbase, oldsp + + (count << 2) + 2) << 16); + PUSHL(temp_val); + break; + case 1: + /* We are a WORD away from the limit, read word. */ + PUSHL(readmemw(oldssbase, oldsp + (count << 2))); + break; + case 0: + /* We are a BYTE away from the limit, read byte. */ + PUSHL(readmemb(oldssbase, oldsp + (count << 2))); + break; + } if (cpu_state.abrt) { SS = oldss; ESP = oldsp2; @@ -1152,9 +1176,20 @@ loadcscall(uint16_t seg) x86seg_log("Write SP to %04X:%04X\n", SS, SP); if (count) { while (count--) { - tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); - x86seg_log("PUSH %04X\n", tempw); - PUSHW(tempw); + switch (oldss_limit_high - (oldsp & 0xffff) - (count << 1)) { + default: + case 1: + /* We are at least an entire WORD away from the limit, + read word. */ + PUSHW(readmemw(oldssbase, (oldsp & 0xffff) + + (count << 1))); + break; + case 0: + /* We are a BYTE away from the limit, read byte. */ + PUSHW(readmemb(oldssbase, (oldsp & 0xffff) + + (count << 1))); + break; + } if (cpu_state.abrt) { SS = oldss; ESP = oldsp2; From 8a4ae19d6bbdfbdc8500e8697ca79777e0d57133 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 2 Jul 2024 16:54:22 -0300 Subject: [PATCH 675/690] qt: Fix invalid scancodes crashing Windows raw input --- src/qt/qt_winrawinputfilter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 3ca091ae6..857ccef3b 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -199,9 +199,10 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) scancode = convert_scan_code(scancode); /* Remap it according to the list from the Registry */ - if (scancode != scancode_map[scancode]) - pclog("Scan code remap: %03X -> %03X\n", scancode, scancode); - scancode = scancode_map[scancode]; + if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { + pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); + scancode = scancode_map[scancode]; + } /* If it's not 0xFFFF, send it to the emulated keyboard. From 357701dbb5563aeb879e0abdca8ad2a6ea1b5c7e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 2 Jul 2024 17:54:44 -0300 Subject: [PATCH 676/690] SVGA: Make changedvram 1 page bigger to fix adjacent page checks going OOB when the framebuffer is at top of VRAM (Voodoo 3 drivers) --- src/video/vid_svga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 307f455c3..5d579585a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1343,7 +1343,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->vram_max = memsize; svga->vram_display_mask = svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = calloc(memsize >> 12, 1); + svga->changedvram = calloc((memsize >> 12) + 1, 1); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; From 46aa5befc098a288c93033f7fa6aa75c0db9d97c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Jul 2024 14:45:13 -0300 Subject: [PATCH 677/690] CMI8x38: Channel reset bits should be fully writable, fixes #4576 --- src/sound/snd_cmi8x38.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 359563b99..39d54e197 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -706,7 +706,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) case 0x02: /* Reset or start DMA channels if requested. */ - dev->io_regs[addr] = val & 0x03; + dev->io_regs[addr] = val & 0x0f; for (int i = 0; i < (sizeof(dev->dma) / sizeof(dev->dma[0])); i++) { if (val & (0x04 << i)) { /* Reset DMA channel. */ @@ -724,15 +724,11 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) } } - /* Clear reset bits. */ - val &= 0x03; - /* Start playback along with DMA channels. */ if (val & 0x03) cmi8x38_start_playback(dev); /* Update interrupts. */ - dev->io_regs[addr] = val; cmi8x38_update_irqs(dev); break; From 0a8d98e9137e3d580f2ce883cb81be6a463d2853 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Jul 2024 17:24:07 -0300 Subject: [PATCH 678/690] CMI8x38: Fix channel reset bit oversight --- src/sound/snd_cmi8x38.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 39d54e197..b1f56f775 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -710,7 +710,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) for (int i = 0; i < (sizeof(dev->dma) / sizeof(dev->dma[0])); i++) { if (val & (0x04 << i)) { /* Reset DMA channel. */ - val &= ~(0x01 << i); + dev->io_regs[addr] &= ~(0x01 << i); /* clear enable */ dev->io_regs[0x10] &= ~(0x01 << i); /* clear interrupt */ /* Reset Sound Blaster as well when resetting channel 0. */ @@ -725,7 +725,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) } /* Start playback along with DMA channels. */ - if (val & 0x03) + if (dev->io_regs[addr] & 0x03) cmi8x38_start_playback(dev); /* Update interrupts. */ From add1c3918894b218e79674edd145434d342ca76f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 24 Aug 2022 04:42:25 -0400 Subject: [PATCH 679/690] Allow complete removal of FDC --- src/floppy/fdc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 4c1170eb9..0f3cf9dbb 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -97,7 +97,6 @@ fdc_log(const char *fmt, ...) # define fdc_log(fmt, ...) #endif -#if 0 const device_t fdc_none_device = { .name = "None", .internal_name = "none", @@ -111,7 +110,6 @@ const device_t fdc_none_device = { .force_redraw = NULL, .config = NULL }; -#endif const device_t fdc_internal_device = { .name = "Internal", @@ -133,9 +131,7 @@ typedef const struct { static fdc_cards_t fdc_cards[] = { // clang-format off -#if 0 { &fdc_none_device }, -#endif { &fdc_internal_device }, { &fdc_b215_device }, { &fdc_pii151b_device }, From 07e3aba22c0520c5646cb0d39dea67914a95d625 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 29 Jun 2024 22:16:04 -0400 Subject: [PATCH 680/690] Better support for internal floppy --- src/config.c | 21 ++++++++ src/include/86box/fdc_ext.h | 3 +- src/machine/m_xt.c | 105 +++++++++++++++++------------------- 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/src/config.c b/src/config.c index ab23ddb4f..a98111edc 100644 --- a/src/config.c +++ b/src/config.c @@ -792,10 +792,31 @@ load_storage_controllers(void) } p = ini_section_get_string(cat, "fdc", NULL); +#if 0 if (p != NULL) fdc_type = fdc_card_get_from_internal_name(p); else fdc_type = FDC_INTERNAL; +#else + if (p == NULL) { + if (machine_has_flags(machine, MACHINE_FDC)) { + p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); + strcpy(p, "internal"); + } else { + p = (char *) malloc((strlen("none") + 1) * sizeof(char)); + strcpy(p, "none"); + } + free_p = 1; + } + + fdc_type = fdc_card_get_from_internal_name(p); + + if (free_p) { + free(p); + p = NULL; + free_p = 0; + } +#endif p = ini_section_get_string(cat, "hdc", NULL); if (p == NULL) { diff --git a/src/include/86box/fdc_ext.h b/src/include/86box/fdc_ext.h index 0d821ac11..2c46d0704 100644 --- a/src/include/86box/fdc_ext.h +++ b/src/include/86box/fdc_ext.h @@ -25,7 +25,8 @@ extern int fdc_type; /* Controller types. */ -#define FDC_INTERNAL 0 +#define FDC_NONE 0 +#define FDC_INTERNAL 1 extern const device_t fdc_b215_device; extern const device_t fdc_pii151b_device; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index ded68f5dc..adca9f4de 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -23,15 +23,15 @@ extern const device_t vendex_xt_rtc_onboard_device; static void -machine_xt_common_init(const machine_t *model) +machine_xt_common_init(const machine_t *model, int fixed_floppy) { + if ((fdc_type == FDC_INTERNAL) || fixed_floppy) + device_add(&fdc_xt_device); + machine_common_init(model); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_xt_device); - nmi_init(); standalone_gameport_type = &gameport_device; } @@ -59,7 +59,7 @@ machine_pc_init(const machine_t *model) device_add(&keyboard_pc_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -93,19 +93,11 @@ machine_pc82_init(const machine_t *model) device_add(&keyboard_pc82_device); device_add(&ibm_5161_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } -static void -machine_xt_init_ex(const machine_t *model) -{ - device_add(&keyboard_xt_device); - - machine_xt_common_init(model); -} - int machine_xt_init(const machine_t *model) { @@ -127,10 +119,12 @@ machine_xt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_init_ex(model); + device_add(&keyboard_xt_device); device_add(&ibm_5161_device); + machine_xt_common_init(model, 0); + return ret; } @@ -145,7 +139,9 @@ machine_genxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_init_ex(model); + device_add(&keyboard_xt_device); + + machine_xt_common_init(model, 0); return ret; } @@ -170,17 +166,17 @@ machine_xt86_init(const machine_t *model) device_add(&keyboard_xt86_device); device_add(&ibm_5161_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } static void -machine_xt_clone_init(const machine_t *model) +machine_xt_clone_init(const machine_t *model, int fixed_floppy) { device_add(&keyboard_xtclone_device); - machine_xt_common_init(model); + machine_xt_common_init(model, fixed_floppy); } int @@ -194,7 +190,7 @@ machine_xt_americxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -210,7 +206,7 @@ machine_xt_amixt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -226,7 +222,7 @@ machine_xt_znic_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -242,7 +238,7 @@ machine_xt_dtk_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -258,7 +254,7 @@ machine_xt_jukopc_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -274,7 +270,7 @@ machine_xt_openxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -294,7 +290,7 @@ machine_xt_pcxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -312,7 +308,7 @@ machine_xt_pxxt_init(const machine_t *model) device_add(&keyboard_xt_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -329,7 +325,7 @@ machine_xt_iskra3104_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -363,7 +359,7 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) device_add(&keyboard_pravetz_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -379,7 +375,10 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_init_ex(model); + device_add(&keyboard_xt_device); + + machine_xt_common_init(model, 0); + return ret; } @@ -394,7 +393,7 @@ machine_xt_pc4i_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -412,7 +411,7 @@ machine_xt_mpc1600_init(const machine_t *model) device_add(&keyboard_pc82_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -435,7 +434,7 @@ machine_xt_pcspirit_init(const machine_t *model) device_add(&keyboard_pc82_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -453,7 +452,7 @@ machine_xt_pc700_init(const machine_t *model) device_add(&keyboard_pc_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -471,7 +470,7 @@ machine_xt_pc500_init(const machine_t *model) device_add(&keyboard_pc_device); - machine_xt_common_init(model); + machine_xt_common_init(model, 0); return ret; } @@ -487,18 +486,20 @@ machine_xt_vendex_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + /* On-board FDC cannot be disabled */ + machine_xt_clone_init(model, 1); + device_add(&vendex_xt_rtc_onboard_device); return ret; } static void -machine_xt_hyundai_common_init(const machine_t *model) +machine_xt_hyundai_common_init(const machine_t *model, int fixed_floppy) { device_add(&keyboard_xt_hyundai_device); - machine_xt_common_init(model); + machine_xt_common_init(model, fixed_floppy); } int @@ -512,10 +513,8 @@ machine_xt_super16t_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_hyundai_common_init(model); - /* On-board FDC cannot be disabled */ - device_add(&fdc_xt_device); + machine_xt_hyundai_common_init(model, 1); return ret; } @@ -531,10 +530,8 @@ machine_xt_super16te_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_hyundai_common_init(model); - /* On-board FDC cannot be disabled */ - device_add(&fdc_xt_device); + machine_xt_hyundai_common_init(model, 1); return ret; } @@ -550,10 +547,8 @@ machine_xt_top88_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); - /* On-board FDC cannot be disabled */ - device_add(&fdc_xt_device); + machine_xt_clone_init(model, 1); return ret; } @@ -569,7 +564,7 @@ machine_xt_kaypropc_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -585,10 +580,8 @@ machine_xt_sansx16_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); - /* On-board FDC cannot be disabled */ - device_add(&fdc_xt_device); + machine_xt_clone_init(model, 1); return ret; } @@ -604,7 +597,7 @@ machine_xt_bw230_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -620,7 +613,7 @@ machine_xt_v20xt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -636,7 +629,7 @@ machine_xt_pb8810_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_clone_init(model, 0); return ret; } @@ -652,7 +645,9 @@ machine_xt_glabios_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_init_ex(model); + device_add(&keyboard_xt_device); + + machine_xt_common_init(model, 0); return ret; } From f68f0487264f02455313613752525d37803fe4f5 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 30 Jun 2024 20:27:17 -0400 Subject: [PATCH 681/690] Don't attempt to add dummy internal device to system --- src/floppy/fdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 0f3cf9dbb..cd514e141 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -188,8 +188,8 @@ fdc_card_get_from_internal_name(char *s) void fdc_card_init(void) { - if ((fdc_type > 0) && fdc_cards[fdc_type].device) - device_add(fdc_cards[fdc_type].device); + if ((fdc_type > FDC_INTERNAL) && fdc_cards[fdc_type].device) + device_add_inst(fdc_cards[fdc_type].device, 0); } uint8_t From 8aba1361e6ec192017b4cd0cb09d615ffcd24de4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 1 Jul 2024 00:25:52 -0400 Subject: [PATCH 682/690] Commented out support for hiding internal fdc --- src/qt/qt_settingsstoragecontrollers.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 389e22852..fa02ce613 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -110,6 +110,14 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) c = 0; selectedRow = 0; while (true) { +#if 0 + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && (machine_has_flags(machineId, MACHINE_FDC) == 0)) { + c++; + continue; + } +#endif + QString name = DeviceConfig::DeviceName(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); if (name.isEmpty()) { break; From 00068539e131a5f759f239472debd1b73e74e542 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 1 Jul 2024 01:44:54 -0400 Subject: [PATCH 683/690] Add ability to select XT or AT FDC --- src/floppy/fdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index cd514e141..49171ae30 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -133,6 +133,8 @@ static fdc_cards_t fdc_cards[] = { // clang-format off { &fdc_none_device }, { &fdc_internal_device }, + { &fdc_xt_device }, + { &fdc_at_device }, { &fdc_b215_device }, { &fdc_pii151b_device }, { &fdc_pii158b_device }, From 7ce119dcbae0c0b6393c2dd59c66c7d86fcc99e5 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 1 Jul 2024 02:01:58 -0400 Subject: [PATCH 684/690] Fix flags in fdc.h --- src/include/86box/fdc.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 6bb8f081e..cee1fed62 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -40,24 +40,23 @@ extern int fdc_type; #define FDC_QUATERNARY_IRQ 6 #define FDC_QUATERNARY_DMA 2 -#define FDC_FLAG_PCJR 0x01 /* PCjr */ -#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ -#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ -#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ -#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ -#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ -#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ -#define FDC_FLAG_SEC 0x1000 /* Is Secondary */ -#define FDC_FLAG_TER 0x2000 /* Is Tertiary */ -#define FDC_FLAG_QUA 0x3000 /* Is Quaternary */ -#define FDC_FLAG_CHANNEL 0x3000 /* Channel mask */ -#define FDC_FLAG_NO_DSR_RESET 0x4000 /* Has no DSR reset */ -#define FDC_FLAG_NEC 0x8000 /* Is NEC upd765-compatible */ +#define FDC_FLAG_PCJR 0x01 /* PCjr */ +#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ +#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ +#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ +#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ +#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ +#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ +#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ +#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ +#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ +#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ +#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ +#define FDC_FLAG_NO_DSR_RESET 0x1000 /* Has no DSR reset */ +#define FDC_FLAG_NEC 0x2000 /* Is NEC upd765-compatible */ +#define FDC_FLAG_SEC 0x10000 /* Is Secondary */ +#define FDC_FLAG_TER 0x20000 /* Is Tertiary */ +#define FDC_FLAG_QUA 0x40000 /* Is Quaternary */ typedef struct fdc_t { uint8_t dor; From 516dc589b7eac6b7e13aa96ef9b3c104f1c8c8f5 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 1 Jul 2024 21:00:26 -0400 Subject: [PATCH 685/690] Handle freeing mallocs in config.c properly --- src/config.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index a98111edc..3035be95f 100644 --- a/src/config.c +++ b/src/config.c @@ -433,8 +433,11 @@ load_video(void) free_p = 1; } gfxcard[0] = video_get_video_from_internal_name(p); - if (free_p) + if (free_p) { free(p); + p = NULL; + free_p = 0; + } } if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) || @@ -853,6 +856,7 @@ load_storage_controllers(void) if (free_p) { free(p); p = NULL; + free_p = 0; } ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0); From db16f0f2095a444d108270fa39a1770dc7637eef Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jul 2024 03:18:26 +0200 Subject: [PATCH 686/690] Add LZW support for Teledisk 1.x advanced compressed files. --- src/floppy/CMakeLists.txt | 3 + src/floppy/fdd_td0.c | 31 ++- src/floppy/lzw/CMakeLists.txt | 16 ++ src/floppy/lzw/lzw.h | 49 ++++ src/floppy/lzw/lzwdecode.c | 269 ++++++++++++++++++++ src/floppy/lzw/lzwencode.c | 454 ++++++++++++++++++++++++++++++++++ src/floppy/lzw/lzwlocal.h | 63 +++++ 7 files changed, 876 insertions(+), 9 deletions(-) create mode 100644 src/floppy/lzw/CMakeLists.txt create mode 100644 src/floppy/lzw/lzw.h create mode 100644 src/floppy/lzw/lzwdecode.c create mode 100644 src/floppy/lzw/lzwencode.c create mode 100644 src/floppy/lzw/lzwlocal.h diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt index 6d69d2d59..5aea98714 100644 --- a/src/floppy/CMakeLists.txt +++ b/src/floppy/CMakeLists.txt @@ -16,3 +16,6 @@ add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_monster.c fdc_pii15xb.c fdi2raw.c fdd_common.c fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_pcjs.c fdd_mfm.c fdd_td0.c) + +add_subdirectory(lzw) +target_link_libraries(86Box lzw) diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 46e29343b..0bf4b1c71 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -42,6 +42,7 @@ #include <86box/fdd_86f.h> #include <86box/fdd_td0.h> #include <86box/fdc.h> +#include "lzw/lzw.h" #define BUFSZ 512 /* new input buffer */ #define TD0_MAX_BUFSZ (1024UL * 1024UL * 4UL) @@ -124,7 +125,9 @@ typedef struct td0_t { uint8_t xdf_ordered_pos[256][2]; uint8_t interleave_ordered_pos[256][2]; + uint8_t *lzw_buf; uint8_t *imagebuf; + uint8_t *processed_buf; } td0_t; @@ -650,11 +653,20 @@ td0_initialize(int drive) head_count = header[9]; if (header[0] == 't') { - td0_log("TD0: File is compressed\n"); - disk_decode.fdd_file = dev->fp; - state_init_Decode(&disk_decode); - disk_decode.fdd_file_offset = 12; - state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); + if (((header[4] / 10) % 10) == 2) { + td0_log("TD0: File is compressed (TeleDisk 2.x, LZHUF)\n"); + disk_decode.fdd_file = dev->fp; + state_init_Decode(&disk_decode); + disk_decode.fdd_file_offset = 12; + state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); + } else { + td0_log("TD0: File is compressed (TeleDisk 1.x, LZW)\n"); + if (fseek(dev->fp, 12, SEEK_SET) == -1) + fatal("td0_initialize(): Error seeking to offet 12\n"); + if (fread(dev->lzw_buf, 1, file_size - 12, dev->fp) != (file_size - 12)) + fatal("td0_initialize(): Error reading LZW-encoded buffer\n"); + LZWDecodeFile((char *) dev->imagebuf, (char *) dev->lzw_buf, NULL, file_size - 12); + } } else { td0_log("TD0: File is uncompressed\n"); if (fseek(dev->fp, 12, SEEK_SET) == -1) @@ -1224,10 +1236,9 @@ td0_load(int drive, char *fn) /* Allocate the processing buffers. */ i = 1024UL * 1024UL * 4UL; - dev->imagebuf = (uint8_t *) malloc(i); - memset(dev->imagebuf, 0x00, i); - dev->processed_buf = (uint8_t *) malloc(i); - memset(dev->processed_buf, 0x00, i); + dev->lzw_buf = (uint8_t *) calloc(1, i); + dev->imagebuf = (uint8_t *) calloc(1, i); + dev->processed_buf = (uint8_t *) calloc(1, i); if (!td0_initialize(drive)) { td0_log("TD0: Failed to initialize\n"); @@ -1268,6 +1279,8 @@ td0_close(int drive) d86f_unregister(drive); + if (dev->lzw_buf) + free(dev->lzw_buf); if (dev->imagebuf) free(dev->imagebuf); if (dev->processed_buf) diff --git a/src/floppy/lzw/CMakeLists.txt b/src/floppy/lzw/CMakeLists.txt new file mode 100644 index 000000000..bc6f0b612 --- /dev/null +++ b/src/floppy/lzw/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# 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. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020-2021 David Hrdlička. +# + +add_library(lzw STATIC lzwdecode.c lzwencode.c) \ No newline at end of file diff --git a/src/floppy/lzw/lzw.h b/src/floppy/lzw/lzw.h new file mode 100644 index 000000000..26abbf6ad --- /dev/null +++ b/src/floppy/lzw/lzw.h @@ -0,0 +1,49 @@ +/*************************************************************************** +* Header for Lempel-Ziv-Welch Encoding and Decoding Library +* +* File : lzw.h +* Purpose : Provides prototypes for functions that use Lempel-Ziv-Welch +* coding to encode/decode files. +* Author : Michael Dipperstein +* Date : January 30, 2004 +* +**************************************************************************** +* +* LZW: An ANSI C Lempel-Ziv-Welch Encoding/Decoding Routines +* Copyright (C) 2005, 2007, 2014 by +* Michael Dipperstein (mdipperstein@gmail.com) +* +* This file is part of the lzw library. +* +* The lzw library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The lzw library is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ + +#ifndef _LZW_H_ +#define _LZW_H_ + +/*************************************************************************** +* CONSTANTS +***************************************************************************/ + +/*************************************************************************** +* PROTOTYPES +***************************************************************************/ + /* encode inFile */ +int LZWEncodeFile(char *dest, char *src, uint64_t *dst_len, uint64_t src_len); + +/* decode inFile*/ +int LZWDecodeFile(char *dest, char *src, uint64_t *dst_len, uint64_t src_len); + +#endif /* ndef _LZW_H_ */ diff --git a/src/floppy/lzw/lzwdecode.c b/src/floppy/lzw/lzwdecode.c new file mode 100644 index 000000000..7634b52f8 --- /dev/null +++ b/src/floppy/lzw/lzwdecode.c @@ -0,0 +1,269 @@ +/*************************************************************************** +* Lempel-Ziv-Welch Decoding Functions +* +* File : lzwdecode.c +* Purpose : Provides a function for decoding Lempel-Ziv-Welch encoded +* file streams +* Author : Michael Dipperstein +* Date : January 30, 2005 +* +**************************************************************************** +* +* LZW: An ANSI C Lempel-Ziv-Welch Encoding/Decoding Routines +* Copyright (C) 2005, 2007, 2014, 2017 by +* Michael Dipperstein (mdipperstein@gmail.com) +* +* This file is part of the lzw library. +* +* The lzw library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The lzw library is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ + +/*************************************************************************** +* INCLUDED FILES +***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "lzw.h" +#include "lzwlocal.h" + +/*************************************************************************** +* TYPE DEFINITIONS +***************************************************************************/ +typedef struct +{ + uint8_t suffixChar; /* last char in encoded string */ + uint16_t prefixCode; /* code for remaining chars in string */ +} decode_dictionary_t; + +/*************************************************************************** +* CONSTANTS +***************************************************************************/ + +/*************************************************************************** +* MACROS +***************************************************************************/ + +/*************************************************************************** +* GLOBAL VARIABLES +***************************************************************************/ + +/* dictionary of string the code word is the dictionary index */ +static decode_dictionary_t dictionary[(MAX_CODES - FIRST_CODE)]; + +/*************************************************************************** +* PROTOTYPES +***************************************************************************/ +static uint8_t DecodeRecursive(unsigned int code, char **dest); + +/* read encoded data */ +static int GetCodeWord(char *src); + +static uint16_t bufPos = 0x0000; +static uint16_t bufLen = 0x0000; + +static uint32_t bufOutPos = 0x00000000; + +/*************************************************************************** +* FUNCTIONS +***************************************************************************/ + +/*************************************************************************** +* Function : LZWDecodeFile +* Description: This routine reads an input file 1 encoded string at a +* time and decodes it using the LZW algorithm. +* Parameters : fpIn - pointer to the open binary file to decode +* fpOut - pointer to the open binary file to write decoded +* output +* Effects : fpIn is decoded using the LZW algorithm with CODE_LEN codes +* and written to fpOut. Neither file is closed after exit. +* Returned : 0 for success, -1 for failure. errno will be set in the +* event of a failure. +***************************************************************************/ +int +LZWDecodeFile_Internal(char *dest, char *src) +{ + uint16_t nextCode; /* value of next code */ + uint16_t lastCode; /* last decoded code word */ + int code; /* code word to decode */ + uint8_t c; /* last decoded character */ + + /* validate arguments */ + if (dest == NULL) { + errno = ENOENT; + return -1; + } + + bufPos = 0x0000; + bufOutPos = 0x00000000; + + /* initialize for decoding */ + nextCode = FIRST_CODE; /* code for next (first) string */ + + /* first code from file must be a character. use it for initial values */ + lastCode = GetCodeWord(src); + c = lastCode; + *(dest++) = lastCode; + bufOutPos++; + + /* decode rest of file */ + while ((int)(code = GetCodeWord(src)) != EOF) { + if (code < nextCode) { + /* we have a known code. decode it */ + c = DecodeRecursive(code, &dest); + } else { + /*************************************************************** + * We got a code that's not in our dictionary. This must be due + * to the string + char + string + char + string exception. + * Build the decoded string using the last character + the + * string from the last code. + ***************************************************************/ + unsigned char tmp; + + tmp = c; + c = DecodeRecursive(lastCode, &dest); + *(dest++) = tmp; + bufOutPos++; + } + + /* if room, add new code to the dictionary */ + if (nextCode < MAX_CODES) { + dictionary[nextCode - FIRST_CODE].prefixCode = lastCode; + dictionary[nextCode - FIRST_CODE].suffixChar = c; + nextCode++; + } + + /* save character and code for use in unknown code word case */ + lastCode = code; + } + + return 0; +} + +int +LZWDecodeFile(char *dest, char *src, uint64_t *dst_len, uint64_t src_len) +{ + uint16_t size = 0x0000; + uint64_t pos = 0x0000000000000000ULL; + + /* validate arguments */ + if ((dest == NULL) || (src == NULL)) { + errno = ENOENT; + return -1; + } + + if (dst_len != NULL) + *dst_len = 0x0000000000000000ULL; + + while (1) { + size = *(uint16_t *) src; + src += 2; + bufLen = size; + size >>= 1; + if (bufLen & 1) + size++; + if (size > 0x1800) + return -1; + LZWDecodeFile_Internal(dest, src); + src += size; + dest += bufOutPos; + if (dst_len != NULL) + *dst_len += bufOutPos; + pos += (size + 2); + if ((size < 0x1800) || (pos >= src_len)) + /* We have just decoded a block smaller than 0x3000 bytes, + this means this has been the last block, end. */ + break; + } + + return 0; +} + +/*************************************************************************** +* Function : DecodeRecursive +* Description: This function uses the dictionary to decode a code word +* into the string it represents and write it to the output +* file. The string is actually built in reverse order and +* recursion is used to write it out in the correct order. +* Parameters : code - the code word to decode +* fpOut - the file that the decoded code word is written to +* Effects : Decoded code word is written to a file +* Returned : The first character in the decoded string +***************************************************************************/ +static uint8_t +DecodeRecursive(unsigned int code, char **dest) +{ + unsigned char c; + unsigned char firstChar; + + if (code >= FIRST_CODE) { + /* code word is string + c */ + c = dictionary[code - FIRST_CODE].suffixChar; + code = dictionary[code - FIRST_CODE].prefixCode; + + /* evaluate new code word for remaining string */ + firstChar = DecodeRecursive(code, dest); + } else { + /* code word is just c */ + c = code; + firstChar = code; + } + + *((*dest)++) = c; + bufOutPos++; + return firstChar; +} + +/*************************************************************************** +* Function : GetCodeWord +* Description: This function reads and returns a code word from an +* encoded file. In order to deal with endian issue the +* code word is read least significant byte followed by the +* remaining bits. +* Parameters : fpIn - file containing the encoded data +* codeLen - number of bits in code word +* Effects : code word is read from encoded input +* Returned : The next code word in the encoded file. EOF if the end +* of file has been reached. +* +* NOTE: If the code word contains more than 16 bits, this routine should +* be modified to read in all the bytes from least significant to +* most significant followed by any left over bits. +***************************************************************************/ +static int +GetCodeWord(char *src) +{ + int code = 0; + static unsigned int realPos; + + realPos = bufPos >> 1; + + if (bufPos >= bufLen) + /* End of buffer. */ + code = EOF; + else if (bufPos & 1) + /* Odd position. */ + code = (((uint8_t) src[realPos] & 0xf0) >> 4) | ((uint8_t) src[realPos + 1] << 4); + else + /* Even position. */ + code = ((uint8_t) src[realPos] & 0xff) | (((uint8_t) src[realPos + 1] & 0xf) << 8); + + bufPos += 3; + + return code; +} diff --git a/src/floppy/lzw/lzwencode.c b/src/floppy/lzw/lzwencode.c new file mode 100644 index 000000000..0a4d659bb --- /dev/null +++ b/src/floppy/lzw/lzwencode.c @@ -0,0 +1,454 @@ +/*************************************************************************** +* Lempel-Ziv-Welch Encoding Functions +* +* File : lzwencode.c +* Purpose : Provides a function for Lempel-Ziv-Welch encoding of file +* streams +* Author : Michael Dipperstein +* Date : January 30, 2005 +* +**************************************************************************** +* +* LZW: An ANSI C Lempel-Ziv-Welch Encoding/Decoding Routines +* Copyright (C) 2005, 2007, 2014, 2017 by +* Michael Dipperstein (mdipperstein@gmail.com) +* +* This file is part of the lzw library. +* +* The lzw library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The lzw library is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ + +/*************************************************************************** +* INCLUDED FILES +***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "lzw.h" +#include "lzwlocal.h" + +/*************************************************************************** +* TYPE DEFINITIONS +***************************************************************************/ +/* node in dictionary tree */ +typedef struct dict_node_t +{ + unsigned int codeWord; /* code word for this entry */ + unsigned char suffixChar; /* last char in encoded string */ + unsigned int prefixCode; /* code for remaining chars in string */ + + /* pointer to child nodes */ + struct dict_node_t *left; /* child with < key */ + struct dict_node_t *right; /* child with >= key */ +} dict_node_t; + +/*************************************************************************** +* CONSTANTS +***************************************************************************/ + +/*************************************************************************** +* MACROS +***************************************************************************/ + +/*************************************************************************** +* GLOBAL VARIABLES +***************************************************************************/ + +/*************************************************************************** +* PROTOTYPES +***************************************************************************/ + +/* dictionary tree node create/free */ +static dict_node_t *MakeNode(const unsigned int codeWord, const unsigned int prefixCode, + const unsigned char suffixChar); +static void FreeTree(dict_node_t *node); + +/* searches tree for matching dictionary entry */ +static dict_node_t *FindDictionaryEntry(dict_node_t *root, const int unsigned prefixCode, + const unsigned char c); + +/* makes key from prefix code and character */ +static unsigned int MakeKey(const unsigned int prefixCode, const unsigned char suffixChar); + +/* write encoded data */ +static int PutCodeWord(char *dest, int code); + +static char *src_base; +static uint64_t src_length = 0x0000000000000000ULL; + +static uint32_t bufPos = 0x00000000; +static uint32_t bufInPos = 0x00000000; + +static int +is_eob(char *src) +{ + return ((uint64_t) (uintptr_t) (src - src_base)) >= src_length; +} + +static int +get_char(char **src) +{ + int ret = EOF; + + if (!is_eob(*src)) { + ret = (uint8_t) **src; + (*src)++; + } + + return ret; +} + +/*************************************************************************** +* FUNCTIONS +***************************************************************************/ + +static int +LZWEncodeFile_Internal(char *dest, char *src) +{ + unsigned int code; /* code for current string */ + unsigned int nextCode; /* next available code index */ + int c; /* character to add to string */ + + dict_node_t *dictRoot; /* root of dictionary tree */ + dict_node_t *node; /* node of dictionary tree */ + + /* validate arguments */ + if (src == NULL) { + errno = ENOENT; + return -1; + } + + /* initialize dictionary as empty */ + dictRoot = NULL; + + nextCode = FIRST_CODE; /* code for next (first) string */ + + bufPos = 0x00000000; + bufInPos = 0x00000000; + + /* now start the actual encoding process */ + + c = get_char(&src); + + if (c == EOF) + return -1; /* empty file */ + else { + bufInPos++; + code = c; /* start with code string = first character */ + } + + /* create a tree root from 1st 2 character string */ + if ((c = get_char(&src)) != EOF) { + bufInPos++; + + /* special case for NULL root */ + dictRoot = MakeNode(nextCode, code, c); + + if (dictRoot == NULL) { + perror("Making Dictionary Root"); + return -1; + } + + nextCode++; + + /* write code for 1st char */ + (void) PutCodeWord(dest, code); + + /* new code is just 2nd char */ + code = c; + } + + /* now encode normally */ + while ((c = get_char(&src)) != EOF) { + /* look for code + c in the dictionary */ + node = FindDictionaryEntry(dictRoot, code, c); + + if ((node->prefixCode == code) && (node->suffixChar == c)) + /* code + c is in the dictionary, make it's code the new code */ + code = node->codeWord; + else { + /* code + c is not in the dictionary, add it if there's room */ + if (nextCode < MAX_CODES) { + dict_node_t *tmp = MakeNode(nextCode, code, c); + + if (tmp == NULL) { + perror("Making Dictionary Node"); + FreeTree(dictRoot); + return -1; + } + + nextCode++; + + if (MakeKey(code, c) < MakeKey(node->prefixCode, node->suffixChar)) + node->left = tmp; + else + node->right = tmp; + } + + /* write out code for the string before c was added */ + if (PutCodeWord(dest, code)) + break; + + /* new code is just c */ + code = c; + } + + bufInPos++; + } + + /* no more input. write out last of the code. */ + (void) PutCodeWord(dest, code); + + /* free the dictionary */ + FreeTree(dictRoot); + + return (c == EOF) ? 1 : 0; +} + +/*************************************************************************** +* Function : LZWEncodeFile +* Description: This routine reads an input file 1 character at a time and +* writes out an LZW encoded version of that file. +* Parameters : fpIn - pointer to the open binary file to encode +* fpOut - pointer to the open binary file to write encoded +* output +* Effects : fpIn is encoded using the LZW algorithm with CODE_LEN codes +* and written to fpOut. Neither file is closed after exit. +* Returned : 0 for success, -1 for failure. errno will be set in the +* event of a failure. +***************************************************************************/ +int +LZWEncodeFile(char *dest, char *src, uint64_t *dst_len, uint64_t src_len) +{ + uint64_t pos = 0x0000000000000000ULL; + + /* validate arguments */ + if ((dest == NULL) || (src == NULL)) { + errno = ENOENT; + return -1; + } + + if (dst_len != NULL) + *dst_len = 0x0000000000000000ULL; + + src_base = src; + src_length = src_len; + + while (1) { + int ret = LZWEncodeFile_Internal(dest + 2, src); + if (ret == -1) + break; + *(uint16_t *) dest = bufPos; + if (bufPos & 1) + bufPos = (bufPos >> 1) + 1; + else + bufPos >>= 1; + dest += (bufPos + 2); + if (dst_len != NULL) + *dst_len += (bufPos + 2); + /* TODO: Why do we need this - 1 clunkfest? */ + src += bufInPos; + pos += bufInPos; + if ((ret == 1) || (pos >= src_len) || (bufPos < 0x1800)) + break; + } + + return 0; +} + +/*************************************************************************** +* Function : MakeKey +* Description: This routine creates a simple key from a prefix code and +* an appended character. The key may be used to establish +* an order when building/searching a dictionary tree. +* Parameters : prefixCode - code for all but the last character of a +* string. +* suffixChar - the last character of a string +* Effects : None +* Returned : Key built from string represented as a prefix + char. Key +* format is {ms nibble of c} + prefix + {ls nibble of c} +***************************************************************************/ +static unsigned int +MakeKey(const unsigned int prefixCode, const unsigned char suffixChar) +{ + unsigned int key; + + /* position ms nibble */ + key = suffixChar & 0xF0; + key <<= MAX_CODE_LEN; + + /* include prefix code */ + key |= (prefixCode << 4); + + /* inclulde ls nibble */ + key |= (suffixChar & 0x0F); + + return key; +} + +/*************************************************************************** +* Function : MakeNode +* Description: This routine creates and initializes a dictionary entry +* for a string and the code word that encodes it. +* Parameters : codeWord - code word used to encode the string prefixCode + +* suffixChar +* prefixCode - code for all but the last character of a +* string. +* suffixChar - the last character of a string +* Effects : Node is allocated for new dictionary entry +* Returned : Pointer to newly allocated node or NULL on error. +* errno will be set on an error. +***************************************************************************/ +static dict_node_t * +MakeNode(const unsigned int codeWord, const unsigned int prefixCode, const unsigned char suffixChar) +{ + dict_node_t *node; + + node = malloc(sizeof(dict_node_t)); + + if (node != NULL) { + node->codeWord = codeWord; + node->prefixCode = prefixCode; + node->suffixChar = suffixChar; + + node->left = NULL; + node->right = NULL; + } + + return node; +} + +/*************************************************************************** +* Function : FreeTree +* Description: This routine will free all nodes of a tree rooted at the +* node past as a parameter. +* Parameters : node - root of tree to free +* Effects : frees allocated tree node from initial parameter down. +* Returned : none +***************************************************************************/ +static void +FreeTree(dict_node_t *node) +{ + if (node == NULL) + /* nothing to free */ + return; + + /* free left branch */ + if (node->left != NULL) + FreeTree(node->left); + + /* free right branch */ + if (node->right != NULL) + FreeTree(node->right); + + /* free root */ + free(node); +} + +/*************************************************************************** +* Function : FindDictionaryEntry +* Description: This routine searches the dictionary tree for an entry +* with a matching string (prefix code + suffix character). +* If one isn't found, the parent node for that string is +* returned. +* Parameters : prefixCode - code for the prefix of string +* c - last character in string +* Effects : None +* Returned : If string is in dictionary, pointer to node containing +* string, otherwise pointer to suitable parent node. NULL +* is returned for an empty tree. +***************************************************************************/ +static dict_node_t * +FindDictionaryEntry(dict_node_t *root, const int unsigned prefixCode, const unsigned char c) +{ + unsigned int searchKey, key; + + if (root == NULL) + return NULL; + + searchKey = MakeKey(prefixCode, c); /* key of string to find */ + + while (1) { + /* key of current node */ + key = MakeKey(root->prefixCode, root->suffixChar); + + if (key == searchKey) + /* current node contains string */ + return root; + else if (searchKey < key) { + if (root->left != NULL) + /* check left branch for string */ + root = root->left; + else + /* string isn't in tree, it can be added as a left child */ + return root; + } else { + if (root->right != NULL) + /* check right branch for string */ + root = root->right; + else + /* string isn't in tree, it can be added as a right child */ + return root; + } + } +} + +/*************************************************************************** +* Function : PutCodeWord +* Description: This function writes a code word from to an encoded file. +* In order to deal with endian issue the code word is +* written least significant byte followed by the remaining +* bits. +* Parameters : bfpOut - bit file containing the encoded data +* code - code word to add to the encoded data +* codeLen - length of the code word +* Effects : code word is written to the encoded output +* Returned : EOF for failure, ENOTSUP unsupported architecture, +* otherwise the number of bits written. If an error occurs +* after a partial write, the partially written bits will not +* be unwritten. +***************************************************************************/ +static int +PutCodeWord(char *dest, int code) +{ + static unsigned int realPos; + int ret = 0; + + if (bufPos >= 0x3000) + ret = -1; + else { + realPos = bufPos >> 1; + + if (bufPos & 1) { + /* Odd position. */ + dest[realPos] = (dest[realPos] & 0x0f) | ((code << 4) & 0xf0); + dest[realPos + 1] = (code >> 4) & 0xff; + } else { + /* Even position. */ + dest[realPos] = code & 0xff; + dest[realPos + 1] = ((code >> 8) & 0x0f); + } + + bufPos += 3; + + if (bufPos >= 0x3000) + ret = 1; + } + + return ret; +} diff --git a/src/floppy/lzw/lzwlocal.h b/src/floppy/lzw/lzwlocal.h new file mode 100644 index 000000000..79d1f9646 --- /dev/null +++ b/src/floppy/lzw/lzwlocal.h @@ -0,0 +1,63 @@ +/*************************************************************************** +* Header for Lempel-Ziv-Welch Encoding and Decoding Library +* +* File : lzwlocal.h +* Purpose : Provides constant definitions for functions values used within +* the functions for Lempel-Ziv-Welch encoding/decoding. +* Author : Michael Dipperstein +* Date : February 22, 2015 +* +**************************************************************************** +* +* LZW: An ANSI C Lempel-Ziv-Welch Encoding/Decoding Routines +* Copyright (C) 2015 by +* Michael Dipperstein (mdipperstein@gmail.com) +* +* This file is part of the lzw library. +* +* The lzw library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The lzw library is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ + +#ifndef _LZWLOCAL_H_ +#define _LZWLOCAL_H_ +/*************************************************************************** +* INCLUDED FILES +***************************************************************************/ +#include +#include + +/*************************************************************************** +* CONSTANTS +***************************************************************************/ +#define MIN_CODE_LEN 12 /* min # bits in a code word */ +#define MAX_CODE_LEN 12 /* max # bits in a code word */ + +#define FIRST_CODE (1 << CHAR_BIT) /* value of 1st string code */ +#define MAX_CODES (1 << MAX_CODE_LEN) + +#if (MIN_CODE_LEN <= CHAR_BIT) +#error Code words must be larger than 1 character +#endif + +#if ((MAX_CODES - 1) > INT_MAX) +#error There cannot be more codes than can fit in an integer +#endif + +/*************************************************************************** +* MACROS +***************************************************************************/ +#define CURRENT_MAX_CODES(bits) ((unsigned int)(1 << (bits))) + +#endif /* ndef _LZWLOCAL_H_ */ From 215b3253a5f2ae247bbe7b3d6dbb929cf663c570 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 8 Jul 2024 00:40:52 -0400 Subject: [PATCH 687/690] Deal with some magic numbers re hdc_current --- src/disk/hdc.c | 2 +- src/include/86box/config.h | 1 + src/machine/m_at_compaq.c | 4 ++-- src/machine/m_europc.c | 2 +- src/machine/m_ps1.c | 2 +- src/machine/m_ps2_isa.c | 2 +- src/machine/m_v86p.c | 2 +- src/machine/m_xt_t1000.c | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 034b8890e..bb7adcd67 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -132,7 +132,7 @@ hdc_reset(void) hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0); /* If we have a valid controller, add its device. */ - if (hdc_current > 1) + if (hdc_current > HDC_INTERNAL) device_add(controllers[hdc_current].device); /* Now, add the tertiary and/or quaternary IDE controllers. */ diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 80c987162..8ce6f4cfe 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -114,6 +114,7 @@ typedef struct config_t { /* Other peripherals category */ int fdc_type; /* Floppy disk controller type */ + int hdc_current; /* Hard disk controller type */ int hdc; /* Hard disk controller */ int scsi_card; /* SCSI controller */ int ide_ter_enabled; /* Tertiary IDE controller enabled */ diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 7f31d4ecd..b628ea095 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -798,7 +798,7 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_PORTABLEIII: - if (hdc_current == 1) + if (hdc_current == HDC_INTERNAL) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); @@ -806,7 +806,7 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_PORTABLEIII386: - if (hdc_current == 1) + if (hdc_current == HDC_INTERNAL) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index e541cf718..c53061c4e 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -660,7 +660,7 @@ europc_boot(UNUSED(const device_t *info)) * * We only do this if we have not configured another one. */ - if (hdc_current == 1) + if (hdc_current == HDC_INTERNAL) (void) device_add(&xta_hd20_device); return sys; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 34691773f..25d21cfb9 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -353,7 +353,7 @@ ps1_setup(int model) device_add(&fdc_at_ps1_device); /* Enable the builtin HDC. */ - if (hdc_current == 1) { + if (hdc_current == HDC_INTERNAL) { priv = device_add(&ps1_hdc_device); ps1_hdc_inform(priv, &ps->ps1_91); diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index fa9c5acc2..4f6d9bc2b 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -179,7 +179,7 @@ ps2_isa_setup(int model, int cpu_type) device_add(&fdc_at_ps1_device); /* Enable the builtin HDC. */ - if (hdc_current == 1) { + if (hdc_current == HDC_INTERNAL) { priv = device_add(&ps1_hdc_device); ps1_hdc_inform(priv, &ps2->ps2_91); } diff --git a/src/machine/m_v86p.c b/src/machine/m_v86p.c index 54af9b053..5d132a839 100644 --- a/src/machine/m_v86p.c +++ b/src/machine/m_v86p.c @@ -94,7 +94,7 @@ machine_v86p_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&f82c425_video_device); - if (hdc_current <= 1) + if (hdc_current <= HDC_INTERNAL) device_add(&st506_xt_victor_v86p_device); return ret; diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index a12fa4e96..88fc6ada2 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -969,7 +969,7 @@ machine_xt_t1200_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&t1200_video_device); - if (hdc_current <= 1) + if (hdc_current <= HDC_INTERNAL) device_add(&st506_xt_toshiba_t1200_device); return ret; From 84a494aa4229ec0a2276cb258898c1198a220aa6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 8 Jul 2024 14:29:27 -0400 Subject: [PATCH 688/690] Don't change default behavior... yet --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 3035be95f..bc4341b0d 100644 --- a/src/config.c +++ b/src/config.c @@ -795,7 +795,7 @@ load_storage_controllers(void) } p = ini_section_get_string(cat, "fdc", NULL); -#if 0 +#if 1 if (p != NULL) fdc_type = fdc_card_get_from_internal_name(p); else From 1b6fd190fbab7facacbda5cd721d0ea74fadb8f8 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 8 Jul 2024 21:21:06 +0200 Subject: [PATCH 689/690] Video changes of the day (July 8th, 2024) IBM 8514/A set: Fixed a one off video bug that was causing the VGA video to not be restored after quitting a 8514/A GUI session (namely on Win2.x' 8514/A's driver). ATI Mach32: Fixed another vertical display issue when activated (in 1280x1024 mode, when 1024 was 1022). All involved: Apply RG's changedvram fix to 8514/A, Mach8/32 and XGA's changedvram pointers. --- src/video/vid_8514a.c | 10 +++++----- src/video/vid_ati_mach8.c | 11 +++++++---- src/video/vid_svga.c | 3 ++- src/video/vid_xga.c | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index fc205dacf..e8ae527b5 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -1004,9 +1004,9 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x4ae8: case 0x4ae9: WRITE8(port, dev->accel.advfunc_cntl, val); - dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; - vga_on = !dev->on[port & 1]; - dev->vendor_mode[port & 1] = 0; + dev->on[0] = dev->accel.advfunc_cntl & 0x01; + vga_on = !dev->on[0]; + dev->vendor_mode[0] = 0; ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); ibm8514_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); @@ -4311,7 +4311,7 @@ ibm8514_recalctimings(svga_t *svga) } else #endif { - if (dev->on[0] || dev->on[1]) { + if (dev->on[0]) { dev->h_total = dev->htotal + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); @@ -4416,7 +4416,7 @@ ibm8514_init(const device_t *info) dev->vram_size = 1024 << 10; dev->vram = calloc(dev->vram_size, 1); - dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; dev->map8 = dev->pallook; dev->local = 0; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 6abdc213a..b170ae205 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2596,13 +2596,16 @@ mach_recalctimings(svga_t *svga) if (dev->interlace) dev->dispend >>= 1; - if (dev->dispend == 766) + if (dev->dispend == 478) dev->dispend += 2; if (dev->dispend == 598) dev->dispend += 2; - if (dev->dispend == 478) + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 1022) dev->dispend += 2; if ((dev->local & 0xff) >= 0x02) { @@ -5870,7 +5873,7 @@ mach8_init(const device_t *info) NULL); dev->vram_size = mach->memory << 10; dev->vram = calloc(dev->vram_size, 1); - dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; dev->hwcursor.cur_ysize = 64; mach->config1 = 0x20; @@ -5918,7 +5921,7 @@ mach8_init(const device_t *info) NULL); dev->vram_size = (1024 << 10); dev->vram = calloc(dev->vram_size, 1); - dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); mach->config1 = 0x01 | 0x02 | 0x20 | 0x08 | 0x80; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5d579585a..7403401be 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -223,7 +223,8 @@ svga_out(uint16_t addr, uint8_t val, void *priv) xga->on = (val & 0x01) ? 0 : 1; if (ibm8514_active && dev) { dev->on[0] = (val & 0x01) ? 0 : 1; - dev->on[1] = dev->on[0]; + if (dev->local & 0xff) + dev->on[1] = dev->on[0]; } svga_log("3C3: VGA ON = %d.\n", val & 0x01); diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 9dcdd84b6..f1cad184e 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -3346,7 +3346,7 @@ xga_init(const device_t *info) xga->vram_size = (1024 << 10); xga->vram_mask = xga->vram_size - 1; xga->vram = calloc(xga->vram_size, 1); - xga->changedvram = calloc(xga->vram_size >> 12, 1); + xga->changedvram = calloc((xga->vram_size >> 12) + 1, 1); xga->on = 0; xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; From 915ddc147f2c37f6052202a30771573312fa12b4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 8 Jul 2024 18:02:43 -0400 Subject: [PATCH 690/690] Change the AT expansion's default start_address --- src/device/isamem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 2b0b8f66b..278bc49a5 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1176,7 +1176,7 @@ static const device_config_t ibmat_config[] = { .description = "Start Address", .type = CONFIG_SPINNER, .default_string = "", - .default_int = 512, + .default_int = 1024, .file_filter = "", .spinner = { .min = 0, @@ -1224,7 +1224,7 @@ static const device_config_t genericat_config[] = { .description = "Start Address", .type = CONFIG_SPINNER, .default_string = "", - .default_int = 512, + .default_int = 1024, .file_filter = "", .spinner = { .min = 0,